Merge "Revert "Remove scrim fade animation when returning to launcher."" into ub-launcher3-master
diff --git a/Android.mk b/Android.mk
index 9d6e629..0477dab 100644
--- a/Android.mk
+++ b/Android.mk
@@ -37,6 +37,14 @@
 LOCAL_SDK_VERSION := current
 include $(BUILD_PREBUILT)
 
+include $(CLEAR_VARS)
+LOCAL_MODULE := libLauncherProtos
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE_CLASS := JAVA_LIBRARIES
+LOCAL_SRC_FILES := libs/launcher_protos.jar
+LOCAL_UNINSTALLABLE_MODULE := true
+LOCAL_SDK_VERSION := current
+include $(BUILD_PREBUILT)
 #
 # Build rule for plugin lib (needed to write a plugin).
 #
@@ -68,13 +76,14 @@
     androidx.recyclerview_recyclerview \
     androidx.dynamicanimation_dynamicanimation \
     androidx.preference_preference \
-    iconloader
+    iconloader_base
 
 LOCAL_STATIC_JAVA_LIBRARIES := LauncherPluginLib
 
 LOCAL_SRC_FILES := \
     $(call all-proto-files-under, protos) \
-    $(call all-proto-files-under, proto_overrides)
+    $(call all-proto-files-under, proto_overrides) \
+    $(call all-java-files-under, src_build_config) \
 
 LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
 
@@ -99,7 +108,9 @@
 LOCAL_USE_AAPT2 := true
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+    Launcher3CommonDepsLib \
+    SecondaryDisplayLauncherLib
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
     $(call all-java-files-under, src_shortcuts_overrides) \
@@ -162,24 +173,29 @@
 LOCAL_MODULE_TAGS := optional
 
 ifneq (,$(wildcard frameworks/base))
-  LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib
+  LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
   LOCAL_PRIVATE_PLATFORM_APIS := true
 else
-  LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI
+  LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos
   LOCAL_SDK_VERSION := system_current
   LOCAL_MIN_SDK_VERSION := 26
 endif
 LOCAL_MODULE := Launcher3QuickStepLib
 LOCAL_PRIVILEGED_MODULE := true
-LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
+LOCAL_STATIC_ANDROID_LIBRARIES := \
+    Launcher3CommonDepsLib \
+    SecondaryDisplayLauncherLib
 
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
     $(call all-java-files-under, quickstep/src) \
+    $(call all-java-files-under, quickstep/recents_ui_overrides/src) \
     $(call all-java-files-under, src_flags) \
     $(call all-java-files-under, src_shortcuts_overrides)
 
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
+LOCAL_RESOURCE_DIR := \
+    $(LOCAL_PATH)/quickstep/res \
+    $(LOCAL_PATH)/quickstep/recents_ui_overrides/res
 LOCAL_PROGUARD_ENABLED := disabled
 
 
@@ -206,7 +222,9 @@
 LOCAL_PRIVILEGED_MODULE := true
 LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3
 
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/quickstep/res
+LOCAL_RESOURCE_DIR := \
+    $(LOCAL_PATH)/quickstep/res \
+    $(LOCAL_PATH)/quickstep/recents_ui_overrides/res
 
 LOCAL_FULL_LIBS_MANIFEST_FILES := \
     $(LOCAL_PATH)/AndroidManifest.xml \
@@ -226,10 +244,10 @@
 LOCAL_MODULE_TAGS := optional
 
 ifneq (,$(wildcard frameworks/base))
-  LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib
+  LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
   LOCAL_PRIVATE_PLATFORM_APIS := true
 else
-  LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI
+  LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos
   LOCAL_SDK_VERSION := system_current
   LOCAL_MIN_SDK_VERSION := 26
 endif
@@ -238,10 +256,12 @@
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
     $(call all-java-files-under, quickstep/src) \
+    $(call all-java-files-under, quickstep/recents_ui_overrides/src) \
     $(call all-java-files-under, go/src)
 
 LOCAL_RESOURCE_DIR := \
     $(LOCAL_PATH)/quickstep/res \
+    $(LOCAL_PATH)/quickstep/recents_ui_overrides/res \
     $(LOCAL_PATH)/go/res
 
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
@@ -260,6 +280,51 @@
 LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
 include $(BUILD_PACKAGE)
 
+#
+# Build rule for Launcher3 Go app with quickstep and Go-specific
+# version of recents for Android Go devices.
+#
+include $(CLEAR_VARS)
+LOCAL_USE_AAPT2 := true
+LOCAL_MODULE_TAGS := optional
+
+ifneq (,$(wildcard frameworks/base))
+  LOCAL_STATIC_JAVA_LIBRARIES := SystemUISharedLib launcherprotosnano
+  LOCAL_PRIVATE_PLATFORM_APIS := true
+else
+  LOCAL_STATIC_JAVA_LIBRARIES := libSharedSystemUI libLauncherProtos
+  LOCAL_SDK_VERSION := system_current
+  LOCAL_MIN_SDK_VERSION := 26
+endif
+LOCAL_STATIC_ANDROID_LIBRARIES := Launcher3CommonDepsLib
+
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src) \
+    $(call all-java-files-under, quickstep/src) \
+    $(call all-java-files-under, go/src) \
+    $(call all-java-files-under, go/quickstep/src)
+
+LOCAL_RESOURCE_DIR := \
+    $(LOCAL_PATH)/quickstep/res \
+    $(LOCAL_PATH)/go/res \
+    $(LOCAL_PATH)/go/quickstep/res
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+LOCAL_PROGUARD_ENABLED := full
+
+LOCAL_PACKAGE_NAME := Launcher3QuickStepGoIconRecents
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3 Launcher3QuickStep
+
+LOCAL_FULL_LIBS_MANIFEST_FILES := \
+    $(LOCAL_PATH)/go/AndroidManifest.xml \
+    $(LOCAL_PATH)/AndroidManifest.xml \
+    $(LOCAL_PATH)/AndroidManifest-common.xml
+
+LOCAL_MANIFEST_FILE := quickstep/AndroidManifest.xml
+LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
+include $(BUILD_PACKAGE)
+
 
 # ==================================================
 include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index 1beaea5..979096c 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -110,8 +110,8 @@
 
         <service
             android:name="com.android.launcher3.notification.NotificationListener"
-            android:label="@string/icon_badging_service_title"
-            android:enabled="@bool/notification_badging_enabled"
+            android:label="@string/notification_dots_service_title"
+            android:enabled="@bool/notification_dots_enabled"
             android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
             <intent-filter>
                 <action android:name="android.service.notification.NotificationListenerService" />
@@ -153,6 +153,15 @@
             android:readPermission="${packageName}.permission.READ_SETTINGS" />
 
         <!--
+        The content provider for exposing various launcher grid options.
+        TODO: Add proper permissions
+        -->
+        <provider
+            android:name="com.android.launcher3.graphics.GridOptionsProvider"
+            android:authorities="${packageName}.grid_control"
+            android:exported="true" />
+
+        <!--
         The settings activity. To extend point settings_fragment_name to appropriate fragment class
         -->
         <activity
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 4ac51ab..1a485ed 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -20,7 +20,7 @@
 <manifest
     xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.launcher3">
-    <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
+    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"/>
     <!--
     Manifest entries specific to Launcher3. This is merged with AndroidManifest-common.xml.
     Refer comments around specific entries on how to extend individual components.
diff --git a/SecondaryDisplayLauncher/Android.mk b/SecondaryDisplayLauncher/Android.mk
new file mode 100644
index 0000000..4fb5eba
--- /dev/null
+++ b/SecondaryDisplayLauncher/Android.mk
@@ -0,0 +1,39 @@
+#
+# 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.
+#
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+LOCAL_USE_AAPT2 := true
+LOCAL_AAPT2_ONLY := true
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_ANDROID_LIBRARIES := androidx.design_design
+
+LOCAL_STATIC_JAVA_LIBRARIES := LauncherPluginLib
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
+
+LOCAL_PROGUARD_ENABLED := disabled
+
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 21
+LOCAL_MODULE := SecondaryDisplayLauncherLib
+LOCAL_PRIVILEGED_MODULE := true
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/SecondaryDisplayLauncher/AndroidManifest.xml b/SecondaryDisplayLauncher/AndroidManifest.xml
new file mode 100644
index 0000000..ebf6b02
--- /dev/null
+++ b/SecondaryDisplayLauncher/AndroidManifest.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 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.
+*/
+-->
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.android.launcher3">
+
+    <application>
+
+        <activity
+            android:name="com.android.launcher3.SecondaryDisplayLauncher"
+            android:theme="@style/SecondaryLauncherTheme"
+            android:launchMode="singleTop"
+            android:configChanges="orientation|screenSize|smallestScreenSize|screenLayout|colorMode|density"
+            android:enabled="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.SECONDARY_HOME" />
+                <category android:name="android.intent.category.DEFAULT" />
+            </intent-filter>
+        </activity>
+
+    </application>
+</manifest>
diff --git a/SecondaryDisplayLauncher/res/drawable/ic_apps.xml b/SecondaryDisplayLauncher/res/drawable/ic_apps.xml
new file mode 100644
index 0000000..db779c2
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/drawable/ic_apps.xml
@@ -0,0 +1,22 @@
+<?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 android:height="24dp" android:tint="#FFFFFF"
+        android:viewportHeight="24.0" android:viewportWidth="24.0"
+        android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M4,8h4L8,4L4,4v4zM10,20h4v-4h-4v4zM4,20h4v-4L4,16v4zM4,14h4v-4L4,10v4zM10,14h4v-4h-4v4zM16,4v4h4L20,4h-4zM10,8h4L14,4h-4v4zM16,14h4v-4h-4v4zM16,20h4v-4h-4v4z"/>
+</vector>
diff --git a/SecondaryDisplayLauncher/res/drawable/ic_settings.xml b/SecondaryDisplayLauncher/res/drawable/ic_settings.xml
new file mode 100644
index 0000000..c269c3b
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/drawable/ic_settings.xml
@@ -0,0 +1,22 @@
+<?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 android:height="24dp" android:tint="#FFFFFF"
+        android:viewportHeight="24.0" android:viewportWidth="24.0"
+        android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+    <path android:fillColor="#FF000000" android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
+</vector>
diff --git a/SecondaryDisplayLauncher/res/layout-sw600dp/secondary_display_launcher.xml b/SecondaryDisplayLauncher/res/layout-sw600dp/secondary_display_launcher.xml
new file mode 100644
index 0000000..46f1674
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/layout-sw600dp/secondary_display_launcher.xml
@@ -0,0 +1,56 @@
+<?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.
+  -->
+
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/RootView"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/launcher_bg_color"
+    android:fitsSystemWindows="true" >
+
+    <GridView
+        android:id="@+id/pinned_app_grid"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="@dimen/app_grid_margin_top"
+        android:layout_marginStart="@dimen/app_grid_margin_left"
+        android:layout_marginEnd="@dimen/app_grid_margin_right"
+        android:columnWidth="@dimen/app_list_col_width"
+        android:verticalSpacing="@dimen/app_list_horizontal_spacing"
+        android:horizontalSpacing="@dimen/app_list_vertical_spacing"
+        android:numColumns="auto_fit" />
+
+    <ImageButton
+        android:id="@+id/OptionsButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|start"
+        android:layout_marginStart="@dimen/options_button_margin"
+        android:layout_marginBottom="@dimen/options_button_margin"
+        android:src="@drawable/ic_settings"
+        android:background="@null"/>
+
+    <FrameLayout
+        android:layout_width="@dimen/app_picker_width"
+        android:layout_height="@dimen/app_picker_height"
+        android:layout_gravity="bottom|end"
+        android:layout_margin="@dimen/app_picker_fab_margin">
+
+        <include layout="@layout/app_picker_layout"/>
+    </FrameLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/SecondaryDisplayLauncher/res/layout-sw720dp/secondary_display_launcher.xml b/SecondaryDisplayLauncher/res/layout-sw720dp/secondary_display_launcher.xml
new file mode 100644
index 0000000..6653a77
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/layout-sw720dp/secondary_display_launcher.xml
@@ -0,0 +1,57 @@
+<?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.
+  -->
+
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/RootView"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/launcher_bg_color"
+    android:fitsSystemWindows="true" >
+
+    <GridView
+        android:id="@+id/pinned_app_grid"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="@dimen/app_grid_margin_top"
+        android:layout_marginStart="@dimen/app_grid_margin_left"
+        android:layout_marginEnd="@dimen/app_grid_margin_right"
+        android:columnWidth="@dimen/app_list_col_width"
+        android:verticalSpacing="@dimen/app_list_horizontal_spacing"
+        android:horizontalSpacing="@dimen/app_list_vertical_spacing"
+        android:numColumns="auto_fit" />
+
+    <ImageButton
+        android:id="@+id/OptionsButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|start"
+        android:layout_marginStart="@dimen/options_button_margin"
+        android:layout_marginBottom="@dimen/options_button_margin"
+        android:src="@drawable/ic_settings"
+        android:background="@null"/>
+
+    <FrameLayout
+        android:layout_width="@dimen/app_picker_width"
+        android:layout_height="@dimen/app_picker_height"
+        android:layout_gravity="bottom|end"
+        android:layout_marginEnd="@dimen/app_picker_fab_margin"
+        android:layout_marginBottom="@dimen/app_picker_fab_margin">
+
+        <include layout="@layout/app_picker_layout"/>
+    </FrameLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/SecondaryDisplayLauncher/res/layout/app_grid_item.xml b/SecondaryDisplayLauncher/res/layout/app_grid_item.xml
new file mode 100644
index 0000000..ee5158a
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/layout/app_grid_item.xml
@@ -0,0 +1,35 @@
+<?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.
+  -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center">
+
+    <ImageView
+        android:id="@+id/app_icon"
+        android:layout_width="@dimen/app_icon_width"
+        android:layout_height="@dimen/app_icon_height" />
+
+    <TextView
+        android:id="@+id/app_name"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:gravity="center"
+        android:maxLines="1" />
+</LinearLayout>
diff --git a/SecondaryDisplayLauncher/res/layout/app_picker_dialog.xml b/SecondaryDisplayLauncher/res/layout/app_picker_dialog.xml
new file mode 100644
index 0000000..563a1af
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/layout/app_picker_dialog.xml
@@ -0,0 +1,34 @@
+<?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.
+  -->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <GridView
+        android:id="@+id/picker_app_grid"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="@dimen/app_grid_margin_top"
+        android:layout_marginStart="@dimen/app_grid_margin_left"
+        android:layout_marginEnd="@dimen/app_grid_margin_right"
+        android:columnWidth="@dimen/app_list_col_width"
+        android:verticalSpacing="@dimen/app_list_horizontal_spacing"
+        android:horizontalSpacing="@dimen/app_list_vertical_spacing"
+        android:numColumns="auto_fit" />
+</FrameLayout>
diff --git a/SecondaryDisplayLauncher/res/layout/app_picker_layout.xml b/SecondaryDisplayLauncher/res/layout/app_picker_layout.xml
new file mode 100644
index 0000000..fbaeac4
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/layout/app_picker_layout.xml
@@ -0,0 +1,46 @@
+<?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.
+  -->
+
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <android.support.design.circularreveal.cardview.CircularRevealCardView
+        android:id="@+id/FloatingSheet"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="invisible">
+
+        <GridView
+            android:id="@+id/app_grid"
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_marginTop="@dimen/app_grid_margin_top"
+            android:columnWidth="@dimen/app_list_col_width"
+            android:verticalSpacing="@dimen/app_list_horizontal_spacing"
+            android:horizontalSpacing="@dimen/app_list_vertical_spacing"
+            android:numColumns="auto_fit" />
+    </android.support.design.circularreveal.cardview.CircularRevealCardView>
+
+    <android.support.design.widget.FloatingActionButton
+        android:id="@+id/FloatingActionButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|end"
+        android:src="@drawable/ic_apps"/>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/SecondaryDisplayLauncher/res/layout/secondary_display_launcher.xml b/SecondaryDisplayLauncher/res/layout/secondary_display_launcher.xml
new file mode 100644
index 0000000..49cd499
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/layout/secondary_display_launcher.xml
@@ -0,0 +1,56 @@
+<?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.
+  -->
+
+<androidx.coordinatorlayout.widget.CoordinatorLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/RootView"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@color/launcher_bg_color"
+    android:fitsSystemWindows="true" >
+
+    <GridView
+        android:id="@+id/pinned_app_grid"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_marginTop="@dimen/app_grid_margin_top"
+        android:layout_marginStart="@dimen/app_grid_margin_left"
+        android:layout_marginEnd="@dimen/app_grid_margin_right"
+        android:columnWidth="@dimen/app_list_col_width"
+        android:verticalSpacing="@dimen/app_list_horizontal_spacing"
+        android:horizontalSpacing="@dimen/app_list_vertical_spacing"
+        android:numColumns="auto_fit" />
+
+    <ImageButton
+        android:id="@+id/OptionsButton"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|start"
+        android:layout_marginStart="@dimen/options_button_margin"
+        android:layout_marginBottom="@dimen/options_button_margin"
+        android:src="@drawable/ic_settings"
+        android:background="@null"/>
+
+    <FrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="bottom|end"
+        android:layout_margin="@dimen/app_picker_fab_margin">
+
+        <include layout="@layout/app_picker_layout"/>
+    </FrameLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/SecondaryDisplayLauncher/res/menu/context_menu.xml b/SecondaryDisplayLauncher/res/menu/context_menu.xml
new file mode 100644
index 0000000..6263842
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/menu/context_menu.xml
@@ -0,0 +1,23 @@
+<?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.
+  -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/add_app_shortcut"
+          android:title="@string/add_app_shortcut" />
+    <item android:id="@+id/set_wallpaper"
+          android:title="@string/set_wallpaper" />
+</menu>
diff --git a/SecondaryDisplayLauncher/res/values-af/strings.xml b/SecondaryDisplayLauncher/res/values-af/strings.xml
new file mode 100644
index 0000000..b544be7a
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-af/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Kon nie die aktiwiteit begin nie"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Voeg programkortpad by"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Stel muurpapier"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-am/strings.xml b/SecondaryDisplayLauncher/res/values-am/strings.xml
new file mode 100644
index 0000000..71854ad
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-am/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"እንቅስቃሴውን ማስጀመር አልተቻለም"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"የመተግበሪያ አቋራጭ ያክሉ"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"ልጣፍ አዘጋጅ"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ar/strings.xml b/SecondaryDisplayLauncher/res/values-ar/strings.xml
new file mode 100644
index 0000000..ba81c11
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ar/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"تعذَّر تشغيل النشاط."</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"إضافة اختصار التطبيق"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"تعيين الخلفية"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-as/strings.xml b/SecondaryDisplayLauncher/res/values-as/strings.xml
new file mode 100644
index 0000000..d199a26
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-as/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"কাৰ্যকলাপটো লঞ্চ কৰিব পৰা নগ’ল"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"এপৰ শ্বর্টকাট যোগ কৰক"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"ৱালপেপাৰ ছেট কৰক"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-az/strings.xml b/SecondaryDisplayLauncher/res/values-az/strings.xml
new file mode 100644
index 0000000..cee70a0
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-az/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Fəaliyyəti başlatmaq mümkün olmadı"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Tətbiq qısayolu əlavə edin"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Divar kağızı ayarlayın"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-b+sr+Latn/strings.xml b/SecondaryDisplayLauncher/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..a8859d9
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Pokretanje aktivnosti nije uspelo"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Dodaj prečicu za aplikaciju"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Podesite pozadinu"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-be/strings.xml b/SecondaryDisplayLauncher/res/values-be/strings.xml
new file mode 100644
index 0000000..3df3760
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-be/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Не ўдалося запусціць дзеянне"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Дадаць ярлык праграмы"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Устанавіць шпалеры"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-bg/strings.xml b/SecondaryDisplayLauncher/res/values-bg/strings.xml
new file mode 100644
index 0000000..4474815
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-bg/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Активността не можа да бъде стартирана"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Добавяне на пряк път към приложението"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Задаване на тапет"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-bn/strings.xml b/SecondaryDisplayLauncher/res/values-bn/strings.xml
new file mode 100644
index 0000000..7322691
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-bn/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"অ্যাক্টিভিটি চালু করা যায়নি"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"অ্যাপ শর্টকাট যোগ করুন"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"ওয়ালপেপার সেট করুন"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-bs/strings.xml b/SecondaryDisplayLauncher/res/values-bs/strings.xml
new file mode 100644
index 0000000..1e59d33
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-bs/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Pokretanje aktivnosti nije uspjelo"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Dodaj prečicu aplikacije"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Postavi pozadinsku sliku"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ca/strings.xml b/SecondaryDisplayLauncher/res/values-ca/strings.xml
new file mode 100644
index 0000000..c0274d1
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ca/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"No s\'ha pogut iniciar l\'activitat"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Afegeix una drecera d\'aplicació"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Estableix el fons de pantalla"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-cs/strings.xml b/SecondaryDisplayLauncher/res/values-cs/strings.xml
new file mode 100644
index 0000000..92ed5fa
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-cs/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Aktivitu nelze zahájit"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Přidat zkratku aplikace"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Nastavení tapety"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-da/strings.xml b/SecondaryDisplayLauncher/res/values-da/strings.xml
new file mode 100644
index 0000000..16bdb33
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-da/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Aktiviteten kunne ikke startes"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Tilføj appgenvej"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Angiv baggrund"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-de/strings.xml b/SecondaryDisplayLauncher/res/values-de/strings.xml
new file mode 100644
index 0000000..3617a5b
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-de/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Aktivität konnte nicht gestartet werden"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"App-Verknüpfung hinzufügen"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Hintergrund festlegen"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-el/strings.xml b/SecondaryDisplayLauncher/res/values-el/strings.xml
new file mode 100644
index 0000000..8d19d09
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-el/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Δεν ήταν δυνατή η εκκίνηση της δραστηριότητας"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Προσθήκη συντόμευσης εφαρμογής"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Ορισμός ταπετσαρίας"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-en-rAU/strings.xml b/SecondaryDisplayLauncher/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..8d8c419
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-en-rAU/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Couldn\'t launch the activity"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Add app shortcut"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Set wallpaper"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-en-rGB/strings.xml b/SecondaryDisplayLauncher/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..8d8c419
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-en-rGB/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Couldn\'t launch the activity"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Add app shortcut"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Set wallpaper"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-en-rIN/strings.xml b/SecondaryDisplayLauncher/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..8d8c419
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-en-rIN/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Couldn\'t launch the activity"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Add app shortcut"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Set wallpaper"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-es-rUS/strings.xml b/SecondaryDisplayLauncher/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..ff6772b
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-es-rUS/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"No se pudo iniciar la actividad"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Agregar acceso directo a app"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Establecer fondo de pantalla"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-es/strings.xml b/SecondaryDisplayLauncher/res/values-es/strings.xml
new file mode 100644
index 0000000..0654dcb
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-es/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"No se ha podido iniciar la acción"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Añadir acceso directo a la aplicación"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Establecer fondo de pantalla"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-et/strings.xml b/SecondaryDisplayLauncher/res/values-et/strings.xml
new file mode 100644
index 0000000..3410fd4
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-et/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Tegevust ei saanud käivitada"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Lisa rakenduse otsetee"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Määra taustapilt"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-eu/strings.xml b/SecondaryDisplayLauncher/res/values-eu/strings.xml
new file mode 100644
index 0000000..d7abe33
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-eu/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Ezin izan da abiarazi jarduera"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Gehitu aplikaziorako lasterbidea"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Ezarri horma-papera"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-fa/strings.xml b/SecondaryDisplayLauncher/res/values-fa/strings.xml
new file mode 100644
index 0000000..4d3ec4d
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-fa/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"فعالیت راه‌اندازی نشد"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"افزودن میان‌بر برنامه"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"تنظیم کاغذدیواری"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-fi/strings.xml b/SecondaryDisplayLauncher/res/values-fi/strings.xml
new file mode 100644
index 0000000..e56f67a
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-fi/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Käynnistäminen epäonnistui"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Lisää sovelluksen pikakuvake"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Aseta taustakuva"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-fr-rCA/strings.xml b/SecondaryDisplayLauncher/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..f5c9ba5
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-fr-rCA/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Impossible de lancer l\'activité"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Ajouter un raccourci vers l\'application"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Définir le fond d\'écran"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-fr/strings.xml b/SecondaryDisplayLauncher/res/values-fr/strings.xml
new file mode 100644
index 0000000..daa186b
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-fr/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Impossible de lancer l\'activité"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Ajouter un raccourci vers l\'application"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Configurer le fond d\'écran"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-gl/strings.xml b/SecondaryDisplayLauncher/res/values-gl/strings.xml
new file mode 100644
index 0000000..0bcf969
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-gl/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Non se puido iniciar a actividade"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Engadir atallo da aplicación"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Definir fondo de pantalla"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-gu/strings.xml b/SecondaryDisplayLauncher/res/values-gu/strings.xml
new file mode 100644
index 0000000..82b4444
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-gu/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"પ્રવૃત્તિ લૉન્ચ કરી શકાઈ નથી"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"ઍપ શૉર્ટકટ ઉમેરો"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"વૉલપેપર સેટ કરો"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-hi/strings.xml b/SecondaryDisplayLauncher/res/values-hi/strings.xml
new file mode 100644
index 0000000..8adb519
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-hi/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"गतिविधि लॉन्च नहीं हो सकी"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"ऐप्लिकेशन शॉर्टकट जोड़ें"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"वॉलपेपर सेट करें"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-hr/strings.xml b/SecondaryDisplayLauncher/res/values-hr/strings.xml
new file mode 100644
index 0000000..87ac874
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-hr/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Pokretanje aktivnosti nije uspjelo"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Dodajte aplikacijski prečac"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Postavljanje pozadine"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-hu/strings.xml b/SecondaryDisplayLauncher/res/values-hu/strings.xml
new file mode 100644
index 0000000..a8870fc
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-hu/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Nem sikerült elindítani a tevékenységet"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Alkalmazás parancsikonjának hozzáadása"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Háttérkép beállítása"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-hy/strings.xml b/SecondaryDisplayLauncher/res/values-hy/strings.xml
new file mode 100644
index 0000000..a64233f
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-hy/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Չհաջողվեց գործարկել գործողությունը"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Ավելացնել հավելվածի դյուրանցումը"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Դարձնել պաստառ"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-in/strings.xml b/SecondaryDisplayLauncher/res/values-in/strings.xml
new file mode 100644
index 0000000..f51d238
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-in/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Tidak dapat meluncurkan aktivitas"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Tambahkan pintasan app"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Setel wallpaper"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-is/strings.xml b/SecondaryDisplayLauncher/res/values-is/strings.xml
new file mode 100644
index 0000000..e8b3e97
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-is/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Ekki tókst að ræsa aðgerðina"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Bæta við flýtileið forrita"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Velja veggfóður"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-it/strings.xml b/SecondaryDisplayLauncher/res/values-it/strings.xml
new file mode 100644
index 0000000..4941515
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-it/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Impossibile avviare l\'attività"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Aggiungi scorciatoia app"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Imposta sfondo"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-iw/strings.xml b/SecondaryDisplayLauncher/res/values-iw/strings.xml
new file mode 100644
index 0000000..06b0c42
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-iw/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"לא ניתן היה להפעיל את הפעילות"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"הוספת קיצור דרך של אפליקציה"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"הגדרת טפט"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ja/strings.xml b/SecondaryDisplayLauncher/res/values-ja/strings.xml
new file mode 100644
index 0000000..3ed7b2b
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ja/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"アクティビティを開始できませんでした"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"アプリのショートカットを追加"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"壁紙を設定"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ka/strings.xml b/SecondaryDisplayLauncher/res/values-ka/strings.xml
new file mode 100644
index 0000000..ac85f70
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ka/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"აქტივობის გაშვება ვერ მოხერხდა"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"აპის მალსახმობის დამატება"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"ფონის დაყენება"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-kk/strings.xml b/SecondaryDisplayLauncher/res/values-kk/strings.xml
new file mode 100644
index 0000000..f9ac455
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-kk/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Әрекет іске қосылмады"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Қолданба таңбашасын енгізу"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Тұсқағаз орнату"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-km/strings.xml b/SecondaryDisplayLauncher/res/values-km/strings.xml
new file mode 100644
index 0000000..afc050f
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-km/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"មិនអាចចាប់ផ្តើមសកម្មភាពទេ"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"បញ្ចូល​ផ្លូវកាត់​កម្មវិធី"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"កំណត់​ផ្ទាំង​រូបភាព"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-kn/strings.xml b/SecondaryDisplayLauncher/res/values-kn/strings.xml
new file mode 100644
index 0000000..09c327f
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-kn/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"ಚಟುವಟಿಕೆಯನ್ನು ಲಾಂಚ್‌ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"ಆ್ಯಪ್‌ ಶಾರ್ಟ್‌ಕಟ್ ಸೇರಿಸಿ"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"ವಾಲ್‌ಪೇಪರ್ ಹೊಂದಿಸಿ"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ko/strings.xml b/SecondaryDisplayLauncher/res/values-ko/strings.xml
new file mode 100644
index 0000000..6a02ac0
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ko/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"활동을 실행할 수 없음"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"앱 바로가기 추가"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"배경화면 설정"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ky/strings.xml b/SecondaryDisplayLauncher/res/values-ky/strings.xml
new file mode 100644
index 0000000..56185fa
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ky/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Аракет аткарылган жок"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Колдонмого кыска жол кошуу"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Тушкагаз орнотуу"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-lo/strings.xml b/SecondaryDisplayLauncher/res/values-lo/strings.xml
new file mode 100644
index 0000000..36a6275
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-lo/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"ບໍ່ສາມາດເປີດໃຊ້ການເຄື່ອນໄຫວໄດ້"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"ເພີ່ມທາງລັດແອັບ"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"ຕັ້ງເປັນຮູບພື້ນຫຼັງ"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-lt/strings.xml b/SecondaryDisplayLauncher/res/values-lt/strings.xml
new file mode 100644
index 0000000..8113eb6
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-lt/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Nepavyko paleisti veiklos"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Pridėti programos šaukinį"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Nustatyti ekrano foną"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-lv/strings.xml b/SecondaryDisplayLauncher/res/values-lv/strings.xml
new file mode 100644
index 0000000..e267933
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-lv/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Nevarēja palaist darbību"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Pievienot lietotnes saīsni"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Iestatīt fona tapeti"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-mk/strings.xml b/SecondaryDisplayLauncher/res/values-mk/strings.xml
new file mode 100644
index 0000000..e2cca03
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-mk/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Не можеше да се стартува активноста"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Додајте кратенка за апликација"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Поставете го тапетот"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ml/strings.xml b/SecondaryDisplayLauncher/res/values-ml/strings.xml
new file mode 100644
index 0000000..864245b
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ml/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"ആക്‌റ്റിവിറ്റി പ്രകാശിപ്പിക്കാനായില്ല"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"ആപ്പ് കുറുക്കുവഴികൾ ചേർക്കുക"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"വാൾപേപ്പർ സജ്ജീകരിക്കുക"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-mn/strings.xml b/SecondaryDisplayLauncher/res/values-mn/strings.xml
new file mode 100644
index 0000000..85fb020
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-mn/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Үйл ажиллагааг эхлүүж чадсангүй"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Аппын товчлол нэмэх"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Ханын зураг тохируулах"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-mr/strings.xml b/SecondaryDisplayLauncher/res/values-mr/strings.xml
new file mode 100644
index 0000000..6e92a2f
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-mr/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"अ‍ॅक्टिव्हिटी लाँच करता आली नाही"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"अ‍ॅप शॉर्टकट जोडा"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"वॉलपेपर सेट करा"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ms/strings.xml b/SecondaryDisplayLauncher/res/values-ms/strings.xml
new file mode 100644
index 0000000..fd78053
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ms/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Tidak dapat melancarkan aktiviti"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Tambah pintasan apl"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Tetapkan kertas dinding"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-my/strings.xml b/SecondaryDisplayLauncher/res/values-my/strings.xml
new file mode 100644
index 0000000..1521402
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-my/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"လုပ်ဆောင်ချက်ကို စတင်၍မရပါ"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"အက်ပ်ဖြတ်လမ်းလင့်ခ်ထည့်ရန်"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"နောက်ခံ သတ်မှတ်ရန်"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-nb/strings.xml b/SecondaryDisplayLauncher/res/values-nb/strings.xml
new file mode 100644
index 0000000..945c87b
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-nb/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Kunne ikke starte aktiviteten"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Legg til en appsnarvei"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Angi bakgrunn"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ne/strings.xml b/SecondaryDisplayLauncher/res/values-ne/strings.xml
new file mode 100644
index 0000000..9a5b0a0
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ne/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"उक्त क्रियाकलाप सुरु गर्न सकिएन"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"अनुप्रयोगको सर्टकट थप्नुहोस्‌"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"वालपेपर सेट गर्नुहोस्"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-nl/strings.xml b/SecondaryDisplayLauncher/res/values-nl/strings.xml
new file mode 100644
index 0000000..8767708
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-nl/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Kan de activiteit niet starten"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"App-snelkoppeling toevoegen"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Achtergrond instellen"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-or/strings.xml b/SecondaryDisplayLauncher/res/values-or/strings.xml
new file mode 100644
index 0000000..9bc5725
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-or/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"ଗତିବିଧିକୁ ଲଞ୍ଚ କରାଯାଇପାରିଲା ନାହିଁ"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"ଆପ୍‌ ସର୍ଟକଟ୍‌ ଯୋଗ କରନ୍ତୁ"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"ୱାଲ୍‌‌ପେପର୍‌କୁ ସେଟ୍ କରନ୍ତୁ"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-pa/strings.xml b/SecondaryDisplayLauncher/res/values-pa/strings.xml
new file mode 100644
index 0000000..c5dd582
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-pa/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"ਸਰਗਰਮੀ ਨੂੰ ਲਾਂਚ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"ਐਪ ਸ਼ਾਰਟਕੱਟ ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"ਵਾਲਪੇਪਰ ਸੈੱਟ ਕਰੋ"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-pl/strings.xml b/SecondaryDisplayLauncher/res/values-pl/strings.xml
new file mode 100644
index 0000000..e8efaed
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-pl/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Nie udało się uruchomić aktywności"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Dodaj skrót do aplikacji"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Ustaw tapetę"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-pt-rPT/strings.xml b/SecondaryDisplayLauncher/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..67c7557
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-pt-rPT/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Não foi possível iniciar a atividade."</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Adicionar atalho de aplicação"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Definir imagem de fundo"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-pt/strings.xml b/SecondaryDisplayLauncher/res/values-pt/strings.xml
new file mode 100644
index 0000000..201fc07
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-pt/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Não foi possível abrir a atividade"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Adicionar atalho de apps"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Definir plano de fundo"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ro/strings.xml b/SecondaryDisplayLauncher/res/values-ro/strings.xml
new file mode 100644
index 0000000..e2e21c5
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ro/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Nu s-a putut lansa activitatea"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Adăugați comanda rapidă pentru aplicație"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Setați imaginea de fundal"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ru/strings.xml b/SecondaryDisplayLauncher/res/values-ru/strings.xml
new file mode 100644
index 0000000..64ba00e
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ru/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Не удалось запустить объект activity"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Добавить ярлык приложения"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Установить обои"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-si/strings.xml b/SecondaryDisplayLauncher/res/values-si/strings.xml
new file mode 100644
index 0000000..ac492eb
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-si/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"ක්‍රියාකාරකම දියත් කිරීමට නොහැකි විය"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"යෙදුම් කෙටිමඟ එක් කරන්න"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"බිතුපත සකසන්න"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-sk/strings.xml b/SecondaryDisplayLauncher/res/values-sk/strings.xml
new file mode 100644
index 0000000..5e6fa7a
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-sk/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Aktivitu sa nepodarilo spustiť"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Pridať odkaz do aplikácie"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Nastaviť tapetu"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-sl/strings.xml b/SecondaryDisplayLauncher/res/values-sl/strings.xml
new file mode 100644
index 0000000..f54dec9
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-sl/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Dejavnosti ni bilo mogoče zagnati"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Dodaj bližnjico do aplikacije"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Nastavi ozadje"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-sq/strings.xml b/SecondaryDisplayLauncher/res/values-sq/strings.xml
new file mode 100644
index 0000000..e626dd1
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-sq/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Aktiviteti nuk mund të hapej"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Shto shkurtoren e aplikacionit"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Cakto imazhin e sfondit"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-sr/strings.xml b/SecondaryDisplayLauncher/res/values-sr/strings.xml
new file mode 100644
index 0000000..94214f1
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-sr/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Покретање активности није успело"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Додај пречицу за апликацију"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Подесите позадину"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-sv/strings.xml b/SecondaryDisplayLauncher/res/values-sv/strings.xml
new file mode 100644
index 0000000..53e17ef
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-sv/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Det gick inte att starta aktiviteten"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Lägg till appgenväg"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Ange bakgrund"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-sw/strings.xml b/SecondaryDisplayLauncher/res/values-sw/strings.xml
new file mode 100644
index 0000000..490561a
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-sw/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Imeshindwa kuanzisha shughuli"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Ongeza njia ya mkato ya programu"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Weka mandhari"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-sw600dp/dimens.xml b/SecondaryDisplayLauncher/res/values-sw600dp/dimens.xml
new file mode 100644
index 0000000..f33a8db
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-sw600dp/dimens.xml
@@ -0,0 +1,22 @@
+<?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.
+  -->
+
+<resources>
+    <dimen name="app_picker_width">400dp</dimen>
+    <dimen name="app_picker_height">400dp</dimen>
+    <dimen name="app_picker_fab_margin">60dp</dimen>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-sw720dp/dimens.xml b/SecondaryDisplayLauncher/res/values-sw720dp/dimens.xml
new file mode 100644
index 0000000..524e52a
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-sw720dp/dimens.xml
@@ -0,0 +1,22 @@
+<?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.
+  -->
+
+<resources>
+    <dimen name="app_picker_width">660dp</dimen>
+    <dimen name="app_picker_height">660dp</dimen>
+    <dimen name="app_picker_fab_margin">70dp</dimen>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ta/strings.xml b/SecondaryDisplayLauncher/res/values-ta/strings.xml
new file mode 100644
index 0000000..2f1262f
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ta/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"நடவடிக்கையைத் துவக்க இயலவில்லை"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"ஆப்ஸ் குறுக்குவழியைச் சேர்"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"வால்பேப்பரை அமை"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-te/strings.xml b/SecondaryDisplayLauncher/res/values-te/strings.xml
new file mode 100644
index 0000000..3dd3c9b
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-te/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"కార్యకలాపాన్ని ప్రారంభించడం సాధ్యం కాలేదు"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"యాప్ షార్ట్‌కట్‌ని జోడించు"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"వాల్‌పేపర్‌ను సెట్ చేయండి"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-th/strings.xml b/SecondaryDisplayLauncher/res/values-th/strings.xml
new file mode 100644
index 0000000..6368950
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-th/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"เปิดกิจกรรมไม่ได้"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"เพิ่มทางลัดของแอป"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"ตั้งวอลเปเปอร์"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-tl/strings.xml b/SecondaryDisplayLauncher/res/values-tl/strings.xml
new file mode 100644
index 0000000..192e5c4
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-tl/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Hindi mailunsad ang aktibidad"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Magdagdag ng shortcut ng app"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Magtakda ng wallpaper"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-tr/strings.xml b/SecondaryDisplayLauncher/res/values-tr/strings.xml
new file mode 100644
index 0000000..e7ed998
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-tr/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"İşlem başlatılamadı"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Uygulama kısayolu ekle"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Duvar kağıdı ayarla"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-uk/strings.xml b/SecondaryDisplayLauncher/res/values-uk/strings.xml
new file mode 100644
index 0000000..e465995
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-uk/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Не вдалося запустити активність"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Розмістити ярлик додатка"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Вибрати фоновий малюнок"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-ur/strings.xml b/SecondaryDisplayLauncher/res/values-ur/strings.xml
new file mode 100644
index 0000000..e4c8641
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-ur/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"سرگرمی کو شروع نہیں کیا جا سکا"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"ایپ شارٹ کٹ شامل کریں"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"وال پیپر سیٹ کریں"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-uz/strings.xml b/SecondaryDisplayLauncher/res/values-uz/strings.xml
new file mode 100644
index 0000000..585739d
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-uz/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Faollik ishga tushmadi"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Yorliq yaratish"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Fonga rasm oʻrnatish"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-vi/strings.xml b/SecondaryDisplayLauncher/res/values-vi/strings.xml
new file mode 100644
index 0000000..15a1a44
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-vi/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Không thể chạy hoạt động"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Thêm lối tắt ứng dụng"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Đặt hình nền"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-zh-rCN/strings.xml b/SecondaryDisplayLauncher/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..3358499
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-zh-rCN/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"无法启动该操作组件"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"添加应用快捷方式"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"设置壁纸"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-zh-rHK/strings.xml b/SecondaryDisplayLauncher/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..bf76f29
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-zh-rHK/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"無法啟動活動"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"新增應用程式捷徑"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"設定桌布"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-zh-rTW/strings.xml b/SecondaryDisplayLauncher/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..bf76f29
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-zh-rTW/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"無法啟動活動"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"新增應用程式捷徑"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"設定桌布"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values-zu/strings.xml b/SecondaryDisplayLauncher/res/values-zu/strings.xml
new file mode 100644
index 0000000..ad2f6b9
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values-zu/strings.xml
@@ -0,0 +1,25 @@
+<?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.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch" msgid="7873588052226763866">"Ayikwazanga ukuqalisa umsebenzi"</string>
+    <string name="add_app_shortcut" msgid="2756755330707509435">"Engeza isinqamuleli sohlelo lokusebenza"</string>
+    <string name="set_wallpaper" msgid="6475195450505435904">"Setha isithombe sangemuva"</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values/colors.xml b/SecondaryDisplayLauncher/res/values/colors.xml
new file mode 100644
index 0000000..66b41a2
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values/colors.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/colors.xml
+**
+** Copyright 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.
+*/
+-->
+<resources>
+    <color name="launcher_bg_color">#884e8391</color>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values/dimens.xml b/SecondaryDisplayLauncher/res/values/dimens.xml
new file mode 100644
index 0000000..7cca607
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values/dimens.xml
@@ -0,0 +1,31 @@
+<?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.
+-->
+
+<resources>
+    <dimen name="app_list_col_width">72dp</dimen>
+    <dimen name="app_list_horizontal_spacing">24dp</dimen>
+    <dimen name="app_list_vertical_spacing">24dp</dimen>
+    <dimen name="app_icon_width">64dp</dimen>
+    <dimen name="app_icon_height">64dp</dimen>
+    <dimen name="app_grid_margin_top">24dp</dimen>
+    <dimen name="app_grid_margin_left">8dp</dimen>
+    <dimen name="app_grid_margin_right">8dp</dimen>
+
+    <dimen name="app_picker_width">300dp</dimen>
+    <dimen name="app_picker_height">300dp</dimen>
+    <dimen name="app_picker_fab_margin">20dp</dimen>
+    <dimen name="options_button_margin">20dp</dimen>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values/strings.xml b/SecondaryDisplayLauncher/res/values/strings.xml
new file mode 100644
index 0000000..b68918a
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values/strings.xml
@@ -0,0 +1,24 @@
+<?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.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="couldnt_launch">Couldn\'t launch the activity</string>
+    <string name="add_app_shortcut">Add app shortcut</string>
+    <string name="set_wallpaper">Set wallpaper</string>
+</resources>
diff --git a/SecondaryDisplayLauncher/res/values/styles.xml b/SecondaryDisplayLauncher/res/values/styles.xml
new file mode 100644
index 0000000..4bfda6a
--- /dev/null
+++ b/SecondaryDisplayLauncher/res/values/styles.xml
@@ -0,0 +1,30 @@
+<?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.
+*/
+-->
+
+<resources>
+    <style name="SecondaryLauncherTheme" parent="Theme.AppCompat.Light.NoActionBar" >
+        <item name="android:windowShowWallpaper">true</item>
+        <item name="android:windowNoTitle">true</item>
+        <item name="android:windowIsTranslucent">true</item>
+        <item name="android:windowTranslucentStatus">true</item>
+        <item name="android:windowTranslucentNavigation">true</item>
+        <item name="android:colorBackgroundCacheHint">@null</item>
+        <item name="android:windowBackground">@android:color/transparent</item>
+    </style>
+</resources>
diff --git a/SecondaryDisplayLauncher/src/com/android/launcher3/AppEntry.java b/SecondaryDisplayLauncher/src/com/android/launcher3/AppEntry.java
new file mode 100644
index 0000000..3017b81
--- /dev/null
+++ b/SecondaryDisplayLauncher/src/com/android/launcher3/AppEntry.java
@@ -0,0 +1,58 @@
+/**
+ * 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;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.graphics.drawable.Drawable;
+
+/** An entry that represents a single activity that can be launched. */
+public  class AppEntry {
+
+    private String mLabel;
+    private Drawable mIcon;
+    private Intent mLaunchIntent;
+
+    AppEntry(ResolveInfo info, PackageManager packageManager) {
+        mLabel = info.loadLabel(packageManager).toString();
+        mIcon = info.loadIcon(packageManager);
+        mLaunchIntent = new Intent();
+        mLaunchIntent.setComponent(new ComponentName(info.activityInfo.packageName,
+                info.activityInfo.name));
+    }
+
+    String getLabel() {
+        return mLabel;
+    }
+
+    Drawable getIcon() {
+        return mIcon;
+    }
+
+    Intent getLaunchIntent() { return mLaunchIntent; }
+
+    ComponentName getComponentName() {
+        return mLaunchIntent.getComponent();
+    }
+
+    @Override
+    public String toString() {
+        return mLabel;
+    }
+}
diff --git a/SecondaryDisplayLauncher/src/com/android/launcher3/AppListAdapter.java b/SecondaryDisplayLauncher/src/com/android/launcher3/AppListAdapter.java
new file mode 100644
index 0000000..aa115cb
--- /dev/null
+++ b/SecondaryDisplayLauncher/src/com/android/launcher3/AppListAdapter.java
@@ -0,0 +1,63 @@
+/**
+ * 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;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.launcher3.R;
+
+import java.util.List;
+
+/** Adapter for available apps list. */
+public class AppListAdapter extends ArrayAdapter<AppEntry> {
+    private final LayoutInflater mInflater;
+
+    AppListAdapter(Context context) {
+        super(context, android.R.layout.simple_list_item_2);
+        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+    }
+
+    void setData(List<AppEntry> data) {
+        clear();
+        if (data != null) {
+            addAll(data);
+        }
+    }
+
+    @Override
+    public View getView(int position, View convertView, ViewGroup parent) {
+        View view;
+
+        if (convertView == null) {
+            view = mInflater.inflate(R.layout.app_grid_item, parent, false);
+        } else {
+            view = convertView;
+        }
+
+        AppEntry item = getItem(position);
+        ((ImageView)view.findViewById(R.id.app_icon)).setImageDrawable(item.getIcon());
+        ((TextView)view.findViewById(R.id.app_name)).setText(item.getLabel());
+
+        return view;
+    }
+}
diff --git a/SecondaryDisplayLauncher/src/com/android/launcher3/AppListViewModel.java b/SecondaryDisplayLauncher/src/com/android/launcher3/AppListViewModel.java
new file mode 100644
index 0000000..914fd5e
--- /dev/null
+++ b/SecondaryDisplayLauncher/src/com/android/launcher3/AppListViewModel.java
@@ -0,0 +1,126 @@
+/**
+ * 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;
+
+import android.app.Application;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.AsyncTask;
+
+import androidx.lifecycle.AndroidViewModel;
+import androidx.lifecycle.LiveData;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A view model that provides a list of activities that can be launched.
+ */
+public class AppListViewModel extends AndroidViewModel {
+
+    private final AppListLiveData mLiveData;
+    private final PackageIntentReceiver
+            mPackageIntentReceiver;
+
+    public AppListViewModel(Application application) {
+        super(application);
+        mLiveData = new AppListLiveData(application);
+        mPackageIntentReceiver = new PackageIntentReceiver(mLiveData, application);
+    }
+
+    public LiveData<List<AppEntry>> getAppList() {
+        return mLiveData;
+    }
+
+    protected void onCleared() {
+        getApplication().unregisterReceiver(mPackageIntentReceiver);
+    }
+}
+
+class AppListLiveData extends LiveData<List<AppEntry>> {
+
+    private final PackageManager mPackageManager;
+    private int mCurrentDataVersion;
+
+    public AppListLiveData(Context context) {
+        mPackageManager = context.getPackageManager();
+        loadData();
+    }
+
+    void loadData() {
+        final int loadDataVersion = ++mCurrentDataVersion;
+
+        new AsyncTask<Void, Void, List<AppEntry>>() {
+            @Override
+            protected List<AppEntry> doInBackground(Void... voids) {
+                Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+                mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+                List<ResolveInfo> apps = mPackageManager.queryIntentActivities(mainIntent,
+                        PackageManager.GET_META_DATA);
+
+                List<AppEntry> entries = new ArrayList<>();
+                if (apps != null) {
+                    for (ResolveInfo app : apps) {
+                        AppEntry entry = new AppEntry(app, mPackageManager);
+                        entries.add(entry);
+                    }
+                }
+                return entries;
+            }
+
+            @Override
+            protected void onPostExecute(List<AppEntry> data) {
+                if (mCurrentDataVersion == loadDataVersion) {
+                    setValue(data);
+                }
+            }
+        }.execute();
+    }
+}
+
+/**
+ * Receiver used to notify live data about app list changes.
+ */
+class PackageIntentReceiver extends BroadcastReceiver {
+
+    private final AppListLiveData mLiveData;
+
+    public PackageIntentReceiver(AppListLiveData liveData, Context context) {
+        mLiveData = liveData;
+        IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
+        filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
+        filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
+        filter.addDataScheme("package");
+        context.registerReceiver(this, filter);
+
+        // Register for events related to sdcard installation.
+        IntentFilter sdFilter = new IntentFilter();
+        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
+        sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
+        context.registerReceiver(this, sdFilter);
+    }
+
+    @Override
+    public void onReceive(Context context, Intent intent) {
+        mLiveData.loadData();
+    }
+}
\ No newline at end of file
diff --git a/SecondaryDisplayLauncher/src/com/android/launcher3/PinnedAppListViewModel.java b/SecondaryDisplayLauncher/src/com/android/launcher3/PinnedAppListViewModel.java
new file mode 100644
index 0000000..4f92038
--- /dev/null
+++ b/SecondaryDisplayLauncher/src/com/android/launcher3/PinnedAppListViewModel.java
@@ -0,0 +1,120 @@
+/**
+ * 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;
+
+import static com.android.launcher3.PinnedAppListViewModel.PINNED_APPS_KEY;
+
+import android.app.Application;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.AsyncTask;
+
+import androidx.lifecycle.AndroidViewModel;
+import androidx.lifecycle.LiveData;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * A view model that provides a list of activities that were pinned by user to always display on
+ * home screen.
+ * The pinned activities are stored in {@link SharedPreferences} to keep the sample simple :).
+ */
+public class PinnedAppListViewModel extends AndroidViewModel {
+
+    final static String PINNED_APPS_KEY = "pinned_apps";
+
+    private final PinnedAppListLiveData mLiveData;
+
+    public PinnedAppListViewModel(Application application) {
+        super(application);
+        mLiveData = new PinnedAppListLiveData(application);
+    }
+
+    public LiveData<List<AppEntry>> getPinnedAppList() {
+        return mLiveData;
+    }
+}
+
+class PinnedAppListLiveData extends LiveData<List<AppEntry>> {
+
+    private final Context mContext;
+    private final PackageManager mPackageManager;
+    // Store listener reference, so it won't be GC-ed.
+    private final SharedPreferences.OnSharedPreferenceChangeListener mChangeListener;
+    private int mCurrentDataVersion;
+
+    public PinnedAppListLiveData(Context context) {
+        mContext = context;
+        mPackageManager = context.getPackageManager();
+
+        final SharedPreferences prefs = context.getSharedPreferences(PINNED_APPS_KEY, 0);
+        mChangeListener = (preferences, key) -> {
+            loadData();
+        };
+        prefs.registerOnSharedPreferenceChangeListener(mChangeListener);
+
+        loadData();
+    }
+
+    private void loadData() {
+        final int loadDataVersion = ++mCurrentDataVersion;
+
+        new AsyncTask<Void, Void, List<AppEntry>>() {
+            @Override
+            protected List<AppEntry> doInBackground(Void... voids) {
+                List<AppEntry> entries = new ArrayList<>();
+
+                final SharedPreferences sp = mContext.getSharedPreferences(PINNED_APPS_KEY, 0);
+                final Set<String> pinnedAppsComponents = sp.getStringSet(PINNED_APPS_KEY, null);
+                if (pinnedAppsComponents == null) {
+                    return null;
+                }
+
+                for (String componentString : pinnedAppsComponents) {
+                    final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
+                    mainIntent.setComponent(ComponentName.unflattenFromString(componentString));
+                    mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
+
+                    final List<ResolveInfo> apps = mPackageManager.queryIntentActivities(mainIntent,
+                            PackageManager.GET_META_DATA);
+
+                    if (apps != null) {
+                        for (ResolveInfo app : apps) {
+                            final AppEntry entry = new AppEntry(app, mPackageManager);
+                            entries.add(entry);
+                        }
+                    }
+                }
+
+                return entries;
+            }
+
+            @Override
+            protected void onPostExecute(List<AppEntry> data) {
+                if (mCurrentDataVersion == loadDataVersion) {
+                    setValue(data);
+                }
+            }
+        }.execute();
+    }
+}
\ No newline at end of file
diff --git a/SecondaryDisplayLauncher/src/com/android/launcher3/PinnedAppPickerDialog.java b/SecondaryDisplayLauncher/src/com/android/launcher3/PinnedAppPickerDialog.java
new file mode 100644
index 0000000..02e6e4a
--- /dev/null
+++ b/SecondaryDisplayLauncher/src/com/android/launcher3/PinnedAppPickerDialog.java
@@ -0,0 +1,74 @@
+/**
+ * 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;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.GridView;
+
+import androidx.fragment.app.DialogFragment;
+
+import com.android.launcher3.R;
+
+/**
+ * Callback to be invoked when an app was picked.
+ */
+interface AppPickedCallback {
+    void onAppPicked(AppEntry appEntry);
+}
+
+/**
+ * Dialog that provides the user with a list of available apps to pin to the home screen.
+ */
+public class PinnedAppPickerDialog extends DialogFragment {
+
+    private AppListAdapter mAppListAdapter;
+    private AppPickedCallback mAppPickerCallback;
+
+    public PinnedAppPickerDialog() {
+    }
+
+    public static PinnedAppPickerDialog newInstance(AppListAdapter appListAdapter,
+            AppPickedCallback callback) {
+        PinnedAppPickerDialog
+                frag = new PinnedAppPickerDialog();
+        frag.mAppListAdapter = appListAdapter;
+        frag.mAppPickerCallback = callback;
+        return frag;
+    }
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.app_picker_dialog, container);
+    }
+
+    @Override
+    public void onViewCreated(View view, Bundle savedInstanceState) {
+        super.onViewCreated(view, savedInstanceState);
+
+        GridView appGridView = view.findViewById(R.id.picker_app_grid);
+        appGridView.setAdapter(mAppListAdapter);
+        appGridView.setOnItemClickListener((adapterView, itemView, position, id) -> {
+            final AppEntry entry = mAppListAdapter.getItem(position);
+            mAppPickerCallback.onAppPicked(entry);
+            dismiss();
+        });
+    }
+}
\ No newline at end of file
diff --git a/SecondaryDisplayLauncher/src/com/android/launcher3/SecondaryDisplayLauncher.java b/SecondaryDisplayLauncher/src/com/android/launcher3/SecondaryDisplayLauncher.java
new file mode 100644
index 0000000..5e8b402
--- /dev/null
+++ b/SecondaryDisplayLauncher/src/com/android/launcher3/SecondaryDisplayLauncher.java
@@ -0,0 +1,217 @@
+/**
+ * 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;
+
+import static com.android.launcher3.PinnedAppListViewModel.PINNED_APPS_KEY;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.app.AlertDialog;
+import android.app.Application;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.support.design.circularreveal.cardview.CircularRevealCardView;
+import android.support.design.widget.FloatingActionButton;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewAnimationUtils;
+import android.widget.GridView;
+import android.widget.ImageButton;
+import android.widget.PopupMenu;
+
+import androidx.fragment.app.FragmentActivity;
+import androidx.fragment.app.FragmentManager;
+import androidx.lifecycle.ViewModelProvider;
+import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Secondary launcher activity. It's launch mode is configured as "singleTop" to allow showing on
+ * multiple displays and to ensure a single instance per each display.
+ */
+public class SecondaryDisplayLauncher extends FragmentActivity implements AppPickedCallback,
+        PopupMenu.OnMenuItemClickListener {
+
+    private AppListAdapter mAppListAdapter;
+    private AppListAdapter mPinnedAppListAdapter;
+    private CircularRevealCardView mAppDrawerView;
+    private FloatingActionButton mFab;
+
+    private boolean mAppDrawerShown;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.secondary_display_launcher);
+
+        mAppDrawerView = findViewById(R.id.FloatingSheet);
+        mFab = findViewById(R.id.FloatingActionButton);
+
+        mFab.setOnClickListener((View v) -> {
+            showAppDrawer(true);
+        });
+
+        final ViewModelProvider viewModelProvider = new ViewModelProvider(getViewModelStore(),
+                new AndroidViewModelFactory((Application) getApplicationContext()));
+
+        mPinnedAppListAdapter = new AppListAdapter(this);
+        final GridView pinnedAppGridView = findViewById(R.id.pinned_app_grid);
+        pinnedAppGridView.setAdapter(mPinnedAppListAdapter);
+        pinnedAppGridView.setOnItemClickListener((adapterView, view, position, id) -> {
+            final AppEntry entry = mPinnedAppListAdapter.getItem(position);
+            launch(entry.getLaunchIntent());
+        });
+        final PinnedAppListViewModel pinnedAppListViewModel =
+                viewModelProvider.get(PinnedAppListViewModel.class);
+        pinnedAppListViewModel.getPinnedAppList().observe(this, data -> {
+            mPinnedAppListAdapter.setData(data);
+        });
+
+        mAppListAdapter = new AppListAdapter(this);
+        final GridView appGridView = findViewById(R.id.app_grid);
+        appGridView.setAdapter(mAppListAdapter);
+        appGridView.setOnItemClickListener((adapterView, view, position, id) -> {
+            final AppEntry entry = mAppListAdapter.getItem(position);
+            launch(entry.getLaunchIntent());
+        });
+        final AppListViewModel appListViewModel = viewModelProvider.get(AppListViewModel.class);
+        appListViewModel.getAppList().observe(this, data -> {
+            mAppListAdapter.setData(data);
+        });
+
+        ImageButton optionsButton = findViewById(R.id.OptionsButton);
+        optionsButton.setOnClickListener((View v) -> {
+            PopupMenu popup = new PopupMenu(this,v);
+            popup.setOnMenuItemClickListener(this);
+            MenuInflater inflater = popup.getMenuInflater();
+            inflater.inflate(R.menu.context_menu, popup.getMenu());
+            popup.show();
+        });
+    }
+
+    @Override
+    public boolean onMenuItemClick(MenuItem item) {
+        // Respond to picking one of the popup menu items.
+        final int id = item.getItemId();
+        if (id == R.id.add_app_shortcut) {
+            FragmentManager fm = getSupportFragmentManager();
+            PinnedAppPickerDialog pickerDialogFragment =
+                    PinnedAppPickerDialog.newInstance(mAppListAdapter, this);
+            pickerDialogFragment.show(fm, "fragment_app_picker");
+            return true;
+        } else if (id == R.id.set_wallpaper) {
+            Intent intent = new Intent(Intent.ACTION_SET_WALLPAPER);
+            startActivity(Intent.createChooser(intent, getString(R.string.set_wallpaper)));
+            return true;
+        }
+
+        return true;
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+        showAppDrawer(false);
+    }
+
+    public void onBackPressed() {
+        // If the app drawer was shown - hide it. Otherwise, not doing anything since we don't want
+        // to close the launcher.
+        showAppDrawer(false);
+    }
+
+    public void onNewIntent(Intent intent) {
+        super.onNewIntent(intent);
+        // A new intent will bring the launcher to top. Hide the app drawer to reset the state.
+        showAppDrawer(false);
+    }
+
+    void launch(Intent launchIntent) {
+        launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        try {
+            startActivity(launchIntent);
+        } catch (Exception e) {
+            final AlertDialog.Builder builder =
+                    new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
+            builder.setTitle(R.string.couldnt_launch)
+                    .setMessage(e.getLocalizedMessage())
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .show();
+        }
+    }
+
+    /**
+     * Store the picked app to persistent pinned list and update the loader.
+     */
+    @Override
+    public void onAppPicked(AppEntry appEntry) {
+        final SharedPreferences sp = getSharedPreferences(PINNED_APPS_KEY, 0);
+        Set<String> pinnedApps = sp.getStringSet(PINNED_APPS_KEY, null);
+        if (pinnedApps == null) {
+            pinnedApps = new HashSet<String>();
+        } else {
+            // Always need to create a new object to make sure that the changes are persisted.
+            pinnedApps = new HashSet<String>(pinnedApps);
+        }
+        pinnedApps.add(appEntry.getComponentName().flattenToString());
+
+        final SharedPreferences.Editor editor = sp.edit();
+        editor.putStringSet(PINNED_APPS_KEY, pinnedApps);
+        editor.apply();
+    }
+
+    /**
+     * Show/hide app drawer card with animation.
+     */
+    private void showAppDrawer(boolean show) {
+        if (show == mAppDrawerShown) {
+            return;
+        }
+
+        final Animator animator = revealAnimator(mAppDrawerView, show);
+        if (show) {
+            mAppDrawerShown = true;
+            mAppDrawerView.setVisibility(View.VISIBLE);
+            mFab.setVisibility(View.INVISIBLE);
+        } else {
+            mAppDrawerShown = false;
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    super.onAnimationEnd(animation);
+                    mAppDrawerView.setVisibility(View.INVISIBLE);
+                    mFab.setVisibility(View.VISIBLE);
+                }
+            });
+        }
+        animator.start();
+    }
+
+    /**
+     * Create reveal/hide animator for app list card.
+     */
+    private Animator revealAnimator(View view, boolean open) {
+        final int radius = (int) Math.hypot((double) view.getWidth(), (double) view.getHeight());
+        return ViewAnimationUtils.createCircularReveal(view, view.getRight(), view.getBottom(),
+                open ? 0 : radius, open ? radius : 0);
+    }
+}
diff --git a/build.gradle b/build.gradle
index 33409c5..4191d47 100644
--- a/build.gradle
+++ b/build.gradle
@@ -36,41 +36,56 @@
         targetCompatibility JavaVersion.VERSION_1_8
     }
 
-    flavorDimensions "default"
+    // The flavor dimensions for build variants (e.g. aospWithQuickstep, aospWithoutQuickstep)
+    // See: https://developer.android.com/studio/build/build-variants#flavor-dimensions
+    flavorDimensions "app", "recents"
 
     productFlavors {
         aosp {
-            dimension "default"
+            dimension "app"
             applicationId 'com.android.launcher3'
             testApplicationId 'com.android.launcher3.tests'
         }
 
         l3go {
-            dimension "default"
+            dimension "app"
             applicationId 'com.android.launcher3'
             testApplicationId 'com.android.launcher3.tests'
         }
 
-        quickstep {
-            dimension "default"
-            applicationId 'com.android.launcher3'
-            testApplicationId 'com.android.launcher3.tests'
+        withQuickstep {
+            dimension "recents"
 
             minSdkVersion 28
         }
+
+        withQuickstepIconRecents {
+            dimension "recents"
+
+            minSdkVersion 28
+        }
+
+        withoutQuickstep {
+            dimension "recents"
+        }
     }
 
     // Disable release builds for now
     android.variantFilter { variant ->
         if (variant.buildType.name.endsWith('release')) {
-            variant.setIgnore(true);
+            variant.setIgnore(true)
+        }
+
+        // Icon recents is Go only
+        if (name.contains("WithQuickstepIconRecents") && !name.contains("l3go")) {
+            variant.setIgnore(true)
         }
     }
 
     sourceSets {
         main {
             res.srcDirs = ['res']
-            java.srcDirs = ['src', 'src_shortcuts_overrides']
+            java.srcDirs = ['src', 'src_plugins']
             manifest.srcFile 'AndroidManifest-common.xml'
             proto {
                 srcDir 'protos/'
@@ -93,18 +108,29 @@
         }
 
         aosp {
-            java.srcDirs = ['src_flags', "src_ui_overrides"]
+            java.srcDirs = ['src_flags', 'src_shortcuts_overrides']
+            manifest.srcFile "AndroidManifest.xml"
         }
 
         l3go {
             res.srcDirs = ['go/res']
-            java.srcDirs = ['go/src', "src_ui_overrides"]
+            java.srcDirs = ['go/src']
             manifest.srcFile "go/AndroidManifest.xml"
         }
 
-        quickstep {
-            res.srcDirs = ['quickstep/res']
-            java.srcDirs = ['src_flags', 'quickstep/src']
+        withoutQuickstep {
+            java.srcDirs = ['src_ui_overrides']
+        }
+
+        withQuickstep {
+            res.srcDirs = ['quickstep/res', 'quickstep/recents_ui_overrides/res']
+            java.srcDirs = ['quickstep/src', 'quickstep/recents_ui_overrides/src']
+            manifest.srcFile "quickstep/AndroidManifest.xml"
+        }
+
+        withQuickstepIconRecents {
+            res.srcDirs = ['quickstep/res', 'go/quickstep/res']
+            java.srcDirs = ['quickstep/src', 'go/quickstep/src']
             manifest.srcFile "quickstep/AndroidManifest.xml"
         }
     }
@@ -121,14 +147,17 @@
     implementation "androidx.dynamicanimation:dynamicanimation:${ANDROID_X_VERSION}"
     implementation "androidx.recyclerview:recyclerview:${ANDROID_X_VERSION}"
     implementation "androidx.preference:preference:${ANDROID_X_VERSION}"
-    implementation PROTOBUF_DEPENDENCY
     implementation project(':IconLoader')
+    implementation fileTree(dir: "libs", include: 'launcher_protos.jar')
 
-    // This is already included in sysui_shared
-    aospImplementation fileTree(dir: "libs", include: 'plugin_core.jar')
-    l3goImplementation fileTree(dir: "libs", include: 'plugin_core.jar')
+    // Recents lib dependency
+    withQuickstepImplementation fileTree(dir: "quickstep/libs", include: 'sysui_shared.jar')
 
-    quickstepImplementation fileTree(dir: "quickstep/libs", include: 'sysui_shared.jar')
+    // Recents lib dependency for Go
+    withQuickstepIconRecentsImplementation fileTree(dir: "quickstep/libs", include: 'sysui_shared.jar')
+
+    // Required for AOSP to compile. This is already included in the sysui_shared.jar
+    withoutQuickstepImplementation fileTree(dir: "libs", include: 'plugin_core.jar')
 
     testImplementation 'junit:junit:4.12'
     androidTestImplementation "org.mockito:mockito-core:1.9.5"
diff --git a/go/AndroidManifest.xml b/go/AndroidManifest.xml
index 0a9ad7b..25518af 100644
--- a/go/AndroidManifest.xml
+++ b/go/AndroidManifest.xml
@@ -22,7 +22,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     package="com.android.launcher3" >
 
-    <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
+    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"/>
 
     <application
         android:backupAgent="com.android.launcher3.LauncherBackupAgent"
@@ -36,16 +36,14 @@
         android:restoreAnyVersion="true"
         android:supportsRtl="true" >
 
-        <!-- Activity for handling PinItemRequest. Only supports shortcuts -->
+        <!-- Activity for handling PinItemRequest is disabled on Android Go. -->
         <activity android:name="com.android.launcher3.dragndrop.AddItemActivity"
             android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert"
             android:excludeFromRecents="true"
             android:autoRemoveFromRecents="true"
             android:label="@string/action_add_to_workspace"
+            android:enabled="false"
             tools:node="replace" >
-            <intent-filter>
-                <action android:name="android.content.pm.action.CONFIRM_PIN_SHORTCUT" />
-            </intent-filter>
         </activity>
 
     </application>
diff --git a/go/quickstep/res/layout/icon_recents_root_view.xml b/go/quickstep/res/layout/icon_recents_root_view.xml
new file mode 100644
index 0000000..82d5890
--- /dev/null
+++ b/go/quickstep/res/layout/icon_recents_root_view.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<com.android.quickstep.views.IconRecentsView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:gravity="center">
+    <!-- TODO(114136250): Remove this temporary placeholder view for Go recents -->
+    <TextView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:text="Stub!"
+        android:textSize="40sp"/>
+</com.android.quickstep.views.IconRecentsView>
\ No newline at end of file
diff --git a/go/quickstep/res/layout/overview_panel.xml b/go/quickstep/res/layout/overview_panel.xml
new file mode 100644
index 0000000..601edce
--- /dev/null
+++ b/go/quickstep/res/layout/overview_panel.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<fragment android:name="com.android.quickstep.IconRecentsFragment"
+          xmlns:android="http://schemas.android.com/apk/res/android"
+          android:id="@+id/low_ram_recents_fragment"
+          android:layout_width="match_parent"
+          android:layout_height="match_parent"/>
diff --git a/go/quickstep/src/com/android/launcher3/uioverrides/PortraitOverviewStateTouchHelper.java b/go/quickstep/src/com/android/launcher3/uioverrides/PortraitOverviewStateTouchHelper.java
new file mode 100644
index 0000000..a3b41b0
--- /dev/null
+++ b/go/quickstep/src/com/android/launcher3/uioverrides/PortraitOverviewStateTouchHelper.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.uioverrides;
+
+import android.view.MotionEvent;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.util.PendingAnimation;
+
+/**
+ * Helper class for {@link PortraitStatesTouchController} that determines swipeable regions and
+ * animations on the overview state that depend on the recents implementation.
+ */
+public final class PortraitOverviewStateTouchHelper {
+
+    public PortraitOverviewStateTouchHelper(Launcher launcher) {}
+
+    /**
+     * Whether or not {@link PortraitStatesTouchController} should intercept the touch when on the
+     * overview state.
+     *
+     * @param ev the motion event
+     * @return true if we should intercept the motion event
+     */
+    boolean canInterceptTouch(MotionEvent ev) {
+        // Go does not support swiping to all-apps from recents.
+        return false;
+    }
+
+    /**
+     * Whether or not swiping down to leave overview state should return to the currently running
+     * task app.
+     *
+     * @return true if going back should take the user to the currently running task
+     */
+    boolean shouldSwipeDownReturnToApp() {
+        // Go does not support swiping tasks down to launch tasks from recents.
+        return false;
+    }
+
+    /**
+     * Create the animation for going from overview to the task app via swiping.
+     *
+     * @param duration how long the animation should be
+     * @return the animation
+     */
+    PendingAnimation createSwipeDownToTaskAppAnimation(long duration) {
+        // Go does not support swiping tasks down to launch tasks from recents.
+        return null;
+    }
+}
diff --git a/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
new file mode 100644
index 0000000..d0c255c
--- /dev/null
+++ b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.uioverrides;
+
+import static android.view.View.VISIBLE;
+
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+
+import android.view.View;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.util.TouchController;
+
+/**
+ * Provides recents-related {@link UiFactory} logic and classes.
+ */
+public final class RecentsUiFactory {
+
+    // Scale recents takes before animating in
+    private static final float RECENTS_PREPARE_SCALE = 1.33f;
+
+    private RecentsUiFactory() {}
+
+    /**
+     * Creates and returns a touch controller for swiping recents tasks.
+     *
+     * @param launcher the launcher activity
+     * @return the touch controller for recents tasks
+     */
+    public static TouchController createTaskSwipeController(Launcher launcher) {
+        // We leave all input handling to the view itself.
+        return null;
+    }
+
+    /**
+     * Creates and returns the controller responsible for recents view state transitions.
+     *
+     * @param launcher the launcher activity
+     * @return state handler for recents
+     */
+    public static StateHandler createRecentsViewStateController(Launcher launcher) {
+        return new RecentsViewStateController(launcher);
+    }
+
+    /**
+     * Prepare the recents view to animate in.
+     *
+     * @param launcher the launcher activity
+     */
+    public static void prepareToShowRecents(Launcher launcher) {
+        View overview = launcher.getOverviewPanel();
+        if (overview.getVisibility() != VISIBLE) {
+            SCALE_PROPERTY.set(overview, RECENTS_PREPARE_SCALE);
+        }
+    }
+
+    /**
+     * Clean-up logic that occurs when recents is no longer in use/visible.
+     *
+     * @param launcher the launcher activity
+     */
+    public static void resetRecents(Launcher launcher) {}
+
+    /**
+     * Recents logic that triggers when launcher state changes or launcher activity stops/resumes.
+     *
+     * @param launcher the launcher activity
+     */
+    public static void onLauncherStateOrResumeChanged(Launcher launcher) {}
+}
diff --git a/go/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
new file mode 100644
index 0000000..f1cb75b
--- /dev/null
+++ b/go/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.uioverrides;
+
+import static com.android.quickstep.views.IconRecentsView.CONTENT_ALPHA;
+import static com.android.quickstep.views.IconRecentsView.TRANSLATION_Y_FACTOR;
+
+import android.util.FloatProperty;
+
+import androidx.annotation.NonNull;
+
+import com.android.launcher3.Launcher;
+import com.android.quickstep.views.IconRecentsView;
+
+/**
+ * State handler for Go's {@link IconRecentsView}.
+ */
+public final class RecentsViewStateController extends
+        BaseRecentsViewStateController<IconRecentsView> {
+
+    public RecentsViewStateController(@NonNull Launcher launcher) {
+        super(launcher);
+    }
+
+    @Override
+    FloatProperty<IconRecentsView> getTranslationYFactorProperty() {
+        return TRANSLATION_Y_FACTOR;
+    }
+
+    @Override
+    FloatProperty<IconRecentsView> getContentAlphaProperty() {
+        return CONTENT_ALPHA;
+    }
+}
diff --git a/go/quickstep/src/com/android/quickstep/IconRecentsFragment.java b/go/quickstep/src/com/android/quickstep/IconRecentsFragment.java
new file mode 100644
index 0000000..facf0d2
--- /dev/null
+++ b/go/quickstep/src/com/android/quickstep/IconRecentsFragment.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.R;
+
+public class IconRecentsFragment extends Fragment {
+    @Nullable
+    @Override
+    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
+            @Nullable Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.icon_recents_root_view, container, false);
+    }
+}
\ No newline at end of file
diff --git a/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
new file mode 100644
index 0000000..e4741e9
--- /dev/null
+++ b/go/quickstep/src/com/android/quickstep/views/IconRecentsView.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep.views;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.FloatProperty;
+import android.view.ViewDebug;
+import android.widget.FrameLayout;
+
+/**
+ * Root view for the icon recents view.
+ */
+public final class IconRecentsView extends FrameLayout {
+
+    public static final FloatProperty<IconRecentsView> TRANSLATION_Y_FACTOR =
+            new FloatProperty<IconRecentsView>("translationYFactor") {
+
+                @Override
+                public void setValue(IconRecentsView view, float v) {
+                    view.setTranslationYFactor(v);
+                }
+
+                @Override
+                public Float get(IconRecentsView view) {
+                    return view.mTranslationYFactor;
+                }
+            };
+
+    public static final FloatProperty<IconRecentsView> CONTENT_ALPHA =
+            new FloatProperty<IconRecentsView>("contentAlpha") {
+                @Override
+                public void setValue(IconRecentsView view, float v) {
+                    ALPHA.set(view, v);
+                }
+
+                @Override
+                public Float get(IconRecentsView view) {
+                    return ALPHA.get(view);
+                }
+            };
+
+    /**
+     * A ratio representing the view's relative placement within its padded space. For example, 0
+     * is top aligned and 0.5 is centered vertically.
+     */
+    @ViewDebug.ExportedProperty(category = "launcher")
+    private float mTranslationYFactor;
+
+    public IconRecentsView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public void setTranslationYFactor(float translationFactor) {
+        mTranslationYFactor = translationFactor;
+        setTranslationY(computeTranslationYForFactor(mTranslationYFactor));
+    }
+
+    private float computeTranslationYForFactor(float translationYFactor) {
+        return translationYFactor * (getPaddingBottom() - getPaddingTop());
+    }
+}
diff --git a/go/res/drawable/ic_widget.xml b/go/res/drawable/ic_widget.xml
deleted file mode 100644
index 5336876..0000000
--- a/go/res/drawable/ic_widget.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-Copyright (C) 2017 The Android Open Source Project
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-    you may not use this file except in compliance with the License.
-    You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
-        android:width="48dp"
-        android:height="48dp"
-        android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
-    <path
-        android:fillColor="#FFFFFFFF"
-        android:pathData="M3.9,18.35c2.5-2.49,5.78-3.64,10.14-3.64v3.05c0,0.47,0.57,0.71,0.9,0.37l5.74-5.74c0.41-0.41,0.41-1.08,0-1.49l-5.74-5.74
-        c-0.33-0.33-0.9-0.1-0.9,0.37v2.95c-6.32,0.9-9.56,4.9-11.02,9.34C2.86,18.34,3.51,18.74,3.9,18.35z"/>
-</vector>
diff --git a/go/res/layout/widget_cell_content.xml b/go/res/layout/widget_cell_content.xml
deleted file mode 100644
index 49506d9..0000000
--- a/go/res/layout/widget_cell_content.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2017 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<merge xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content">
-
-    <LinearLayout
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:paddingTop="@dimen/widget_preview_label_vertical_padding"
-        android:paddingBottom="@dimen/widget_preview_label_vertical_padding"
-        android:paddingLeft="@dimen/widget_preview_label_horizontal_padding"
-        android:paddingRight="@dimen/widget_preview_label_horizontal_padding"
-        android:orientation="horizontal">
-
-        <!-- The name of the widget. -->
-        <TextView
-            android:id="@+id/widget_name"
-            android:layout_width="0dp"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:ellipsize="end"
-            android:fadingEdge="horizontal"
-            android:fontFamily="sans-serif-condensed"
-            android:gravity="center"
-            android:singleLine="true"
-            android:maxLines="1"
-            android:textColor="?android:attr/textColorSecondary"
-            android:textSize="14sp" />
-
-        <!-- The original dimensions of the widget (can't be the same text as above due to different
-             style. -->
-        <TextView
-            android:id="@+id/widget_dims"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginStart="5dp"
-            android:layout_marginLeft="5dp"
-            android:visibility="gone"
-            android:textColor="?android:attr/textColorSecondary"
-            android:textSize="14sp"
-            android:fontFamily="sans-serif-condensed"
-            android:alpha="0.8" />
-    </LinearLayout>
-
-    <!-- The image of the widget. This view does not support padding. Any placement adjustment
-         should be done using margins. -->
-    <com.android.launcher3.widget.WidgetImageView
-        android:id="@+id/widget_preview"
-        android:layout_width="match_parent"
-        android:layout_height="0dp"
-        android:layout_weight="1" />
-</merge>
\ No newline at end of file
diff --git a/go/res/values-af/strings.xml b/go/res/values-af/strings.xml
deleted file mode 100644
index 10ac473..0000000
--- a/go/res/values-af/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Raak en hou om \'n kortpad op te tel."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dubbeltik en hou om \'n kortpad op te tel of gebruik gepasmaakte handelinge."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Kortpaaie"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-kortpaaie"</string>
-</resources>
diff --git a/go/res/values-am/strings.xml b/go/res/values-am/strings.xml
deleted file mode 100644
index b3b253f..0000000
--- a/go/res/values-am/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-ar/strings.xml b/go/res/values-ar/strings.xml
deleted file mode 100644
index 9888d0f..0000000
--- a/go/res/values-ar/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-as/strings.xml b/go/res/values-as/strings.xml
deleted file mode 100644
index 6b5807f..0000000
--- a/go/res/values-as/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-az/strings.xml b/go/res/values-az/strings.xml
deleted file mode 100644
index c4b8cb7..0000000
--- a/go/res/values-az/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Qısayolu seçmək üçün toxunub saxlayın."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Qısayollar"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> qısayolları"</string>
-</resources>
diff --git a/go/res/values-b+sr+Latn/strings.xml b/go/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 0da5699..0000000
--- a/go/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Dodirnite i zadržite da biste izabrali prečicu."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i zadržite da biste izabrali prečicu ili koristite prilagođene radnje."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Prečice"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečice za <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-be/strings.xml b/go/res/values-be/strings.xml
deleted file mode 100644
index 4189e35..0000000
--- a/go/res/values-be/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Дакраніцеся і ўтрымлiвайце ярлык, каб дадаць яго."</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/go/res/values-bg/strings.xml b/go/res/values-bg/strings.xml
deleted file mode 100644
index 1b85992..0000000
--- a/go/res/values-bg/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-bn/strings.xml b/go/res/values-bn/strings.xml
deleted file mode 100644
index c56c925..0000000
--- a/go/res/values-bn/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-bs/strings.xml b/go/res/values-bs/strings.xml
deleted file mode 100644
index 3141b9d..0000000
--- a/go/res/values-bs/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Dodirnite i držite da uzmete prečicu."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dodirnite dvaput i držite da uzmete prečicu ili koristite prilagođene akcije."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Prečice"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečice aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-ca/strings.xml b/go/res/values-ca/strings.xml
deleted file mode 100644
index 3b5c3f7..0000000
--- a/go/res/values-ca/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Mantén premuda una drecera per seleccionar-la."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Fes doble toc i mantén premut per seleccionar una drecera o per utilitzar accions personalitzades."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Dreceres"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Dreceres de l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-cs/strings.xml b/go/res/values-cs/strings.xml
deleted file mode 100644
index e4018f2..0000000
--- a/go/res/values-cs/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Zkratku vyberete podržením."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvojitým klepnutím a podržením vyberte zkratku, případně použijte vlastní akce."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Zkratky"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Zkratky aplikace <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-da/strings.xml b/go/res/values-da/strings.xml
deleted file mode 100644
index 821d36a..0000000
--- a/go/res/values-da/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Hold en genvej nede for at samle den op."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tryk to gange, og hold en genvej nede for at samle den op og bruge tilpassede handlinger."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Genveje"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-genveje"</string>
-</resources>
diff --git a/go/res/values-de/strings.xml b/go/res/values-de/strings.xml
deleted file mode 100644
index 43a1b3a..0000000
--- a/go/res/values-de/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Doppeltippen und halten, um eine Verknüpfung auszuwählen."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Doppeltippen und halten, um eine Verknüpfung auszuwählen oder benutzerdefinierte Aktionen zu nutzen."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Verknüpfungen"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-Verknüpfungen"</string>
-</resources>
diff --git a/go/res/values-el/strings.xml b/go/res/values-el/strings.xml
deleted file mode 100644
index ae59907..0000000
--- a/go/res/values-el/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-en-rAU/strings.xml b/go/res/values-en-rAU/strings.xml
deleted file mode 100644
index 2ee2c26..0000000
--- a/go/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Touch &amp; hold to pick up a shortcut."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Shortcuts"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shortcuts"</string>
-</resources>
diff --git a/go/res/values-en-rGB/strings.xml b/go/res/values-en-rGB/strings.xml
deleted file mode 100644
index 2ee2c26..0000000
--- a/go/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Touch &amp; hold to pick up a shortcut."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Shortcuts"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shortcuts"</string>
-</resources>
diff --git a/go/res/values-en-rIN/strings.xml b/go/res/values-en-rIN/strings.xml
deleted file mode 100644
index 2ee2c26..0000000
--- a/go/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Touch &amp; hold to pick up a shortcut."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Shortcuts"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shortcuts"</string>
-</resources>
diff --git a/go/res/values-es-rUS/strings.xml b/go/res/values-es-rUS/strings.xml
deleted file mode 100644
index 5212c03..0000000
--- a/go/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Mantén presionado para elegir un acceso directo."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Presiona dos veces y mantén presionado para elegir un acceso directo o usar acciones personalizadas."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Accesos directos"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Accesos directos de <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-es/strings.xml b/go/res/values-es/strings.xml
deleted file mode 100644
index 3ae4588..0000000
--- a/go/res/values-es/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Mantén pulsado el acceso directo que quieras."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toca dos veces y mantén pulsado el acceso directo o utiliza acciones personalizadas."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Accesos directos"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Accesos directos de <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-et/strings.xml b/go/res/values-et/strings.xml
deleted file mode 100644
index 2513e65..0000000
--- a/go/res/values-et/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Otsetee valimiseks puudutage seda pikalt."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Topeltpuudutage ja hoidke otsetee valimiseks või kohandatud toimingute kasutamiseks."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Otseteed"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Rakenduse <xliff:g id="NAME">%1$s</xliff:g> otseteed"</string>
-</resources>
diff --git a/go/res/values-eu/strings.xml b/go/res/values-eu/strings.xml
deleted file mode 100644
index 9949ef0..0000000
--- a/go/res/values-eu/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Eduki sakatuta lasterbide bat aukeratzeko."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Sakatu birritan eta eduki sakatuta lasterbide bat aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Lasterbideak"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioaren lasterbidea"</string>
-</resources>
diff --git a/go/res/values-fa/strings.xml b/go/res/values-fa/strings.xml
deleted file mode 100644
index f1584d9..0000000
--- a/go/res/values-fa/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-fi/strings.xml b/go/res/values-fi/strings.xml
deleted file mode 100644
index da9b0e1..0000000
--- a/go/res/values-fi/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Valitse pikakuvake painamalla sitä pitkään."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Valitse pikakuvake tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla pitkään."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Pikakuvakkeet"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Kohteen <xliff:g id="NAME">%1$s</xliff:g> pikakuvakkeet"</string>
-</resources>
diff --git a/go/res/values-fr-rCA/strings.xml b/go/res/values-fr-rCA/strings.xml
deleted file mode 100644
index c7fd6d6..0000000
--- a/go/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Maintenez un doigt sur le raccourci pour l\'ajouter"</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Touchez 2x un raccourci et maintenez doigt dessus pour l’aj. ou utiliser des actions personnalisées."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Raccourcis"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Raccourcis : <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-fr/strings.xml b/go/res/values-fr/strings.xml
deleted file mode 100644
index 238fe73..0000000
--- a/go/res/values-fr/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Appui prolongé pour sélectionner raccourci."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Appuyez 2 fois et maintenez pression pour sélectionner raccourci ou utilisez actions personnalisées."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Raccourcis"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Raccourcis <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-gl/strings.xml b/go/res/values-gl/strings.xml
deleted file mode 100644
index 31621d5..0000000
--- a/go/res/values-gl/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Mantén premido un atallo para seleccionalo."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toca dúas veces e mantén premido para seleccionar un atallo ou utiliza accións personalizadas."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Atallos"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Atallos da aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-gu/strings.xml b/go/res/values-gu/strings.xml
deleted file mode 100644
index bdb549f..0000000
--- a/go/res/values-gu/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-hi/strings.xml b/go/res/values-hi/strings.xml
deleted file mode 100644
index 2c1650a..0000000
--- a/go/res/values-hi/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-hr/strings.xml b/go/res/values-hr/strings.xml
deleted file mode 100644
index fccdeb5..0000000
--- a/go/res/values-hr/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Dodirnite i zadržite kako biste podigli prečac."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i zadržite pritisak kako biste podigli prečac ili pokušajte prilagođenim radnjama."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Prečaci"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečaci za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-hu/strings.xml b/go/res/values-hu/strings.xml
deleted file mode 100644
index 369c227..0000000
--- a/go/res/values-hu/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Felvételhez tartsa nyomva a parancsikont."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Parancsikon felvételéhez koppintson rá duplán és tartsa nyomva, vagy használjon egyéni műveleteket."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Parancsikonok"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-parancsikonok"</string>
-</resources>
diff --git a/go/res/values-hy/strings.xml b/go/res/values-hy/strings.xml
deleted file mode 100644
index 4747f6d..0000000
--- a/go/res/values-hy/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-in/strings.xml b/go/res/values-in/strings.xml
deleted file mode 100644
index c8b9da3..0000000
--- a/go/res/values-in/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Tap lama untuk memilih pintasan."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tap dua kali &amp; tahan untuk memilih pintasan atau menggunakan tindakan khusus."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Pintasan"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Pintasan <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-is/strings.xml b/go/res/values-is/strings.xml
deleted file mode 100644
index b8bb923..0000000
--- a/go/res/values-is/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Haltu fingri á flýtileið til að grípa hana."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ýttu tvisvar og haltu fingri á flýtileið til að grípa hana eða notaðu sérsniðnar aðgerðir."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Flýtileiðir"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> flýtileiðir"</string>
-</resources>
diff --git a/go/res/values-it/strings.xml b/go/res/values-it/strings.xml
deleted file mode 100644
index bc5d998..0000000
--- a/go/res/values-it/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Tocca e tieni premuto per scegliere la scorciatoia"</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tocca due volte e tieni premuto per scegliere una scorciatoia o per usare azioni personalizzate."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Scorciatoie"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Scorciatoie di <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-iw/strings.xml b/go/res/values-iw/strings.xml
deleted file mode 100644
index f541d4d..0000000
--- a/go/res/values-iw/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-ja/strings.xml b/go/res/values-ja/strings.xml
deleted file mode 100644
index 8f02d7f..0000000
--- a/go/res/values-ja/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-ka/strings.xml b/go/res/values-ka/strings.xml
deleted file mode 100644
index 1b46534..0000000
--- a/go/res/values-ka/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-kk/strings.xml b/go/res/values-kk/strings.xml
deleted file mode 100644
index e909818..0000000
--- a/go/res/values-kk/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-km/strings.xml b/go/res/values-km/strings.xml
deleted file mode 100644
index 40082a4..0000000
--- a/go/res/values-km/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-kn/strings.xml b/go/res/values-kn/strings.xml
deleted file mode 100644
index 9c121fd..0000000
--- a/go/res/values-kn/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-ko/strings.xml b/go/res/values-ko/strings.xml
deleted file mode 100644
index 60f925e..0000000
--- a/go/res/values-ko/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-ky/strings.xml b/go/res/values-ky/strings.xml
deleted file mode 100644
index 4c7e973..0000000
--- a/go/res/values-ky/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-lo/strings.xml b/go/res/values-lo/strings.xml
deleted file mode 100644
index 7864884..0000000
--- a/go/res/values-lo/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-lt/strings.xml b/go/res/values-lt/strings.xml
deleted file mode 100644
index 8f49032..0000000
--- a/go/res/values-lt/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Dukart pal. ir palaik., kad pasir. spart. klav."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dukart palieskite ir palaikykite, kad pasirinkt. spartųjį klavišą ar naudotumėte tinkintus veiksmus."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Spartieji klavišai"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"„<xliff:g id="NAME">%1$s</xliff:g>“ spartieji klavišai"</string>
-</resources>
diff --git a/go/res/values-lv/strings.xml b/go/res/values-lv/strings.xml
deleted file mode 100644
index 04315eb..0000000
--- a/go/res/values-lv/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Lai izvēlētos saīsni, pieskarieties un turiet to."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Lai atlasītu saīsni, veiciet dubultskārienu uz tās un turiet to vai arī veiciet pielāgotas darbības."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Saīsnes"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Lietotnes <xliff:g id="NAME">%1$s</xliff:g> saīsnes"</string>
-</resources>
diff --git a/go/res/values-mk/strings.xml b/go/res/values-mk/strings.xml
deleted file mode 100644
index 52d66b5..0000000
--- a/go/res/values-mk/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-ml/strings.xml b/go/res/values-ml/strings.xml
deleted file mode 100644
index b3c12e1..0000000
--- a/go/res/values-ml/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-mn/strings.xml b/go/res/values-mn/strings.xml
deleted file mode 100644
index c89dfd1..0000000
--- a/go/res/values-mn/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-mr/strings.xml b/go/res/values-mr/strings.xml
deleted file mode 100644
index 2c767b4..0000000
--- a/go/res/values-mr/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-ms/strings.xml b/go/res/values-ms/strings.xml
deleted file mode 100644
index 42add9a..0000000
--- a/go/res/values-ms/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Sentuh &amp; tahan untuk mengambil pintasan."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ketik dua kali &amp; tahan untuk mengambil pintasan atau menggunakan tindakan tersuai."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Pintasan"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Pintasan <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-my/strings.xml b/go/res/values-my/strings.xml
deleted file mode 100644
index 5784df6..0000000
--- a/go/res/values-my/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-nb/strings.xml b/go/res/values-nb/strings.xml
deleted file mode 100644
index 2a5ffb6..0000000
--- a/go/res/values-nb/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Trykk og hold for å velge en snarvei."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dobbelttrykk og hold for å velge en snarvei eller bruke tilpassede handlinger."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Snarveier"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-snarveier"</string>
-</resources>
diff --git a/go/res/values-ne/strings.xml b/go/res/values-ne/strings.xml
deleted file mode 100644
index 0be0375..0000000
--- a/go/res/values-ne/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-nl/strings.xml b/go/res/values-nl/strings.xml
deleted file mode 100644
index 5bcd016..0000000
--- a/go/res/values-nl/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Tik en houd vast om snelkoppeling toe te voegen."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dubbeltik en houd vast om een snelkoppeling toe te voegen of aangepaste acties te gebruiken."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Snelkoppelingen"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-snelkoppelingen"</string>
-</resources>
diff --git a/go/res/values-or/strings.xml b/go/res/values-or/strings.xml
deleted file mode 100644
index 3ec8a72..0000000
--- a/go/res/values-or/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-pa/strings.xml b/go/res/values-pa/strings.xml
deleted file mode 100644
index c7e4abf..0000000
--- a/go/res/values-pa/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-pl/strings.xml b/go/res/values-pl/strings.xml
deleted file mode 100644
index 0861daa..0000000
--- a/go/res/values-pl/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Naciśnij i przytrzymaj, by wybrać skrót."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Kliknij dwukrotnie i przytrzymaj, by wybrać skrót lub użyć działań niestandardowych."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Skróty"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> – skróty"</string>
-</resources>
diff --git a/go/res/values-pt-rPT/strings.xml b/go/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 7a75a05..0000000
--- a/go/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Toque sem soltar para escolher um atalho."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toque duas vezes sem soltar para escolher um atalho ou utilize ações personalizadas."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Atalhos"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Atalhos da aplicação <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-pt/strings.xml b/go/res/values-pt/strings.xml
deleted file mode 100644
index 53bbfc4..0000000
--- a/go/res/values-pt/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Toque e segure para selecionar um atalho."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toque duas vezes na tela e segure para selecionar um atalho ou usar ações personalizadas."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Atalhos"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Atalhos do app <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-ro/strings.xml b/go/res/values-ro/strings.xml
deleted file mode 100644
index 75d1796..0000000
--- a/go/res/values-ro/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Atingeți și țineți apăsat pentru a selecta o comandă rapidă."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Atingeți de două ori și țineți apăsat pentru comandă rapidă sau folosiți acțiuni personalizate."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Comenzi rapide"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Comenzi rapide pentru <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-ru/strings.xml b/go/res/values-ru/strings.xml
deleted file mode 100644
index 9c5c8cd..0000000
--- a/go/res/values-ru/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-si/strings.xml b/go/res/values-si/strings.xml
deleted file mode 100644
index 4b25c90..0000000
--- a/go/res/values-si/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-sk/strings.xml b/go/res/values-sk/strings.xml
deleted file mode 100644
index fc02933..0000000
--- a/go/res/values-sk/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Skratku pridáte pridržaním."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Skratku pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Skratky"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Skratky aplikácie <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-sl/strings.xml b/go/res/values-sl/strings.xml
deleted file mode 100644
index 6ecedfb..0000000
--- a/go/res/values-sl/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Pridržite bližnjico, da jo izberete."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvakrat se dotaknite bližnjice in jo pridržite, da jo izberete, ali pa uporabite dejanja po meri."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Bližnjice"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Bližnjice za <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-sq/strings.xml b/go/res/values-sq/strings.xml
deleted file mode 100644
index bb74db6..0000000
--- a/go/res/values-sq/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Prek dhe mbaj prekur për të zgjedhur një shkurtore."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Prek dy herë dhe mbaj prekur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Shkurtoret"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shkurtore"</string>
-</resources>
diff --git a/go/res/values-sr/strings.xml b/go/res/values-sr/strings.xml
deleted file mode 100644
index 0b9aea2..0000000
--- a/go/res/values-sr/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-sv/strings.xml b/go/res/values-sv/strings.xml
deleted file mode 100644
index c3f434c..0000000
--- a/go/res/values-sv/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Tryck länge om du vill ta upp en genväg."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tryck snabbt två gånger och håll kvar om du vill ta upp en genväg eller använda anpassade åtgärder."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Genvägar"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Genvägar för <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-sw/strings.xml b/go/res/values-sw/strings.xml
deleted file mode 100644
index 13c12e4..0000000
--- a/go/res/values-sw/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Gusa na ushikilie ili uchague njia ya mkato."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Gusa mara mbili na ushikilie ile uchague njia ya mkato au utumie vitendo maalum."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Njia za mkato"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Njia za mkato za <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-ta/strings.xml b/go/res/values-ta/strings.xml
deleted file mode 100644
index 50059b6..0000000
--- a/go/res/values-ta/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-te/strings.xml b/go/res/values-te/strings.xml
deleted file mode 100644
index 0bdf743..0000000
--- a/go/res/values-te/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"సత్వరమార్గాన్ని ఎంచుకోవడానికి తాకి &amp; నొక్కి ఉంచండి."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"సత్వరమార్గాన్ని ఎంచుకోవడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కి &amp;ఉంచండి."</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/go/res/values-th/strings.xml b/go/res/values-th/strings.xml
deleted file mode 100644
index e73d89f..0000000
--- a/go/res/values-th/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-tl/strings.xml b/go/res/values-tl/strings.xml
deleted file mode 100644
index 8f44ec5..0000000
--- a/go/res/values-tl/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Pindutin nang matagal upang kumuha ng shortcut."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"I-double tap nang matagal upang kumuha ng shortcut o gumamit ng mga custom na pagkilos."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Mga Shortcut"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Mga shortcut sa <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-tr/strings.xml b/go/res/values-tr/strings.xml
deleted file mode 100644
index f0f3cce..0000000
--- a/go/res/values-tr/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Kısayol seçmek için dokunun ve basılı tutun."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Bir kısayolu seçmek veya özel işlemleri kullanmak için iki kez dokunun ve basılı tutun."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Kısayollar"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> kısayolları"</string>
-</resources>
diff --git a/go/res/values-uk/strings.xml b/go/res/values-uk/strings.xml
deleted file mode 100644
index 8d1f583..0000000
--- a/go/res/values-uk/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-ur/strings.xml b/go/res/values-ur/strings.xml
deleted file mode 100644
index 46bd823..0000000
--- a/go/res/values-ur/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-uz/strings.xml b/go/res/values-uz/strings.xml
deleted file mode 100644
index 318bc15..0000000
--- a/go/res/values-uz/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Yorliqni tanlab olish uchun bosib turing."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Yorliqlar"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi yorliqlari"</string>
-</resources>
diff --git a/go/res/values-vi/strings.xml b/go/res/values-vi/strings.xml
deleted file mode 100644
index 1197619..0000000
--- a/go/res/values-vi/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Chạm và giữ để chọn lối tắt."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Nhấn đúp và giữ để chọn lối tắt hoặc sử dụng hành động tùy chỉnh."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Lối tắt"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Lối tắt <xliff:g id="NAME">%1$s</xliff:g>"</string>
-</resources>
diff --git a/go/res/values-zh-rCN/strings.xml b/go/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 57351d3..0000000
--- a/go/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-zh-rHK/strings.xml b/go/res/values-zh-rHK/strings.xml
deleted file mode 100644
index dea7749..0000000
--- a/go/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-zh-rTW/strings.xml b/go/res/values-zh-rTW/strings.xml
deleted file mode 100644
index 07ae2ed..0000000
--- a/go/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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="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/go/res/values-zu/strings.xml b/go/res/values-zu/strings.xml
deleted file mode 100644
index e5051df..0000000
--- a/go/res/values-zu/strings.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<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">"Thinta futhi ubambe ukuze ukhethe isinqamuleli."</string>
-    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Thepha kabulu futhi ubambe ukuze ukhethe isinqamuleli noma usebenzise izenzo zangokwezifiso."</string>
-    <string name="widget_button_text" msgid="4221900832360456858">"Izinqamuleli"</string>
-    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> izinqamuleli"</string>
-</resources>
diff --git a/go/res/values/strings.xml b/go/res/values/strings.xml
deleted file mode 100644
index 8ef2e62..0000000
--- a/go/res/values/strings.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2017 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-
-    <!-- Message to tell the user to press and hold on a shortcut to add it [CHAR_LIMIT=50] -->
-    <string name="long_press_widget_to_add">Touch &amp; hold to pick up a shortcut.</string>
-    <!-- Accessibility spoken hint message in widget picker, which allows user to add a shortcut. Custom action is the label for additional accessibility actions available in this mode [CHAR_LIMIT=100] -->
-    <string name="long_accessible_way_to_add">Double-tap &amp; hold to pick up a shortcut or use custom actions.</string>
-    <!-- Text for shortcut add button -->
-    <string name="widget_button_text">Shortcuts</string>
-
-    <!-- Strings for widgets & more in the popup container/bottom sheet -->
-    <!-- Title for a bottom sheet that shows shortcuts for a particular app -->
-    <string name="widgets_bottom_sheet_title"><xliff:g id="name" example="Messenger">%1$s</xliff:g> shortcuts</string>
-
-</resources>
diff --git a/go/res/xml/device_profiles.xml b/go/res/xml/device_profiles.xml
index 16d7e13..92a2b6a 100644
--- a/go/res/xml/device_profiles.xml
+++ b/go/res/xml/device_profiles.xml
@@ -17,17 +17,23 @@
 
 <profiles xmlns:launcher="http://schemas.android.com/apk/res-auto" >
 
-    <profile
-        launcher:name="Go Device"
-        launcher:minWidthDps="296"
-        launcher:minHeightDps="491.33"
+    <grid-option
+        launcher:name="4_by_4"
         launcher:numRows="4"
         launcher:numColumns="4"
         launcher:numFolderRows="4"
         launcher:numFolderColumns="4"
-        launcher:iconSize="60"
-        launcher:iconTextSize="14.0"
-        launcher:defaultLayoutId="@xml/default_workspace_4x4"
-        />
+        launcher:numHotseatIcons="4"
+        launcher:defaultLayoutId="@xml/default_workspace_4x4" >
+
+        <display-option
+            launcher:name="Go Device"
+            launcher:minWidthDps="296"
+            launcher:minHeightDps="491.33"
+            launcher:iconSize="60"
+            launcher:iconTextSize="14.0"
+            launcher:canBeDefault="true" />
+
+    </grid-option>
 
 </profiles>
\ No newline at end of file
diff --git a/go/src/com/android/launcher3/model/LoaderResults.java b/go/src/com/android/launcher3/model/LoaderResults.java
new file mode 100644
index 0000000..b82f362
--- /dev/null
+++ b/go/src/com/android/launcher3/model/LoaderResults.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.model;
+
+import com.android.launcher3.AllAppsList;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherModel.Callbacks;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
+ */
+public class LoaderResults extends BaseLoaderResults {
+
+    public LoaderResults(LauncherAppState app, BgDataModel dataModel,
+            AllAppsList allAppsList, int pageToBindFirst, WeakReference<Callbacks> callbacks) {
+        super(app, dataModel, allAppsList, pageToBindFirst, callbacks);
+    }
+
+    @Override
+    public void bindDeepShortcuts() {
+    }
+
+    @Override
+    public void bindWidgets() {
+    }
+}
diff --git a/iconloaderlib/Android.bp b/iconloaderlib/Android.bp
index 8a71f94..f12d16e 100644
--- a/iconloaderlib/Android.bp
+++ b/iconloaderlib/Android.bp
@@ -13,7 +13,7 @@
 // limitations under the License.
 
 android_library {
-    name: "iconloader",
+    name: "iconloader_base",
     sdk_version: "28",
     min_sdk_version: "21",
     static_libs: [
@@ -26,3 +26,19 @@
         "src/**/*.java",
     ],
 }
+
+android_library {
+    name: "iconloader",
+    sdk_version: "system_current",
+    min_sdk_version: "21",
+    static_libs: [
+        "androidx.core_core",
+    ],
+    resource_dirs: [
+        "res",
+    ],
+    srcs: [
+        "src/**/*.java",
+        "src_full_lib/**/*.java",
+    ],
+}
diff --git a/iconloaderlib/build.gradle b/iconloaderlib/build.gradle
index d080293..f6a820a 100644
--- a/iconloaderlib/build.gradle
+++ b/iconloaderlib/build.gradle
@@ -24,7 +24,7 @@
 
     sourceSets {
         main {
-            java.srcDirs = ['src']
+            java.srcDirs = ['src', 'src_full_lib']
             manifest.srcFile 'AndroidManifest.xml'
             res.srcDirs = ['res']
         }
@@ -37,6 +37,11 @@
     tasks.withType(JavaCompile) {
         options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
     }
+
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
 }
 
 
diff --git a/iconloaderlib/res/values/config.xml b/iconloaderlib/res/values/config.xml
new file mode 100644
index 0000000..68c2d2e
--- /dev/null
+++ b/iconloaderlib/res/values/config.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 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.
+*/
+-->
+<resources>
+
+    <!-- Various configurations to control the simple cache implementation -->
+
+    <dimen name="default_icon_bitmap_size">56dp</dimen>
+    <bool name="simple_cache_enable_im_memory">false</bool>
+    <string name="cache_db_name" translatable="false">app_icons.db</string>
+
+</resources>
\ No newline at end of file
diff --git a/iconloaderlib/src/com/android.launcher3/icons/BaseIconFactory.java b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
similarity index 76%
rename from iconloaderlib/src/com/android.launcher3/icons/BaseIconFactory.java
rename to iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
index 681c03c..af1b353 100644
--- a/iconloaderlib/src/com/android.launcher3/icons/BaseIconFactory.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/BaseIconFactory.java
@@ -1,5 +1,10 @@
 package com.android.launcher3.icons;
 
+import static android.graphics.Paint.DITHER_FLAG;
+import static android.graphics.Paint.FILTER_BITMAP_FLAG;
+
+import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR;
+
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -18,30 +23,26 @@
 import android.os.Process;
 import android.os.UserHandle;
 
-import com.android.launcher3.icons.R;
-
-import static android.graphics.Paint.DITHER_FLAG;
-import static android.graphics.Paint.FILTER_BITMAP_FLAG;
-import static com.android.launcher3.icons.ShadowGenerator.BLUR_FACTOR;
-
 /**
  * This class will be moved to androidx library. There shouldn't be any dependency outside
  * this package.
  */
-public class BaseIconFactory {
+public class BaseIconFactory implements AutoCloseable {
 
+    private static final String TAG = "BaseIconFactory";
     private static final int DEFAULT_WRAPPER_BACKGROUND = Color.WHITE;
-    public static final boolean ATLEAST_OREO = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
+    static final boolean ATLEAST_OREO = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
+    static final boolean ATLEAST_P = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
 
     private final Rect mOldBounds = new Rect();
-    private final Context mContext;
+    protected final Context mContext;
     private final Canvas mCanvas;
     private final PackageManager mPm;
     private final ColorExtractor mColorExtractor;
     private boolean mDisableColorExtractor;
 
-    private int mFillResIconDpi;
-    private int mIconBitmapSize;
+    protected final int mFillResIconDpi;
+    protected final int mIconBitmapSize;
 
     private IconNormalizer mNormalizer;
     private ShadowGenerator mShadowGenerator;
@@ -81,6 +82,7 @@
         return mNormalizer;
     }
 
+    @SuppressWarnings("deprecation")
     public BitmapInfo createIconBitmap(Intent.ShortcutIconResource iconRes) {
         try {
             Resources resources = mPm.getResourcesForApplication(iconRes.packageName);
@@ -99,11 +101,11 @@
     }
 
     public BitmapInfo createIconBitmap(Bitmap icon) {
-        if (mIconBitmapSize == icon.getWidth() && mIconBitmapSize == icon.getHeight()) {
-            return BitmapInfo.fromBitmap(icon);
+        if (mIconBitmapSize != icon.getWidth() || mIconBitmapSize != icon.getHeight()) {
+            icon = createIconBitmap(new BitmapDrawable(mContext.getResources(), icon), 1f);
         }
-        return BitmapInfo.fromBitmap(
-                createIconBitmap(new BitmapDrawable(mContext.getResources(), icon), 1f));
+
+        return BitmapInfo.fromBitmap(icon, mDisableColorExtractor ? null : mColorExtractor);
     }
 
     public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
@@ -116,6 +118,29 @@
         return createBadgedIconBitmap(icon, user, shrinkNonAdaptiveIcons, isInstantApp, null);
     }
 
+    public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
+            int iconAppTargetSdk) {
+        return createBadgedIconBitmap(icon, user, iconAppTargetSdk, false);
+    }
+
+    public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
+            int iconAppTargetSdk, boolean isInstantApp) {
+        return createBadgedIconBitmap(icon, user, iconAppTargetSdk, isInstantApp, null);
+    }
+
+    public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
+            int iconAppTargetSdk, boolean isInstantApp, float[] scale) {
+        boolean shrinkNonAdaptiveIcons = ATLEAST_P ||
+                (ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O);
+        return createBadgedIconBitmap(icon, user, shrinkNonAdaptiveIcons, isInstantApp, scale);
+    }
+
+    public Bitmap createScaledBitmapWithoutShadow(Drawable icon, int iconAppTargetSdk) {
+        boolean shrinkNonAdaptiveIcons = ATLEAST_P ||
+                (ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O);
+        return  createScaledBitmapWithoutShadow(icon, shrinkNonAdaptiveIcons);
+    }
+
     /**
      * Creates bitmap using the source drawable and various parameters.
      * The bitmap is visually normalized with other icons and has enough spacing to add shadow.
@@ -184,8 +209,7 @@
             RectF outIconBounds, float[] outScale) {
         float scale = 1f;
 
-        if (shrinkNonAdaptiveIcons) {
-            boolean[] outShape = new boolean[1];
+        if (shrinkNonAdaptiveIcons && ATLEAST_OREO) {
             if (mWrapperIcon == null) {
                 mWrapperIcon = mContext.getDrawable(R.drawable.adaptive_icon_drawable_wrapper)
                         .mutate();
@@ -193,7 +217,7 @@
             AdaptiveIconDrawable dr = (AdaptiveIconDrawable) mWrapperIcon;
             dr.setBounds(0, 0, 1, 1);
             scale = getNormalizer().getScale(icon, outIconBounds);
-            if (ATLEAST_OREO && !(icon instanceof AdaptiveIconDrawable)) {
+            if (!(icon instanceof AdaptiveIconDrawable)) {
                 FixedScaleDrawable fsd = ((FixedScaleDrawable) dr.getForeground());
                 fsd.setDrawable(icon);
                 fsd.setScale(scale);
@@ -229,19 +253,24 @@
         badge.draw(target);
     }
 
+    private Bitmap createIconBitmap(Drawable icon, float scale) {
+        return createIconBitmap(icon, scale, mIconBitmapSize);
+    }
+
     /**
+     * @param icon drawable that should be flattened to a bitmap
      * @param scale the scale to apply before drawing {@param icon} on the canvas
      */
-    private Bitmap createIconBitmap(Drawable icon, float scale) {
-        Bitmap bitmap = Bitmap.createBitmap(mIconBitmapSize, mIconBitmapSize,
-                Bitmap.Config.ARGB_8888);
+    public Bitmap createIconBitmap(Drawable icon, float scale, int size) {
+        Bitmap bitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
+
         mCanvas.setBitmap(bitmap);
         mOldBounds.set(icon.getBounds());
 
         if (ATLEAST_OREO && icon instanceof AdaptiveIconDrawable) {
-            int offset = Math.max((int) Math.ceil(BLUR_FACTOR * mIconBitmapSize),
-                    Math.round(mIconBitmapSize * (1 - scale) / 2 ));
-            icon.setBounds(offset, offset, mIconBitmapSize - offset, mIconBitmapSize - offset);
+            int offset = Math.max((int) Math.ceil(BLUR_FACTOR * size),
+                    Math.round(size * (1 - scale) / 2 ));
+            icon.setBounds(offset, offset, size - offset, size - offset);
             icon.draw(mCanvas);
         } else {
             if (icon instanceof BitmapDrawable) {
@@ -251,8 +280,8 @@
                     bitmapDrawable.setTargetDensity(mContext.getResources().getDisplayMetrics());
                 }
             }
-            int width = mIconBitmapSize;
-            int height = mIconBitmapSize;
+            int width = size;
+            int height = size;
 
             int intrinsicWidth = icon.getIntrinsicWidth();
             int intrinsicHeight = icon.getIntrinsicHeight();
@@ -265,11 +294,11 @@
                     width = (int) (height * ratio);
                 }
             }
-            final int left = (mIconBitmapSize - width) / 2;
-            final int top = (mIconBitmapSize - height) / 2;
+            final int left = (size - width) / 2;
+            final int top = (size - height) / 2;
             icon.setBounds(left, top, left + width, top + height);
             mCanvas.save();
-            mCanvas.scale(scale, scale, mIconBitmapSize / 2, mIconBitmapSize / 2);
+            mCanvas.scale(scale, scale, size / 2, size / 2);
             icon.draw(mCanvas);
             mCanvas.restore();
 
@@ -279,6 +308,23 @@
         return bitmap;
     }
 
+    @Override
+    public void close() {
+        clear();
+    }
+
+    public BitmapInfo makeDefaultIcon(UserHandle user) {
+        return createBadgedIconBitmap(getFullResDefaultActivityIcon(mFillResIconDpi),
+                user, Build.VERSION.SDK_INT);
+    }
+
+    public static Drawable getFullResDefaultActivityIcon(int iconDpi) {
+        return Resources.getSystem().getDrawableForDensity(
+                Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
+                        ? android.R.drawable.sym_def_app_icon : android.R.mipmap.sym_def_app_icon,
+                iconDpi);
+    }
+
     /**
      * An extension of {@link BitmapDrawable} which returns the bitmap pixel size as intrinsic size.
      * This allows the badging to be done based on the action bitmap size rather than
diff --git a/iconloaderlib/src/com/android.launcher3/icons/BitmapInfo.java b/iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java
similarity index 100%
rename from iconloaderlib/src/com/android.launcher3/icons/BitmapInfo.java
rename to iconloaderlib/src/com/android/launcher3/icons/BitmapInfo.java
diff --git a/src/com/android/launcher3/graphics/BitmapRenderer.java b/iconloaderlib/src/com/android/launcher3/icons/BitmapRenderer.java
similarity index 91%
rename from src/com/android/launcher3/graphics/BitmapRenderer.java
rename to iconloaderlib/src/com/android/launcher3/icons/BitmapRenderer.java
index 2a7f20e..a66b929 100644
--- a/src/com/android/launcher3/graphics/BitmapRenderer.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/BitmapRenderer.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.graphics;
+package com.android.launcher3.icons;
 
 import android.annotation.TargetApi;
 import android.graphics.Bitmap;
@@ -21,14 +21,12 @@
 import android.graphics.Picture;
 import android.os.Build;
 
-import com.android.launcher3.Utilities;
-
 /**
  * Interface representing a bitmap draw operation.
  */
 public interface BitmapRenderer {
 
-    boolean USE_HARDWARE_BITMAP = Utilities.ATLEAST_P;
+    boolean USE_HARDWARE_BITMAP = Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
 
     static Bitmap createSoftwareBitmap(int width, int height, BitmapRenderer renderer) {
         Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
diff --git a/iconloaderlib/src/com/android.launcher3/icons/ColorExtractor.java b/iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java
similarity index 100%
rename from iconloaderlib/src/com/android.launcher3/icons/ColorExtractor.java
rename to iconloaderlib/src/com/android/launcher3/icons/ColorExtractor.java
diff --git a/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java b/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java
new file mode 100644
index 0000000..6bc859a
--- /dev/null
+++ b/iconloaderlib/src/com/android/launcher3/icons/DotRenderer.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.icons;
+
+import static android.graphics.Paint.ANTI_ALIAS_FLAG;
+import static android.graphics.Paint.FILTER_BITMAP_FLAG;
+
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.util.Log;
+import android.view.ViewDebug;
+
+/**
+ * Used to draw a notification dot on top of an icon.
+ */
+public class DotRenderer {
+
+    private static final String TAG = "DotRenderer";
+
+    // The dot size is defined as a percentage of the app icon size.
+    private static final float SIZE_PERCENTAGE = 0.38f;
+
+    // Extra scale down of the dot
+    private static final float DOT_SCALE = 0.6f;
+
+    // Offset the dot slightly away from the icon if there's space.
+    private static final float OFFSET_PERCENTAGE = 0.02f;
+
+    private final float mDotCenterOffset;
+    private final int mOffset;
+    private final float mCircleRadius;
+    private final Paint mCirclePaint = new Paint(ANTI_ALIAS_FLAG | FILTER_BITMAP_FLAG);
+
+    private final Bitmap mBackgroundWithShadow;
+    private final float mBitmapOffset;
+
+    public DotRenderer(int iconSizePx) {
+        mDotCenterOffset = SIZE_PERCENTAGE * iconSizePx;
+        mOffset = (int) (OFFSET_PERCENTAGE * iconSizePx);
+
+        int size = (int) (DOT_SCALE * mDotCenterOffset);
+        ShadowGenerator.Builder builder = new ShadowGenerator.Builder(Color.TRANSPARENT);
+        builder.ambientShadowAlpha = 88;
+        mBackgroundWithShadow = builder.setupBlurForSize(size).createPill(size, size);
+        mCircleRadius = builder.radius;
+
+        mBitmapOffset = -mBackgroundWithShadow.getHeight() * 0.5f; // Same as width.
+    }
+
+    /**
+     * Draw a circle on top of the canvas according to the given params.
+     */
+    public void draw(Canvas canvas, DrawParams params) {
+        if (params == null) {
+            Log.e(TAG, "Invalid null argument(s) passed in call to draw.");
+            return;
+        }
+        canvas.save();
+        // We draw the dot relative to its center.
+        float dotCenterX = params.leftAlign
+                ? params.iconBounds.left + mDotCenterOffset / 2
+                : params.iconBounds.right - mDotCenterOffset / 2;
+        float dotCenterY = params.iconBounds.top + mDotCenterOffset / 2;
+
+        int offsetX = Math.min(mOffset, params.spaceForOffset.x);
+        int offsetY = Math.min(mOffset, params.spaceForOffset.y);
+        canvas.translate(dotCenterX + offsetX, dotCenterY - offsetY);
+        canvas.scale(params.scale, params.scale);
+
+        mCirclePaint.setColor(Color.BLACK);
+        canvas.drawBitmap(mBackgroundWithShadow, mBitmapOffset, mBitmapOffset, mCirclePaint);
+        mCirclePaint.setColor(params.color);
+        canvas.drawCircle(0, 0, mCircleRadius, mCirclePaint);
+        canvas.restore();
+    }
+
+    public static class DrawParams {
+        /** The color (possibly based on the icon) to use for the dot. */
+        @ViewDebug.ExportedProperty(category = "notification dot", formatToHexString = true)
+        public int color;
+        /** The bounds of the icon that the dot is drawn on top of. */
+        @ViewDebug.ExportedProperty(category = "notification dot")
+        public Rect iconBounds = new Rect();
+        /** The progress of the animation, from 0 to 1. */
+        @ViewDebug.ExportedProperty(category = "notification dot")
+        public float scale;
+        /** Overrides internally calculated offset if specified value is smaller. */
+        @ViewDebug.ExportedProperty(category = "notification dot")
+        public Point spaceForOffset = new Point();
+        /** Whether the dot should align to the top left of the icon rather than the top right. */
+        @ViewDebug.ExportedProperty(category = "notification dot")
+        public boolean leftAlign;
+    }
+}
diff --git a/iconloaderlib/src/com/android.launcher3/icons/FixedScaleDrawable.java b/iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java
similarity index 100%
rename from iconloaderlib/src/com/android.launcher3/icons/FixedScaleDrawable.java
rename to iconloaderlib/src/com/android/launcher3/icons/FixedScaleDrawable.java
diff --git a/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java
new file mode 100644
index 0000000..11d5eef
--- /dev/null
+++ b/iconloaderlib/src/com/android/launcher3/icons/GraphicsUtils.java
@@ -0,0 +1,63 @@
+/*
+ * 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.icons;
+
+import android.graphics.Bitmap;
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import androidx.annotation.ColorInt;
+
+public class GraphicsUtils {
+
+    private static final String TAG = "GraphicsUtils";
+
+    /**
+     * Set the alpha component of {@code color} to be {@code alpha}. Unlike the support lib version,
+     * it bounds the alpha in valid range instead of throwing an exception to allow for safer
+     * interpolation of color animations
+     */
+    @ColorInt
+    public static int setColorAlphaBound(int color, int alpha) {
+        if (alpha < 0) {
+            alpha = 0;
+        } else if (alpha > 255) {
+            alpha = 255;
+        }
+        return (color & 0x00ffffff) | (alpha << 24);
+    }
+
+    /**
+     * Compresses the bitmap to a byte array for serialization.
+     */
+    public static byte[] flattenBitmap(Bitmap bitmap) {
+        // Try go guesstimate how much space the icon will take when serialized
+        // to avoid unnecessary allocations/copies during the write (4 bytes per pixel).
+        int size = bitmap.getWidth() * bitmap.getHeight() * 4;
+        ByteArrayOutputStream out = new ByteArrayOutputStream(size);
+        try {
+            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
+            out.flush();
+            out.close();
+            return out.toByteArray();
+        } catch (IOException e) {
+            Log.w(TAG, "Could not write bitmap");
+            return null;
+        }
+    }
+}
diff --git a/iconloaderlib/src/com/android.launcher3/icons/IconNormalizer.java b/iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java
similarity index 100%
rename from iconloaderlib/src/com/android.launcher3/icons/IconNormalizer.java
rename to iconloaderlib/src/com/android/launcher3/icons/IconNormalizer.java
diff --git a/iconloaderlib/src/com/android.launcher3/icons/ShadowGenerator.java b/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java
similarity index 96%
rename from iconloaderlib/src/com/android.launcher3/icons/ShadowGenerator.java
rename to iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java
index 6491b7e..455c58c 100644
--- a/iconloaderlib/src/com/android.launcher3/icons/ShadowGenerator.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/ShadowGenerator.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.icons;
 
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
 import android.graphics.BlurMaskFilter;
@@ -27,8 +29,6 @@
 import android.graphics.PorterDuffXfermode;
 import android.graphics.RectF;
 
-import androidx.core.graphics.ColorUtils;
-
 /**
  * Utility class to add shadows to bitmaps.
  */
@@ -142,12 +142,12 @@
 
             // Key shadow
             p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
-                    ColorUtils.setAlphaComponent(Color.BLACK, keyShadowAlpha));
+                    setColorAlphaBound(Color.BLACK, keyShadowAlpha));
             c.drawRoundRect(bounds, radius, radius, p);
 
             // Ambient shadow
             p.setShadowLayer(shadowBlur, 0, 0,
-                    ColorUtils.setAlphaComponent(Color.BLACK, ambientShadowAlpha));
+                    setColorAlphaBound(Color.BLACK, ambientShadowAlpha));
             c.drawRoundRect(bounds, radius, radius, p);
 
             if (Color.alpha(color) < 255) {
diff --git a/src/com/android/launcher3/icons/BaseIconCache.java b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
similarity index 75%
rename from src/com/android/launcher3/icons/BaseIconCache.java
rename to iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
index 2afe713..ce66448 100644
--- a/src/com/android/launcher3/icons/BaseIconCache.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/BaseIconCache.java
@@ -13,16 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.icons;
+package com.android.launcher3.icons.cache;
 
+import static com.android.launcher3.icons.BaseIconFactory.getFullResDefaultActivityIcon;
 import static com.android.launcher3.icons.BitmapInfo.LOW_RES_ICON;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
 import android.content.ComponentName;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.LauncherActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
@@ -33,40 +34,36 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.drawable.Drawable;
-import android.os.Build.VERSION;
+import android.os.Build;
 import android.os.Handler;
+import android.os.Looper;
 import android.os.Process;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.Log;
 
-import com.android.launcher3.IconProvider;
-import com.android.launcher3.ItemInfoWithIcon;
-import com.android.launcher3.LauncherFiles;
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.MainThreadExecutor;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.graphics.BitmapRenderer;
-import com.android.launcher3.model.PackageItemInfo;
+import com.android.launcher3.icons.BaseIconFactory;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.BitmapRenderer;
+import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.InstantAppResolver;
-import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.SQLiteCacheHelper;
 
+import java.util.AbstractMap;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
 
 import androidx.annotation.NonNull;
-import androidx.core.graphics.ColorUtils;
 
-public class BaseIconCache {
+public abstract class BaseIconCache {
 
     private static final String TAG = "BaseIconCache";
     private static final boolean DEBUG = false;
-    private static final boolean DEBUG_IGNORE_CACHE = false;
 
     private static final int INITIAL_ICON_CACHE_CAPACITY = 50;
 
@@ -80,44 +77,73 @@
 
     private final HashMap<UserHandle, BitmapInfo> mDefaultIcons = new HashMap<>();
 
-    final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
-    final Context mContext;
-    final PackageManager mPackageManager;
-    final IconProvider mIconProvider;
-    final UserManagerCompat mUserManager;
-    final LauncherAppsCompat mLauncherApps;
+    protected final Context mContext;
+    protected final PackageManager mPackageManager;
 
-    private final HashMap<ComponentKey, CacheEntry> mCache =
-            new HashMap<>(INITIAL_ICON_CACHE_CAPACITY);
-    private final InstantAppResolver mInstantAppResolver;
-    final Handler mWorkerHandler;
+    private final Map<ComponentKey, CacheEntry> mCache;
+    protected final Handler mWorkerHandler;
 
-    int mIconDpi;
-    IconDB mIconDb;
+    protected int mIconDpi;
+    protected IconDB mIconDb;
+    protected String mSystemState = "";
 
+    private final String mDbFileName;
     private final BitmapFactory.Options mDecodeOptions;
+    private final Looper mBgLooper;
 
-    public BaseIconCache(Context context, int iconDpi, int iconPixelSize) {
+    public BaseIconCache(Context context, String dbFileName, Looper bgLooper,
+            int iconDpi, int iconPixelSize, boolean inMemoryCache) {
         mContext = context;
+        mDbFileName = dbFileName;
         mPackageManager = context.getPackageManager();
-        mUserManager = UserManagerCompat.getInstance(mContext);
-        mLauncherApps = LauncherAppsCompat.getInstance(mContext);
-        mInstantAppResolver = InstantAppResolver.newInstance(mContext);
+        mBgLooper = bgLooper;
+        mWorkerHandler = new Handler(mBgLooper);
 
-        mIconProvider = IconProvider.newInstance(context);
-        mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
+        if (inMemoryCache) {
+            mCache = new HashMap<>(INITIAL_ICON_CACHE_CAPACITY);
+        } else {
+            // Use a dummy cache
+            mCache = new AbstractMap<ComponentKey, CacheEntry>() {
+                @Override
+                public Set<Entry<ComponentKey, CacheEntry>> entrySet() {
+                    return Collections.emptySet();
+                }
 
-        if (BitmapRenderer.USE_HARDWARE_BITMAP) {
+                @Override
+                public CacheEntry put(ComponentKey key, CacheEntry value) {
+                    return value;
+                }
+            };
+        }
+
+        if (BitmapRenderer.USE_HARDWARE_BITMAP && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             mDecodeOptions = new BitmapFactory.Options();
             mDecodeOptions.inPreferredConfig = Bitmap.Config.HARDWARE;
         } else {
             mDecodeOptions = null;
         }
 
+        updateSystemState();
         mIconDpi = iconDpi;
-        mIconDb = new IconDB(context, iconPixelSize);
+        mIconDb = new IconDB(context, dbFileName, iconPixelSize);
     }
 
+    /**
+     * Returns the persistable serial number for {@param user}. Subclass should implement proper
+     * caching strategy to avoid making binder call every time.
+     */
+    protected abstract long getSerialNumberForUser(UserHandle user);
+
+    /**
+     * Return true if the given app is an instant app and should be badged appropriately.
+     */
+    protected abstract boolean isInstantApp(ApplicationInfo info);
+
+    /**
+     * Opens and returns an icon factory. The factory is recycled by the caller.
+     */
+    protected abstract BaseIconFactory getIconFactory();
+
     public void updateIconParams(int iconDpi, int iconPixelSize) {
         mWorkerHandler.post(() -> updateIconParamsBg(iconDpi, iconPixelSize));
     }
@@ -125,32 +151,26 @@
     private synchronized void updateIconParamsBg(int iconDpi, int iconPixelSize) {
         mIconDpi = iconDpi;
         mDefaultIcons.clear();
-
+        mIconDb.clear();
         mIconDb.close();
-        mIconDb = new IconDB(mContext, iconPixelSize);
+        mIconDb = new IconDB(mContext, mDbFileName, iconPixelSize);
         mCache.clear();
     }
 
-    private Drawable getFullResDefaultActivityIcon() {
-        return Resources.getSystem().getDrawableForDensity(Utilities.ATLEAST_OREO
-                ? android.R.drawable.sym_def_app_icon : android.R.mipmap.sym_def_app_icon,
-                mIconDpi);
-    }
-
     private Drawable getFullResIcon(Resources resources, int iconId) {
         if (resources != null && iconId != 0) {
             try {
                 return resources.getDrawableForDensity(iconId, mIconDpi);
             } catch (Resources.NotFoundException e) { }
         }
-        return getFullResDefaultActivityIcon();
+        return getFullResDefaultActivityIcon(mIconDpi);
     }
 
     public Drawable getFullResIcon(String packageName, int iconId) {
         try {
             return getFullResIcon(mPackageManager.getResourcesForApplication(packageName), iconId);
         } catch (PackageManager.NameNotFoundException e) { }
-        return getFullResDefaultActivityIcon();
+        return getFullResDefaultActivityIcon(mIconDpi);
     }
 
     public Drawable getFullResIcon(ActivityInfo info) {
@@ -158,21 +178,12 @@
             return getFullResIcon(mPackageManager.getResourcesForApplication(info.applicationInfo),
                     info.getIconResource());
         } catch (PackageManager.NameNotFoundException e) { }
-        return getFullResDefaultActivityIcon();
+        return getFullResDefaultActivityIcon(mIconDpi);
     }
 
-    public Drawable getFullResIcon(LauncherActivityInfo info) {
-        return getFullResIcon(info, true);
-    }
-
-    public Drawable getFullResIcon(LauncherActivityInfo info, boolean flattenDrawable) {
-        return mIconProvider.getIcon(info, mIconDpi, flattenDrawable);
-    }
-
-    protected BitmapInfo makeDefaultIcon(UserHandle user) {
-        try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
-            return li.createBadgedIconBitmap(
-                    getFullResDefaultActivityIcon(), user, VERSION.SDK_INT);
+    private BitmapInfo makeDefaultIcon(UserHandle user) {
+        try (BaseIconFactory li = getIconFactory()) {
+            return li.makeDefaultIcon(user);
         }
     }
 
@@ -204,25 +215,44 @@
      */
     public synchronized void removeIconsForPkg(String packageName, UserHandle user) {
         removeFromMemCacheLocked(packageName, user);
-        long userSerial = mUserManager.getSerialNumberForUser(user);
+        long userSerial = getSerialNumberForUser(user);
         mIconDb.delete(
                 IconDB.COLUMN_COMPONENT + " LIKE ? AND " + IconDB.COLUMN_USER + " = ?",
                 new String[]{packageName + "/%", Long.toString(userSerial)});
     }
 
     public IconCacheUpdateHandler getUpdateHandler() {
-        mIconProvider.updateSystemStateString(mContext);
+        updateSystemState();
         return new IconCacheUpdateHandler(this);
     }
 
     /**
+     * Refreshes the system state definition used to check the validity of the cache. It
+     * incorporates all the properties that can affect the cache like locale and system-version.
+     */
+    private void updateSystemState() {
+        final String locale;
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+            locale = mContext.getResources().getConfiguration().getLocales().toLanguageTags();
+        } else {
+            locale = Locale.getDefault().toString();
+        }
+
+        mSystemState = locale + "," + Build.VERSION.SDK_INT;
+    }
+
+    protected String getIconSystemState(String packageName) {
+        return mSystemState;
+    }
+
+    /**
      * Adds an entry into the DB and the in-memory cache.
      * @param replaceExisting if true, it will recreate the bitmap even if it already exists in
      *                        the memory. This is useful then the previous bitmap was created using
      *                        old data.
      * package private
      */
-    synchronized <T> void addIconToDBAndMemCache(T object, CachingLogic<T> cachingLogic,
+    protected synchronized <T> void addIconToDBAndMemCache(T object, CachingLogic<T> cachingLogic,
             PackageInfo info, long userSerial, boolean replaceExisting) {
         UserHandle user = cachingLogic.getUser(object);
         ComponentName componentName = cachingLogic.getComponent(object);
@@ -238,10 +268,10 @@
         }
         if (entry == null) {
             entry = new CacheEntry();
-            cachingLogic.loadIcon(mContext, this, object, entry);
+            cachingLogic.loadIcon(mContext, object, entry);
         }
-        entry.title = cachingLogic.getLabel(object, mPackageManager);
-        entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
+        entry.title = cachingLogic.getLabel(object);
+        entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
         mCache.put(key, entry);
 
         ContentValues values = newContentValues(entry, entry.title.toString(),
@@ -262,22 +292,6 @@
         mIconDb.insertOrReplace(values);
     }
 
-    /**
-     * Fill in {@param infoInOut} with the corresponding icon and label.
-     */
-    public synchronized void getTitleAndIconForApp(
-            PackageItemInfo infoInOut, boolean useLowResIcon) {
-        CacheEntry entry = getEntryForPackageLocked(
-                infoInOut.packageName, infoInOut.user, useLowResIcon);
-        applyCacheEntry(entry, infoInOut);
-    }
-
-    protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) {
-        info.title = Utilities.trim(entry.title);
-        info.contentDescription = entry.contentDescription;
-        info.applyFrom((entry.icon == null) ? getDefaultIcon(info.user) : entry);
-    }
-
     public synchronized BitmapInfo getDefaultIcon(UserHandle user) {
         if (!mDefaultIcons.containsKey(user)) {
             mDefaultIcons.put(user, makeDefaultIcon(user));
@@ -305,7 +319,7 @@
             @NonNull ComponentName componentName, @NonNull UserHandle user,
             @NonNull Provider<T> infoProvider, @NonNull CachingLogic<T> cachingLogic,
             boolean usePackageIcon, boolean useLowResIcon, boolean addToMemCache) {
-        Preconditions.assertWorkerThread();
+        assertWorkerThread();
         ComponentKey cacheKey = new ComponentKey(componentName, user);
         CacheEntry entry = mCache.get(cacheKey);
         if (entry == null || (entry.isLowRes() && !useLowResIcon)) {
@@ -318,12 +332,12 @@
             T object = null;
             boolean providerFetchedOnce = false;
 
-            if (!getEntryFromDB(cacheKey, entry, useLowResIcon) || DEBUG_IGNORE_CACHE) {
+            if (!getEntryFromDB(cacheKey, entry, useLowResIcon)) {
                 object = infoProvider.get();
                 providerFetchedOnce = true;
 
                 if (object != null) {
-                    cachingLogic.loadIcon(mContext, this, object, entry);
+                    cachingLogic.loadIcon(mContext, object, entry);
                 } else {
                     if (usePackageIcon) {
                         CacheEntry packageEntry = getEntryForPackageLocked(
@@ -350,8 +364,8 @@
                     providerFetchedOnce = true;
                 }
                 if (object != null) {
-                    entry.title = cachingLogic.getLabel(object, mPackageManager);
-                    entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
+                    entry.title = cachingLogic.getLabel(object);
+                    entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
                 }
             }
         }
@@ -359,7 +373,7 @@
     }
 
     public synchronized void clear() {
-        Preconditions.assertWorkerThread();
+        assertWorkerThread();
         mIconDb.clear();
     }
 
@@ -382,9 +396,9 @@
             entry.title = title;
         }
         if (icon != null) {
-            LauncherIcons li = LauncherIcons.obtain(mContext);
+            BaseIconFactory li = getIconFactory();
             li.createIconBitmap(icon).applyTo(entry);
-            li.recycle();
+            li.close();
         }
         if (!TextUtils.isEmpty(title) && entry.icon != null) {
             mCache.put(cacheKey, entry);
@@ -400,9 +414,9 @@
      * Gets an entry for the package, which can be used as a fallback entry for various components.
      * This method is not thread safe, it must be called from a synchronized method.
      */
-    private CacheEntry getEntryForPackageLocked(String packageName, UserHandle user,
+    protected CacheEntry getEntryForPackageLocked(String packageName, UserHandle user,
             boolean useLowResIcon) {
-        Preconditions.assertWorkerThread();
+        assertWorkerThread();
         ComponentKey cacheKey = getPackageKey(packageName, user);
         CacheEntry entry = mCache.get(cacheKey);
 
@@ -421,16 +435,16 @@
                         throw new NameNotFoundException("ApplicationInfo is null");
                     }
 
-                    LauncherIcons li = LauncherIcons.obtain(mContext);
+                    BaseIconFactory li = getIconFactory();
                     // Load the full res icon for the application, but if useLowResIcon is set, then
                     // only keep the low resolution icon instead of the larger full-sized icon
                     BitmapInfo iconInfo = li.createBadgedIconBitmap(
                             appInfo.loadIcon(mPackageManager), user, appInfo.targetSdkVersion,
-                            mInstantAppResolver.isInstantApp(appInfo));
-                    li.recycle();
+                            isInstantApp(appInfo));
+                    li.close();
 
                     entry.title = appInfo.loadLabel(mPackageManager);
-                    entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
+                    entry.contentDescription = mPackageManager.getUserBadgedLabel(entry.title, user);
                     entry.icon = useLowResIcon ? LOW_RES_ICON : iconInfo.icon;
                     entry.color = iconInfo.color;
 
@@ -438,8 +452,7 @@
                     // package updates.
                     ContentValues values = newContentValues(
                             iconInfo, entry.title.toString(), packageName);
-                    addIconToDB(values, cacheKey.componentName, info,
-                            mUserManager.getSerialNumberForUser(user));
+                    addIconToDB(values, cacheKey.componentName, info, getSerialNumberForUser(user));
 
                 } catch (NameNotFoundException e) {
                     if (DEBUG) Log.d(TAG, "Application not installed " + packageName);
@@ -463,16 +476,16 @@
                     IconDB.COLUMN_COMPONENT + " = ? AND " + IconDB.COLUMN_USER + " = ?",
                     new String[]{
                             cacheKey.componentName.flattenToString(),
-                            Long.toString(mUserManager.getSerialNumberForUser(cacheKey.user))});
+                            Long.toString(getSerialNumberForUser(cacheKey.user))});
             if (c.moveToNext()) {
                 // Set the alpha to be 255, so that we never have a wrong color
-                entry.color = ColorUtils.setAlphaComponent(c.getInt(0), 255);
+                entry.color = setColorAlphaBound(c.getInt(0), 255);
                 entry.title = c.getString(1);
                 if (entry.title == null) {
                     entry.title = "";
                     entry.contentDescription = "";
                 } else {
-                    entry.contentDescription = mUserManager.getBadgedLabelForUser(
+                    entry.contentDescription = mPackageManager.getUserBadgedLabel(
                             entry.title, cacheKey.user);
                 }
 
@@ -516,10 +529,8 @@
         public final static String[] COLUMNS_LOW_RES = new String[] {
                 IconDB.COLUMN_ICON_COLOR, IconDB.COLUMN_LABEL };
 
-        public IconDB(Context context, int iconPixelSize) {
-            super(context, LauncherFiles.APP_ICONS_DB,
-                    (RELEASE_VERSION << 16) + iconPixelSize,
-                    TABLE_NAME);
+        public IconDB(Context context, String dbFileName, int iconPixelSize) {
+            super(context, dbFileName, (RELEASE_VERSION << 16) + iconPixelSize, TABLE_NAME);
         }
 
         @Override
@@ -541,12 +552,18 @@
     private ContentValues newContentValues(BitmapInfo bitmapInfo, String label, String packageName) {
         ContentValues values = new ContentValues();
         values.put(IconDB.COLUMN_ICON,
-                bitmapInfo.isLowRes() ? null : Utilities.flattenBitmap(bitmapInfo.icon));
+                bitmapInfo.isLowRes() ? null : GraphicsUtils.flattenBitmap(bitmapInfo.icon));
         values.put(IconDB.COLUMN_ICON_COLOR, bitmapInfo.color);
 
         values.put(IconDB.COLUMN_LABEL, label);
-        values.put(IconDB.COLUMN_SYSTEM_STATE, mIconProvider.getIconSystemState(packageName));
+        values.put(IconDB.COLUMN_SYSTEM_STATE, getIconSystemState(packageName));
 
         return values;
     }
+
+    private void assertWorkerThread() {
+        if (Looper.myLooper() != mBgLooper) {
+            throw new IllegalStateException("Cache accessed on wrong thread " + Looper.myLooper());
+        }
+    }
 }
diff --git a/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
new file mode 100644
index 0000000..addb51f
--- /dev/null
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/CachingLogic.java
@@ -0,0 +1,33 @@
+/*
+ * 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.icons.cache;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.UserHandle;
+
+import com.android.launcher3.icons.BitmapInfo;
+
+public interface CachingLogic<T> {
+
+    ComponentName getComponent(T object);
+
+    UserHandle getUser(T object);
+
+    CharSequence getLabel(T object);
+
+    void loadIcon(Context context, T object, BitmapInfo target);
+}
diff --git a/src/com/android/launcher3/icons/HandlerRunnable.java b/iconloaderlib/src/com/android/launcher3/icons/cache/HandlerRunnable.java
similarity index 97%
rename from src/com/android/launcher3/icons/HandlerRunnable.java
rename to iconloaderlib/src/com/android/launcher3/icons/cache/HandlerRunnable.java
index e7132cd..ee52934 100644
--- a/src/com/android/launcher3/icons/HandlerRunnable.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/HandlerRunnable.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.icons;
+package com.android.launcher3.icons.cache;
 
 import android.os.Handler;
 
diff --git a/src/com/android/launcher3/icons/IconCacheUpdateHandler.java b/iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java
similarity index 90%
rename from src/com/android/launcher3/icons/IconCacheUpdateHandler.java
rename to iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java
index 07451b9..3c71bd0 100644
--- a/src/com/android/launcher3/icons/IconCacheUpdateHandler.java
+++ b/iconloaderlib/src/com/android/launcher3/icons/cache/IconCacheUpdateHandler.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.icons;
+package com.android.launcher3.icons.cache;
 
 import android.content.ComponentName;
 import android.content.pm.ApplicationInfo;
@@ -27,11 +27,8 @@
 import android.util.Log;
 import android.util.SparseBooleanArray;
 
-import com.android.launcher3.Utilities;
-import com.android.launcher3.icons.BaseIconCache.IconDB;
-import com.android.launcher3.util.IntArray;
+import com.android.launcher3.icons.cache.BaseIconCache.IconDB;
 
-import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -86,7 +83,8 @@
 
     private void createPackageInfoMap() {
         PackageManager pm = mIconCache.mPackageManager;
-        for (PackageInfo info : pm.getInstalledPackages(PackageManager.GET_UNINSTALLED_PACKAGES)) {
+        for (PackageInfo info :
+                pm.getInstalledPackages(PackageManager.MATCH_UNINSTALLED_PACKAGES)) {
             mPkgInfoMap.put(info.packageName, info);
         }
     }
@@ -125,13 +123,14 @@
      * the DB and are updated.
      * @return The set of packages for which icons have updated.
      */
+    @SuppressWarnings("unchecked")
     private <T> void updateIconsPerUser(UserHandle user, HashMap<ComponentName, T> componentMap,
             CachingLogic<T> cachingLogic, OnUpdateCallback onUpdateCallback) {
         Set<String> ignorePackages = mPackagesToIgnore.get(user);
         if (ignorePackages == null) {
             ignorePackages = Collections.emptySet();
         }
-        long userSerial = mIconCache.mUserManager.getSerialNumberForUser(user);
+        long userSerial = mIconCache.getSerialNumberForUser(user);
 
         Stack<T> appsToUpdate = new Stack<>();
 
@@ -174,7 +173,7 @@
                 T app = componentMap.remove(component);
                 if (version == info.versionCode && updateTime == info.lastUpdateTime &&
                         TextUtils.equals(c.getString(systemStateIndex),
-                                mIconCache.mIconProvider.getIconSystemState(info.packageName))) {
+                                mIconCache.getIconSystemState(info.packageName))) {
 
                     if (mFilterMode == MODE_CLEAR_VALID_ITEMS) {
                         mItemsToDelete.put(rowId, false);
@@ -204,18 +203,31 @@
         }
     }
 
+    /**
+     * Commits all updates as part of the update handler to disk. Not more calls should be made
+     * to this class after this.
+     */
     public void finish() {
         // Commit all deletes
-        IntArray deleteIds = new IntArray();
+        int deleteCount = 0;
+        StringBuilder queryBuilder = new StringBuilder()
+                .append(IconDB.COLUMN_ROWID)
+                .append(" IN (");
+
         int count = mItemsToDelete.size();
         for (int i = 0;  i < count; i++) {
             if (mItemsToDelete.valueAt(i)) {
-                deleteIds.add(mItemsToDelete.keyAt(i));
+                if (deleteCount > 0) {
+                    queryBuilder.append(", ");
+                }
+                queryBuilder.append(mItemsToDelete.keyAt(i));
+                deleteCount++;
             }
         }
-        if (!deleteIds.isEmpty()) {
-            mIconCache.mIconDb.delete(
-                    Utilities.createDbSelectionQuery(IconDB.COLUMN_ROWID, deleteIds), null);
+        queryBuilder.append(')');
+
+        if (deleteCount > 0) {
+            mIconCache.mIconDb.delete(queryBuilder.toString(), null);
         }
     }
 
diff --git a/src/com/android/launcher3/util/ComponentKey.java b/iconloaderlib/src/com/android/launcher3/util/ComponentKey.java
similarity index 93%
rename from src/com/android/launcher3/util/ComponentKey.java
rename to iconloaderlib/src/com/android/launcher3/util/ComponentKey.java
index d478ffa..34bed94 100644
--- a/src/com/android/launcher3/util/ComponentKey.java
+++ b/iconloaderlib/src/com/android/launcher3/util/ComponentKey.java
@@ -29,8 +29,9 @@
     private final int mHashCode;
 
     public ComponentKey(ComponentName componentName, UserHandle user) {
-        Preconditions.assertNotNull(componentName);
-        Preconditions.assertNotNull(user);
+        if (componentName == null || user == null) {
+            throw new NullPointerException();
+        }
         this.componentName = componentName;
         this.user = user;
         mHashCode = Arrays.hashCode(new Object[] {componentName, user});
diff --git a/src/com/android/launcher3/util/NoLocaleSQLiteHelper.java b/iconloaderlib/src/com/android/launcher3/util/NoLocaleSQLiteHelper.java
similarity index 93%
rename from src/com/android/launcher3/util/NoLocaleSQLiteHelper.java
rename to iconloaderlib/src/com/android/launcher3/util/NoLocaleSQLiteHelper.java
index 05a7d27..fe864a2 100644
--- a/src/com/android/launcher3/util/NoLocaleSQLiteHelper.java
+++ b/iconloaderlib/src/com/android/launcher3/util/NoLocaleSQLiteHelper.java
@@ -18,8 +18,6 @@
 
 import static android.database.sqlite.SQLiteDatabase.NO_LOCALIZED_COLLATORS;
 
-import static com.android.launcher3.Utilities.ATLEAST_P;
-
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.database.DatabaseErrorHandler;
@@ -27,6 +25,7 @@
 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 import android.database.sqlite.SQLiteDatabase.OpenParams;
 import android.database.sqlite.SQLiteOpenHelper;
+import android.os.Build;
 
 /**
  * Extension of {@link SQLiteOpenHelper} which avoids creating default locale table by
@@ -34,6 +33,9 @@
  */
 public abstract class NoLocaleSQLiteHelper extends SQLiteOpenHelper {
 
+    private static final boolean ATLEAST_P =
+            Build.VERSION.SDK_INT >= Build.VERSION_CODES.P;
+
     public NoLocaleSQLiteHelper(Context context, String name, int version) {
         super(ATLEAST_P ? context : new NoLocalContext(context), name, null, version);
         if (ATLEAST_P) {
diff --git a/src/com/android/launcher3/util/Provider.java b/iconloaderlib/src/com/android/launcher3/util/Provider.java
similarity index 100%
rename from src/com/android/launcher3/util/Provider.java
rename to iconloaderlib/src/com/android/launcher3/util/Provider.java
diff --git a/src/com/android/launcher3/util/SQLiteCacheHelper.java b/iconloaderlib/src/com/android/launcher3/util/SQLiteCacheHelper.java
similarity index 92%
rename from src/com/android/launcher3/util/SQLiteCacheHelper.java
rename to iconloaderlib/src/com/android/launcher3/util/SQLiteCacheHelper.java
index 3faf070..49de4bd 100644
--- a/src/com/android/launcher3/util/SQLiteCacheHelper.java
+++ b/iconloaderlib/src/com/android/launcher3/util/SQLiteCacheHelper.java
@@ -9,9 +9,6 @@
 import android.database.sqlite.SQLiteOpenHelper;
 import android.util.Log;
 
-import com.android.launcher3.Utilities;
-import com.android.launcher3.config.FeatureFlags;
-
 /**
  * An extension of {@link SQLiteOpenHelper} with utility methods for a single table cache DB.
  * Any exception during write operations are ignored, and any version change causes a DB reset.
@@ -19,8 +16,7 @@
 public abstract class SQLiteCacheHelper {
     private static final String TAG = "SQLiteCacheHelper";
 
-    private static final boolean NO_ICON_CACHE = FeatureFlags.IS_DOGFOOD_BUILD &&
-            Utilities.isPropertyEnabled(LogConfig.MEMORY_ONLY_ICON_CACHE);
+    private static final boolean IN_MEMORY_CACHE = false;
 
     private final String mTableName;
     private final MySQLiteOpenHelper mOpenHelper;
@@ -28,7 +24,7 @@
     private boolean mIgnoreWrites;
 
     public SQLiteCacheHelper(Context context, String name, int version, String tableName) {
-        if (NO_ICON_CACHE) {
+        if (IN_MEMORY_CACHE) {
             name = null;
         }
         mTableName = tableName;
diff --git a/iconloaderlib/src_full_lib/com/android/launcher3/icons/IconFactory.java b/iconloaderlib/src_full_lib/com/android/launcher3/icons/IconFactory.java
new file mode 100644
index 0000000..48f11fd
--- /dev/null
+++ b/iconloaderlib/src_full_lib/com/android/launcher3/icons/IconFactory.java
@@ -0,0 +1,89 @@
+/*
+ * 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.icons;
+
+import android.content.Context;
+
+/**
+ * Wrapper class to provide access to {@link BaseIconFactory} and also to provide pool of this class
+ * that are threadsafe.
+ */
+public class IconFactory extends BaseIconFactory {
+
+    private static final Object sPoolSync = new Object();
+    private static IconFactory sPool;
+    private static int sPoolId = 0;
+
+    /**
+     * Return a new Message instance from the global pool. Allows us to
+     * avoid allocating new objects in many cases.
+     */
+    public static IconFactory obtain(Context context) {
+        int poolId;
+        synchronized (sPoolSync) {
+            if (sPool != null) {
+                IconFactory m = sPool;
+                sPool = m.next;
+                m.next = null;
+                return m;
+            }
+            poolId = sPoolId;
+        }
+
+        return new IconFactory(context,
+                context.getResources().getConfiguration().densityDpi,
+                context.getResources().getDimensionPixelSize(R.dimen.default_icon_bitmap_size),
+                poolId);
+    }
+
+    public static void clearPool() {
+        synchronized (sPoolSync) {
+            sPool = null;
+            sPoolId++;
+        }
+    }
+
+    private final int mPoolId;
+
+    private IconFactory next;
+
+    private IconFactory(Context context, int fillResIconDpi, int iconBitmapSize, int poolId) {
+        super(context, fillResIconDpi, iconBitmapSize);
+        mPoolId = poolId;
+    }
+
+    /**
+     * Recycles a LauncherIcons that may be in-use.
+     */
+    public void recycle() {
+        synchronized (sPoolSync) {
+            if (sPoolId != mPoolId) {
+                return;
+            }
+            // Clear any temporary state variables
+            clear();
+
+            next = sPool;
+            sPool = this;
+        }
+    }
+
+    @Override
+    public void close() {
+        recycle();
+    }
+}
diff --git a/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java b/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java
new file mode 100644
index 0000000..1337975
--- /dev/null
+++ b/iconloaderlib/src_full_lib/com/android/launcher3/icons/SimpleIconCache.java
@@ -0,0 +1,114 @@
+/*
+ * 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.icons;
+
+import static android.content.Intent.ACTION_MANAGED_PROFILE_ADDED;
+import static android.content.Intent.ACTION_MANAGED_PROFILE_REMOVED;
+
+import android.annotation.TargetApi;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.util.SparseLongArray;
+
+import com.android.launcher3.icons.cache.BaseIconCache;
+
+/**
+ * Wrapper class to provide access to {@link BaseIconFactory} and also to provide pool of this class
+ * that are threadsafe.
+ */
+@TargetApi(Build.VERSION_CODES.P)
+public class SimpleIconCache extends BaseIconCache {
+
+    private static SimpleIconCache sIconCache = null;
+    private static final Object CACHE_LOCK = new Object();
+
+    private final SparseLongArray mUserSerialMap = new SparseLongArray(2);
+    private final UserManager mUserManager;
+
+    public SimpleIconCache(Context context, String dbFileName, Looper bgLooper, int iconDpi,
+            int iconPixelSize, boolean inMemoryCache) {
+        super(context, dbFileName, bgLooper, iconDpi, iconPixelSize, inMemoryCache);
+        mUserManager = context.getSystemService(UserManager.class);
+
+        // Listen for user cache changes.
+        IntentFilter filter = new IntentFilter(ACTION_MANAGED_PROFILE_ADDED);
+        filter.addAction(ACTION_MANAGED_PROFILE_REMOVED);
+        context.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                resetUserCache();
+            }
+        }, filter, null, new Handler(bgLooper), 0);
+    }
+
+    @Override
+    protected long getSerialNumberForUser(UserHandle user) {
+        synchronized (mUserSerialMap) {
+            int index = mUserSerialMap.indexOfKey(user.getIdentifier());
+            if (index >= 0) {
+                return mUserSerialMap.valueAt(index);
+            }
+            long serial = mUserManager.getSerialNumberForUser(user);
+            mUserSerialMap.put(user.getIdentifier(), serial);
+            return serial;
+        }
+    }
+
+    private void resetUserCache() {
+        synchronized (mUserSerialMap) {
+            mUserSerialMap.clear();
+        }
+    }
+
+    @Override
+    protected boolean isInstantApp(ApplicationInfo info) {
+        return info.isInstantApp();
+    }
+
+    @Override
+    protected BaseIconFactory getIconFactory() {
+        return IconFactory.obtain(mContext);
+    }
+
+    public static SimpleIconCache getIconCache(Context context) {
+        synchronized (CACHE_LOCK) {
+            if (sIconCache != null) {
+                return sIconCache;
+            }
+            boolean inMemoryCache =
+                    context.getResources().getBoolean(R.bool.simple_cache_enable_im_memory);
+            String dbFileName = context.getString(R.string.cache_db_name);
+
+            HandlerThread bgThread = new HandlerThread("simple-icon-cache");
+            bgThread.start();
+
+            sIconCache = new SimpleIconCache(context.getApplicationContext(), dbFileName,
+                    bgThread.getLooper(), context.getResources().getConfiguration().densityDpi,
+                    context.getResources().getDimensionPixelSize(R.dimen.default_icon_bitmap_size),
+                    inMemoryCache);
+            return sIconCache;
+        }
+    }
+}
diff --git a/libs/README.txt b/libs/README.txt
new file mode 100644
index 0000000..9109592
--- /dev/null
+++ b/libs/README.txt
@@ -0,0 +1,8 @@
+These jar are compiled in the frameworks/base of the platform tree.
+
+launcher_protos.jar is defined as launcherprotosnano in the following file:
+frameworks/base/core/protos/android/stats/launcher/Android.bp
+
+plugin_core.jar is defined as PluginCoreLib in the following file:
+frameworks/base/packages/SystemUI/plugin/Android.bp
+
diff --git a/libs/launcher_protos.jar b/libs/launcher_protos.jar
new file mode 100644
index 0000000..c043936
--- /dev/null
+++ b/libs/launcher_protos.jar
Binary files differ
diff --git a/proguard.flags b/proguard.flags
index bb52a6c..272ab7a 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -24,7 +24,7 @@
 -keep class androidx.recyclerview.widget.RecyclerView { *; }
 
 # Preference fragments
--keep class ** extends android.preference.PreferenceFragment {
+-keep class ** extends android.app.Fragment {
     public <init>(...);
 }
 
@@ -50,3 +50,4 @@
 -dontwarn android.app.**
 -dontwarn android.view.**
 -dontwarn android.os.**
+-dontwarn android.graphics.**
\ No newline at end of file
diff --git a/quickstep/AndroidManifest.xml b/quickstep/AndroidManifest.xml
index 74e0b1e..542a235 100644
--- a/quickstep/AndroidManifest.xml
+++ b/quickstep/AndroidManifest.xml
@@ -22,7 +22,6 @@
     xmlns:tools="http://schemas.android.com/tools"
     package="com.android.launcher3" >
 
-    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="28"/>
     <uses-permission android:name="android.permission.CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS" />
 
     <application
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 163524e..8af310c 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/res/layout/overview_panel.xml b/quickstep/recents_ui_overrides/res/layout/overview_panel.xml
similarity index 100%
rename from quickstep/res/layout/overview_panel.xml
rename to quickstep/recents_ui_overrides/res/layout/overview_panel.xml
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PortraitOverviewStateTouchHelper.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PortraitOverviewStateTouchHelper.java
new file mode 100644
index 0000000..eead4c8
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PortraitOverviewStateTouchHelper.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.uioverrides;
+
+import static com.android.launcher3.uioverrides.PortraitStatesTouchController.isTouchOverHotseat;
+
+import android.view.MotionEvent;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.util.PendingAnimation;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.TaskView;
+
+/**
+ * Helper class for {@link PortraitStatesTouchController} that determines swipeable regions and
+ * animations on the overview state that depend on the recents implementation.
+ */
+public final class PortraitOverviewStateTouchHelper {
+
+    RecentsView mRecentsView;
+    Launcher mLauncher;
+
+    public PortraitOverviewStateTouchHelper(Launcher launcher) {
+        mLauncher = launcher;
+        mRecentsView = launcher.getOverviewPanel();
+    }
+
+    /**
+     * Whether or not {@link PortraitStatesTouchController} should intercept the touch when on the
+     * overview state.
+     *
+     * @param ev the motion event
+     * @return true if we should intercept the motion event
+     */
+    boolean canInterceptTouch(MotionEvent ev) {
+        if (mRecentsView.getChildCount() > 0) {
+            // Allow swiping up in the gap between the hotseat and overview.
+            return ev.getY() >= mRecentsView.getChildAt(0).getBottom();
+        } else {
+            // If there are no tasks, we only intercept if we're below the hotseat height.
+            return isTouchOverHotseat(mLauncher, ev);
+        }
+    }
+
+    /**
+     * Whether or not swiping down to leave overview state should return to the currently running
+     * task app.
+     *
+     * @return true if going back should take the user to the currently running task
+     */
+    boolean shouldSwipeDownReturnToApp() {
+        TaskView taskView = mRecentsView.getTaskViewAt(mRecentsView.getNextPage());
+        return taskView != null && mRecentsView.shouldSwipeDownLaunchApp();
+    }
+
+    /**
+     * Create the animation for going from overview to the task app via swiping. Should only be
+     * called when {@link #shouldSwipeDownReturnToApp()} returns true.
+     *
+     * @param duration how long the animation should be
+     * @return the animation
+     */
+    PendingAnimation createSwipeDownToTaskAppAnimation(long duration) {
+        TaskView taskView = mRecentsView.getTaskViewAt(mRecentsView.getNextPage());
+        if (taskView == null) {
+            throw new IllegalStateException("There is no task view to animate to.");
+        }
+        return mRecentsView.createTaskLauncherAnimation(taskView, duration);
+    }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
new file mode 100644
index 0000000..f18f43c
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsUiFactory.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.uioverrides;
+
+import static android.view.View.VISIBLE;
+
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.util.TouchController;
+import com.android.quickstep.views.RecentsView;
+
+/**
+ * Provides recents-related {@link UiFactory} logic and classes.
+ */
+public final class RecentsUiFactory {
+
+    // Scale recents takes before animating in
+    private static final float RECENTS_PREPARE_SCALE = 1.33f;
+
+    private RecentsUiFactory() {}
+
+    /**
+     * Creates and returns a touch controller for swiping recents tasks.
+     *
+     * @param launcher the launcher activity
+     * @return the touch controller for recents tasks
+     */
+    public static TouchController createTaskSwipeController(Launcher launcher) {
+        return new LauncherTaskViewController(launcher);
+    }
+
+    /**
+     * Creates and returns the controller responsible for recents view state transitions.
+     *
+     * @param launcher the launcher activity
+     * @return state handler for recents
+     */
+    public static StateHandler createRecentsViewStateController(Launcher launcher) {
+        return new RecentsViewStateController(launcher);
+    }
+
+    /**
+     * Prepare the recents view to animate in.
+     *
+     * @param launcher the launcher activity
+     */
+    public static void prepareToShowRecents(Launcher launcher) {
+        RecentsView overview = launcher.getOverviewPanel();
+        if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
+            SCALE_PROPERTY.set(overview, RECENTS_PREPARE_SCALE);
+        }
+    }
+
+    /**
+     * Clean-up logic that occurs when recents is no longer in use/visible.
+     *
+     * @param launcher the launcher activity
+     */
+    public static void resetRecents(Launcher launcher) {
+        RecentsView recents = launcher.getOverviewPanel();
+        recents.reset();
+    }
+
+    /**
+     * Recents logic that triggers when launcher state changes or launcher activity stops/resumes.
+     *
+     * @param launcher the launcher activity
+     */
+    public static void onLauncherStateOrResumeChanged(Launcher launcher) {
+        LauncherState state = launcher.getStateManager().getState();
+        if (state == NORMAL) {
+            launcher.<RecentsView>getOverviewPanel().setSwipeDownShouldLaunchApp(false);
+        }
+    }
+
+    private static final class LauncherTaskViewController extends
+            TaskViewTouchController<Launcher> {
+
+        LauncherTaskViewController(Launcher activity) {
+            super(activity);
+        }
+
+        @Override
+        protected boolean isRecentsInteractive() {
+            return mActivity.isInState(OVERVIEW);
+        }
+
+        @Override
+        protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) {
+            mActivity.getStateManager().setCurrentUserControlledAnimation(animController);
+        }
+    }
+}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
new file mode 100644
index 0000000..7d7946d
--- /dev/null
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.uioverrides;
+
+import static com.android.launcher3.LauncherState.FAST_OVERVIEW;
+import static com.android.launcher3.LauncherState.OVERVIEW;
+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.CONTENT_ALPHA;
+
+import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.util.FloatProperty;
+import android.view.animation.Interpolator;
+
+import androidx.annotation.NonNull;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.LauncherStateManager.AnimationConfig;
+import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.anim.Interpolators;
+import com.android.quickstep.views.LauncherRecentsView;
+import com.android.quickstep.views.RecentsView;
+
+/**
+ * State handler for handling UI changes for {@link LauncherRecentsView}. In addition to managing
+ * the basic view properties, this class also manages changes in the task visuals.
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public final class RecentsViewStateController extends
+        BaseRecentsViewStateController<LauncherRecentsView> {
+
+    public RecentsViewStateController(Launcher launcher) {
+        super(launcher);
+    }
+
+    @Override
+    public void setState(@NonNull LauncherState state) {
+        super.setState(state);
+        if (state.overviewUi) {
+            mRecentsView.updateEmptyMessage();
+            mRecentsView.resetTaskVisuals();
+        }
+    }
+
+    @Override
+    void setStateWithAnimationInternal(@NonNull final LauncherState toState,
+            @NonNull AnimatorSetBuilder builder, @NonNull AnimationConfig config) {
+        super.setStateWithAnimationInternal(toState, builder, config);
+
+        if (!toState.overviewUi) {
+            builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals);
+        }
+
+        if (toState.overviewUi) {
+            ValueAnimator updateAnim = ValueAnimator.ofFloat(0, 1);
+            updateAnim.addUpdateListener(valueAnimator -> {
+                // While animating into recents, update the visible task data as needed
+                mRecentsView.loadVisibleTaskData();
+            });
+            updateAnim.setDuration(config.duration);
+            builder.play(updateAnim);
+            mRecentsView.updateEmptyMessage();
+        }
+    }
+
+    @Override
+    Interpolator getScaleAndTransYInterpolator(@NonNull LauncherState toState,
+            @NonNull AnimatorSetBuilder builder) {
+        if (mLauncher.getStateManager().getState() == OVERVIEW && toState == FAST_OVERVIEW) {
+            return Interpolators.clampToProgress(QUICK_SCRUB_START_INTERPOLATOR, 0,
+                    QUICK_SCRUB_TRANSLATION_Y_FACTOR);
+        }
+        return super.getScaleAndTransYInterpolator(toState, builder);
+    }
+
+    @Override
+    FloatProperty<LauncherRecentsView> getTranslationYFactorProperty() {
+        return TRANSLATION_Y_FACTOR;
+    }
+
+    @Override
+    FloatProperty<RecentsView> getContentAlphaProperty() {
+        return CONTENT_ALPHA;
+    }
+}
diff --git a/quickstep/res/drawable/bg_wellbeing_toast.xml b/quickstep/res/drawable/bg_wellbeing_toast.xml
new file mode 100644
index 0000000..22d6f8a
--- /dev/null
+++ b/quickstep/res/drawable/bg_wellbeing_toast.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
+    <solid android:color="#E61A73E8" />
+    <corners android:radius="@dimen/task_corner_radius" />
+</shape>
\ No newline at end of file
diff --git a/quickstep/res/drawable/hourglass_bottom.xml b/quickstep/res/drawable/hourglass_bottom.xml
new file mode 100644
index 0000000..b5ef008
--- /dev/null
+++ b/quickstep/res/drawable/hourglass_bottom.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <group>
+        <clip-path android:pathData="M0,0H24V24H0Z M 0,0"/>
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M6,2V8H6l4,4L6,16H6v6H18V16h0l-4,-4,4,-4h0V2Zm6,9.5,-4,-4V4h8V7.5Z"/>
+    </group>
+</vector>
diff --git a/quickstep/res/drawable/hourglass_top.xml b/quickstep/res/drawable/hourglass_top.xml
new file mode 100644
index 0000000..7fc77d3
--- /dev/null
+++ b/quickstep/res/drawable/hourglass_top.xml
@@ -0,0 +1,12 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24"
+        android:viewportHeight="24">
+    <group>
+        <clip-path android:pathData="M0,0H24V24H0Z M 0,0"/>
+        <path
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M6,2V8H6l4,4L6,16H6v6H18V16h0l-4,-4,4,-4h0V2ZM16,16.5V20H8V16.5l4,-4Z"/>
+    </group>
+</vector>
diff --git a/quickstep/res/layout/task.xml b/quickstep/res/layout/task.xml
index 36d327d..f96a66f 100644
--- a/quickstep/res/layout/task.xml
+++ b/quickstep/res/layout/task.xml
@@ -34,4 +34,30 @@
         android:layout_gravity="top|center_horizontal"
         android:focusable="false"
         android:importantForAccessibility="no" />
+
+    <com.android.quickstep.views.DigitalWellBeingToast
+        android:id="@+id/digital_well_being_toast"
+        android:layout_width="match_parent"
+        android:layout_height="48dp"
+        android:importantForAccessibility="noHideDescendants"
+        android:background="@drawable/bg_wellbeing_toast"
+        android:layout_gravity="bottom"
+        android:gravity="center"
+        android:visibility="gone">
+        <ImageView
+            android:id="@+id/digital_well_being_hourglass"
+            android:layout_width="24dp"
+            android:layout_height="24dp"
+            android:layout_marginEnd="8dp"
+        />
+        <TextView
+            android:id="@+id/digital_well_being_remaining_time"
+            android:layout_width="wrap_content"
+            android:layout_height="24dp"
+            android:fontFamily="sans-serif"
+            android:textSize="14sp"
+            android:textColor="@android:color/white"
+            android:gravity="center_vertical"
+        />
+    </com.android.quickstep.views.DigitalWellBeingToast>
 </com.android.quickstep.views.TaskView>
\ No newline at end of file
diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml
index f9432ad..5ce3c0d 100644
--- a/quickstep/res/values-af/strings.xml
+++ b/quickstep/res/values-af/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Verdeelde skerm"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Speld vas"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Vormvry"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Oorsig"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Geen onlangse items nie"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Maak toe"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Programgebruikinstellings"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Vee alles uit"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Onlangse programme"</string>
 </resources>
diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml
index 4ca0c67..99dc137 100644
--- a/quickstep/res/values-am/strings.xml
+++ b/quickstep/res/values-am/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"የተከፈለ ማያ ገጽ"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ሰካ"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"ነጻ ቅጽ"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ማጠቃለያ"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"ምንም የቅርብ ጊዜ ንጥሎች የሉም"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ዝጋ"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"የመተግበሪያ አጠቃቀም ቅንብሮች"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ሁሉንም አጽዳ"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"የቅርብ ጊዜ መተግበሪያዎች"</string>
 </resources>
diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml
index c203a4f..808082e 100644
--- a/quickstep/res/values-ar/strings.xml
+++ b/quickstep/res/values-ar/strings.xml
@@ -21,6 +21,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"تقسيم الشاشة"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"تثبيت"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"شكل مجاني"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"نظرة عامة"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"ليست هناك عناصر تم استخدامها مؤخرًا"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"إغلاق"</string>
diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml
index 812a246..eac2878 100644
--- a/quickstep/res/values-as/strings.xml
+++ b/quickstep/res/values-as/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"বিভাজিত স্ক্ৰীণ"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"পিন"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"অৱলোকন"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"কোনো শেহতীয়া বস্তু নাই"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"বন্ধ কৰক"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"এপে ব্যৱহাৰ কৰা ডেটাৰ ছেটিংসমূহ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"সকলো মচক"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"শেহতীয়া এপসমূহ"</string>
 </resources>
diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml
index 57ad30d..d707108 100644
--- a/quickstep/res/values-az/strings.xml
+++ b/quickstep/res/values-az/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Bölünmüş ekran"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Sancın"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Sərbəst rejim"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"İcmal"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Son elementlər yoxdur"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Bağlayın"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Tətbiq istifadə ayarları"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hamısını silin"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Son tətbiqlər"</string>
 </resources>
diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml
index fc4c8c0..fd449b8 100644
--- a/quickstep/res/values-b+sr+Latn/strings.xml
+++ b/quickstep/res/values-b+sr+Latn/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Podeljeni ekran"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Zakači"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodni oblik"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pregled"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zatvori"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Podešavanja korišćenja aplikacije"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Obriši sve"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Nedavne aplikacije"</string>
 </resources>
diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml
index c5d03d4..fa1f28e 100644
--- a/quickstep/res/values-be/strings.xml
+++ b/quickstep/res/values-be/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Падзяліць экран"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Замацаваць"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Адвольная форма"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Агляд"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Няма новых элементаў"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Закрыць"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Налады выкарыстання праграмы"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ачысціць усё"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Нядаўнія праграмы"</string>
 </resources>
diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml
index 2672b83..0f817ac 100644
--- a/quickstep/res/values-bg/strings.xml
+++ b/quickstep/res/values-bg/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Разделен екран"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Фиксиране"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Свободна форма"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Общ преглед"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Няма скорошни елементи"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Затваряне"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Настройки за използването на приложенията"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Изчистване на всички"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Скорошни приложения"</string>
 </resources>
diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml
index 0a824c2..c7342f3 100644
--- a/quickstep/res/values-bn/strings.xml
+++ b/quickstep/res/values-bn/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"স্ক্রিন স্প্লিট করুন"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"পিন করুন"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"ফ্রি-ফর্ম"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"এক নজরে"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"কোনো সাম্প্রতিক আইটেম নেই"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"বন্ধ করুন"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"অ্যাপ ব্যবহারের সেটিংস"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"সবকিছু খালি করুন"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"সম্প্রতি ব্যবহৃত অ্যাপ"</string>
 </resources>
diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml
index 3228de0..d0d0aa6 100644
--- a/quickstep/res/values-bs/strings.xml
+++ b/quickstep/res/values-bs/strings.xml
@@ -21,10 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Način rada podijeljenog ekrana"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Zakači"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodan oblik"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pregled"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zatvaranje"</string>
-    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Postavke upotrebe aplikacija"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Postavke korištenja aplikacije"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Obriši sve"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Nedavne aplikacije"</string>
 </resources>
diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml
index 2d51703..5bdd67d 100644
--- a/quickstep/res/values-ca/strings.xml
+++ b/quickstep/res/values-ca/strings.xml
@@ -19,11 +19,13 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Divideix la pantalla"</string>
+    <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Pantalla dividida"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixa"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Format lliure"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Aplicacions recents"</string>
     <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="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuració d\'ús d\'aplicacions"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Esborra-ho tot"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplicacions recents"</string>
 </resources>
diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml
index ec5095c..5fe7088 100644
--- a/quickstep/res/values-cs/strings.xml
+++ b/quickstep/res/values-cs/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Rozdělená obrazovka"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"PIN"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Neomezený režim"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Přehled"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Žádné nedávné položky"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zavřít"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavení využití aplikací"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Vymazat vše"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Poslední aplikace"</string>
 </resources>
diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml
index 13eb0cd..4c3ec59 100644
--- a/quickstep/res/values-da/strings.xml
+++ b/quickstep/res/values-da/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Opdel skærm"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fastgør"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Frit format"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Oversigt"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Ingen nye elementer"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Luk"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Indstillinger for appforbrug"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ryd alt"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Seneste apps"</string>
 </resources>
diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml
index 2f50639..fb428f7 100644
--- a/quickstep/res/values-de/strings.xml
+++ b/quickstep/res/values-de/strings.xml
@@ -19,13 +19,13 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Splitscreen (Duden compliant spelling, sorry!) Splitscreenmodus (or spelling variations thereof) Splitscreen öffnen"</string>
+    <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Splitscreen"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixieren"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform-Modus"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Übersicht"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Keine kürzlich verwendeten Elemente"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Schließen"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Einstellungen zur App-Nutzung"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Alle Apps schließen"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Zuletzt aktive Apps"</string>
 </resources>
diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml
index 7c11681..54d4677 100644
--- a/quickstep/res/values-el/strings.xml
+++ b/quickstep/res/values-el/strings.xml
@@ -21,6 +21,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Διαχωρισμός οθόνης"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Καρφίτσωμα"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Ελεύθερη μορφή"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Επισκόπηση"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Δεν υπάρχουν πρόσφατα στοιχεία"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Κλείσιμο"</string>
diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml
index e6cb731..df2fee8 100644
--- a/quickstep/res/values-en-rAU/strings.xml
+++ b/quickstep/res/values-en-rAU/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Split screen"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overview"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Close"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Recent apps"</string>
 </resources>
diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml
index e6cb731..df2fee8 100644
--- a/quickstep/res/values-en-rGB/strings.xml
+++ b/quickstep/res/values-en-rGB/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Split screen"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overview"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Close"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Recent apps"</string>
 </resources>
diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml
index e6cb731..df2fee8 100644
--- a/quickstep/res/values-en-rIN/strings.xml
+++ b/quickstep/res/values-en-rIN/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Split screen"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pin"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overview"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"No recent items"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Close"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"App usage settings"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Clear all"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Recent apps"</string>
 </resources>
diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml
index 83e9d96..9d98d6b 100644
--- a/quickstep/res/values-es-rUS/strings.xml
+++ b/quickstep/res/values-es-rUS/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Pantalla dividida"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fijar"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Formato libre"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Recientes"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"No hay elementos recientes"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Cerrar"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuración de uso de la app"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Apps recientes"</string>
 </resources>
diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml
index e076df5..b39262b 100644
--- a/quickstep/res/values-es/strings.xml
+++ b/quickstep/res/values-es/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Dividir pantalla"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fijar"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Formato libre"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Aplicaciones recientes"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"No hay elementos recientes"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Cerrar"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ajustes de uso de la aplicación"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplicaciones recientes"</string>
 </resources>
diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml
index 85de9c0..9b859fd 100644
--- a/quickstep/res/values-et/strings.xml
+++ b/quickstep/res/values-et/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Jagatud ekraan"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Kinnita"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Vabavorm"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ülevaade"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Hiljutisi üksusi pole"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Sule"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Rakenduse kasutuse seaded"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Sule kõik"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Hiljutised rakendused"</string>
 </resources>
diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml
index c54071f..096a849 100644
--- a/quickstep/res/values-eu/strings.xml
+++ b/quickstep/res/values-eu/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Zatitu pantaila"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Ainguratu"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Modu librea"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ikuspegi orokorra"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Ez dago azkenaldi honetako ezer"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Itxi"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Aplikazioen erabileraren ezarpenak"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Garbitu guztiak"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Azken aplikazioak"</string>
 </resources>
diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml
index 976d656..3ae1bd8 100644
--- a/quickstep/res/values-fa/strings.xml
+++ b/quickstep/res/values-fa/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"تقسیم صفحه"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"پین"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"نمای کلی"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"بدون موارد اخیر"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"بستن"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"تنظیمات استفاده از برنامه"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"پاک کردن همه"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"برنامه‌های اخیر"</string>
 </resources>
diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml
index 8f41350..79c2d6b 100644
--- a/quickstep/res/values-fi/strings.xml
+++ b/quickstep/res/values-fi/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Jaettu näyttö"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Kiinnitä"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Vapaamuotoinen"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Viimeisimmät"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Ei viimeaikaisia kohteita"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Sulje"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Sovelluksen käyttöasetukset"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Poista kaikki"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Viimeisimmät sovellukset"</string>
 </resources>
diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml
index 7177996..e64985e 100644
--- a/quickstep/res/values-fr-rCA/strings.xml
+++ b/quickstep/res/values-fr-rCA/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Écran divisé"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Épingler"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Forme libre"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Aperçu"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Fermer"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Paramètres d\'utilisation de l\'application"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Applications récentes"</string>
 </resources>
diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml
index 0deb00b..03b2f68 100644
--- a/quickstep/res/values-fr/strings.xml
+++ b/quickstep/res/values-fr/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Écran partagé"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Épingler"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Format libre"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Aperçu"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Aucun élément récent"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Fermer"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Paramètres de consommation de l\'application"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Tout effacer"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Applications récentes"</string>
 </resources>
diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml
index 8c217eb..2fefd82 100644
--- a/quickstep/res/values-gl/strings.xml
+++ b/quickstep/res/values-gl/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Pantalla dividida"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Forma libre"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Visión xeral"</string>
     <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="accessibility_app_usage_settings" msgid="6312864233673544149">"Configuración do uso de aplicacións"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Borrar todo"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplicacións recentes"</string>
 </resources>
diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml
index 8b9a538..2e5fdde 100644
--- a/quickstep/res/values-gu/strings.xml
+++ b/quickstep/res/values-gu/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"સ્ક્રીનને વિભાજિત કરો"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"પિન કરો"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"ફ્રિફોર્મ"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ઝલક"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"તાજેતરની કોઈ આઇટમ નથી"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"બંધ કરો"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ઍપ વપરાશનું સેટિંગ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"બધું સાફ કરો"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"તાજેતરની ઍપ"</string>
 </resources>
diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml
index 83c31e7..a1107a2 100644
--- a/quickstep/res/values-hi/strings.xml
+++ b/quickstep/res/values-hi/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"स्क्रीन को दो हिस्सों में बाँटना (स्प्लिट स्क्रीन)"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"पिन करना"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"फ़्रीफ़ॉर्म"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"खास जानकारी"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"हाल ही में इस्तेमाल किया गया कोई ऐप्लिकेशन नहीं है"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"बंद करें"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ऐप्लिकेशन इस्तेमाल की सेटिंग"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सभी ऐप्लिकेशन बंद करें"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"हाल ही में इस्तेमाल किए गए एेप्लिकेशन"</string>
 </resources>
diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml
index fbc3e48..f7e0caa 100644
--- a/quickstep/res/values-hr/strings.xml
+++ b/quickstep/res/values-hr/strings.xml
@@ -21,6 +21,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Podijeljeni zaslon"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Prikvači"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Slobodni oblik"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pregled"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Nema nedavnih stavki"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zatvori"</string>
diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml
index d971374..c2f042c 100644
--- a/quickstep/res/values-hu/strings.xml
+++ b/quickstep/res/values-hu/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Osztott képernyő"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Rögzítés"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Szabad forma"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Áttekintés"</string>
     <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="accessibility_app_usage_settings" msgid="6312864233673544149">"Alkalmazáshasználati beállítások"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Összes törlése"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Legutóbbi alkalmazások"</string>
 </resources>
diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml
index b4b9b98..b8a12c9 100644
--- a/quickstep/res/values-hy/strings.xml
+++ b/quickstep/res/values-hy/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Տրոհել էկրանը"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Ամրացնել"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Կամայական ձև"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ընդհանուր տեղեկություններ"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Վերջին տարրեր չկան"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Փակել"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Հավելվածի օգտագործման կարգավորումներ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Փակել բոլորը"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Վերջին օգտագործած հավելվածները"</string>
 </resources>
diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml
index d16d4e8..276c144 100644
--- a/quickstep/res/values-in/strings.xml
+++ b/quickstep/res/values-in/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Layar terpisah"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pasang pin"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Format bebas"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ringkasan"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Tidak ada item yang baru dibuka"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Tutup"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Setelan penggunaan aplikasi"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hapus semua"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplikasi baru-baru ini"</string>
 </resources>
diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml
index 1aface0..b4fb172 100644
--- a/quickstep/res/values-is/strings.xml
+++ b/quickstep/res/values-is/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Skipta skjá"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Festa"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Frjálst snið"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Yfirlit"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Engin nýleg atriði"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Loka"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Notkunarstillingar forrits"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hreinsa allt"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Nýleg forrit"</string>
 </resources>
diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml
index eda8363..c44cc01 100644
--- a/quickstep/res/values-it/strings.xml
+++ b/quickstep/res/values-it/strings.xml
@@ -21,6 +21,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Schermo diviso"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Blocca"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Forma libera"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Panoramica"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Nessun elemento recente"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Chiudi"</string>
diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml
index 13cb7b4..f7a0384 100644
--- a/quickstep/res/values-iw/strings.xml
+++ b/quickstep/res/values-iw/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"מסך מפוצל"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"הצמדה"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"מצב חופשי"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"מסכים אחרונים"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"אין פריטים אחרונים"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"סגירה"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"הגדרות שימוש באפליקציה"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ניקוי הכול"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"אפליקציות אחרונות"</string>
 </resources>
diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml
index 558112c..fff8a0d 100644
--- a/quickstep/res/values-ja/strings.xml
+++ b/quickstep/res/values-ja/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"分割画面"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"フリーフォーム"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"概要"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"最近のアイテムはありません"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"閉じる"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"アプリの使用状況の設定"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"すべてクリア"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"最近使ったアプリ"</string>
 </resources>
diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml
index c5f823e..cc0d594 100644
--- a/quickstep/res/values-ka/strings.xml
+++ b/quickstep/res/values-ka/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ეკრანის გაყოფა"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ჩამაგრება"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"თავისუფალი ფორმა"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"მიმოხილვა"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"ბოლოს გამოყენებული ერთეულები არ არის"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"დახურვა"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"აპების გამოყენების პარამეტრები"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ყველას გასუფთავება"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"ბოლოდროინდელი აპები"</string>
 </resources>
diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml
index 3e72130..b0a1b4e 100644
--- a/quickstep/res/values-kk/strings.xml
+++ b/quickstep/res/values-kk/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Экранды бөлу"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Бекіту"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Еркін форма"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Шолу"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Соңғы элементтер жоқ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Жабу"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Қолданбаны пайдалану параметрлері"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Барлығын өшіру"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Соңғы пайдаланылған қолданбалар"</string>
 </resources>
diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml
index 6ae9482..7aa407c 100644
--- a/quickstep/res/values-km/strings.xml
+++ b/quickstep/res/values-km/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"មុខងារ​បំបែកអេក្រង់"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ដៅ"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"មុខងារទម្រង់សេរី"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ទិដ្ឋភាពរួម"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"មិនមានធាតុថ្មីៗទេ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"បិទ"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ការកំណត់​ការប្រើប្រាស់​កម្មវិធី"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"សម្អាត​ទាំងអស់"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"កម្មវិធី​ថ្មីៗ"</string>
 </resources>
diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml
index 1caa220..e5ac0df 100644
--- a/quickstep/res/values-kn/strings.xml
+++ b/quickstep/res/values-kn/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ಪರದೆಯನ್ನು ಬೇರ್ಪಡಿಸಿ"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ಪಿನ್ ಮಾಡಿ"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"ಮುಕ್ತಸ್ವರೂಪ"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ಅವಲೋಕನ"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"ಯಾವುದೇ ಇತ್ತೀಚಿನ ಐಟಂಗಳಿಲ್ಲ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ಮುಚ್ಚಿ"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ಆ್ಯಪ್‌ ಬಳಕೆಯ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ಎಲ್ಲವನ್ನೂ ತೆರವುಗೊಳಿಸಿ"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"ಇತ್ತೀಚಿನ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
 </resources>
diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml
index 5b1ecbd..8e7dcb1 100644
--- a/quickstep/res/values-ko/strings.xml
+++ b/quickstep/res/values-ko/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"화면 분할"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"고정"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"자유 형식"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"최근 사용"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"최근 항목이 없습니다."</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"닫기"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"앱 사용 설정"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"모두 삭제"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"최근 앱"</string>
 </resources>
diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml
index 9f84037..13d8399 100644
--- a/quickstep/res/values-ky/strings.xml
+++ b/quickstep/res/values-ky/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Экранды бөлүү"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Кадап коюу"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Эркин форма режими"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Сереп салуу"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Акыркы колдонмолор жок"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Жабуу"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Колдонмону пайдалануу жөндөөлөрү"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Баарын тазалоо"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Акыркы колдонмолор"</string>
 </resources>
diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml
index ed1cb6e..622118c 100644
--- a/quickstep/res/values-lo/strings.xml
+++ b/quickstep/res/values-lo/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ແບ່ງໜ້າຈໍ"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ປັກໝຸດ"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"ຮູບແບບອິດສະຫລະ"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ພາບຮວມ"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"ບໍ່ມີລາຍການຫຼ້າສຸດ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ປິດ"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ການຕັ້ງຄ່າການນຳໃຊ້ແອັບ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ລຶບລ້າງທັງໝົດ"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"ແອັບຫຼ້າສຸດ"</string>
 </resources>
diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml
index c16fc56..42e4fe8 100644
--- a/quickstep/res/values-lt/strings.xml
+++ b/quickstep/res/values-lt/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Skaidyti ekraną"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Prisegti"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Laisva forma"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Apžvalga"</string>
     <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="accessibility_app_usage_settings" msgid="6312864233673544149">"Programos naudojimo nustatymai"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Išvalyti viską"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Naujausios programos"</string>
 </resources>
diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml
index 2dee41c..c249928 100644
--- a/quickstep/res/values-lv/strings.xml
+++ b/quickstep/res/values-lv/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Sadalīt ekrānu"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Piespraust"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Brīva forma"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pārskats"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Nav nesenu vienumu."</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Aizvērt"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Lietotņu izmantošanas iestatījumi"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Notīrīt visu"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Pēdējās izmantotās lietotnes"</string>
 </resources>
diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml
index ff16cea..fa4e401 100644
--- a/quickstep/res/values-mk/strings.xml
+++ b/quickstep/res/values-mk/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Поделен екран"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Прикачување"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Преглед"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Нема неодамнешни ставки"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Затвори"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Поставки за користење на апликациите"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Исчисти ги сите"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Неодамнешни апликации"</string>
 </resources>
diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml
index 624aded..4be84c8 100644
--- a/quickstep/res/values-ml/strings.xml
+++ b/quickstep/res/values-ml/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"സ്‌ക്രീൻ വിഭജിക്കുക"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"പിൻ ചെയ്യുക"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"ഫ്രീഫോം"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"അവലോകനം"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"സമീപകാല ഇനങ്ങൾ ഒന്നുമില്ല"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"അവസാനിപ്പിക്കുക"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ആപ്പ് ഉപയോഗ ക്രമീകരണം"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"എല്ലാം മായ്‌ക്കുക"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"സമീപകാല ആപ്പുകൾ"</string>
 </resources>
diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml
index f902125..b3e3d7f 100644
--- a/quickstep/res/values-mn/strings.xml
+++ b/quickstep/res/values-mn/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Дэлгэцийг хуваах"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Тогтоох"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Чөлөөтэй хувьсах"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Тойм"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Сүүлийн үеийн зүйл алга"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Хаах"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Апп ашиглалтын тохиргоо"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Бүгдийг устгах"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Саяхны аппууд"</string>
 </resources>
diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml
index ffafbdb..fa8574a 100644
--- a/quickstep/res/values-mr/strings.xml
+++ b/quickstep/res/values-mr/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"विभाजित स्क्रीन"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"पिन करा"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"फ्रीफॉर्म"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"अवलोकन"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"कोणतेही अलीकडील आयटम नाहीत"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"बंद"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"अ‍ॅप वापर सेटिंग्ज"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सर्व साफ करा"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"अलीकडील अॅप्स"</string>
 </resources>
diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml
index 6995863..975e127 100644
--- a/quickstep/res/values-ms/strings.xml
+++ b/quickstep/res/values-ms/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Skrin pisah"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Semat"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Bentuk bebas"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Ikhtisar"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Tiada item terbaharu"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Tutup"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Tetapan penggunaan apl"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Kosongkan semua"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Apl terbaharu"</string>
 </resources>
diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml
index 6eab2fc..52d4dae 100644
--- a/quickstep/res/values-my/strings.xml
+++ b/quickstep/res/values-my/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"မျက်နှာပြင် ခွဲ၍ပြသခြင်း"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ပင်ထိုးခြင်း"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"အလွတ်ပုံစံ"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"အနှစ်ချုပ်"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"မကြာမီကဖွင့်ထားသည်များ မရှိပါ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ပိတ်ရန်"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"အက်ပ်အသုံးပြုမှု ဆက်တင်များ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"အားလုံးကို ရှင်းရန်"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"လတ်တလောသုံး အက်ပ်များ"</string>
 </resources>
diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml
index cb8ee10..c681a1e 100644
--- a/quickstep/res/values-nb/strings.xml
+++ b/quickstep/res/values-nb/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Delt skjerm"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fest"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Fritt format"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Oversikt"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Ingen nylige elementer"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Lukk"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Innstillinger for appbruk"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Fjern alt"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Nylige apper"</string>
 </resources>
diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml
index 4efae7b..46e0eaf 100644
--- a/quickstep/res/values-ne/strings.xml
+++ b/quickstep/res/values-ne/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"स्क्रिन विभाजन गर्नुहोस्"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"पिन गर्नुहोस्"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"फ्रिफर्म"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"परिदृश्य"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"हालसालैको कुनै पनि वस्तु छैन"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"बन्द गर्नुहोस्"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"अनुप्रयोगको उपयोगका सेटिङहरू"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"सबै खाली गर्नुहोस्"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"हालसालैका अनुप्रयोगहरू"</string>
 </resources>
diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml
index 8ef2a5d..dbbd2ec 100644
--- a/quickstep/res/values-nl/strings.xml
+++ b/quickstep/res/values-nl/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Gesplitst scherm"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Vastzetten"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Vrije vorm"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overzicht"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Geen recente items"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Sluiten"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Instellingen voor app-gebruik"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Alles wissen"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Recente apps"</string>
 </resources>
diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml
index 6895ef5..60f7823 100644
--- a/quickstep/res/values-or/strings.xml
+++ b/quickstep/res/values-or/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ସ୍କ୍ରୀନ୍‌କୁ ଭାଗ କରନ୍ତୁ"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ପିନ୍‍"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"ଫ୍ରିଫର୍ମ"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ସଂକ୍ଷିପ୍ତ ବିବରଣ"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"କୌଣସି ସାମ୍ପ୍ରତିକ ଆଇଟମ୍ ନାହିଁ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ବନ୍ଦ କରନ୍ତୁ"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ଆପ୍‍ ବ୍ୟବହାର ସେଟିଂସ୍‍"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ସବୁ ଖାଲି କରନ୍ତୁ"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"ସାମ୍ପ୍ରତିକ ଆପ୍‌"</string>
 </resources>
diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml
index 4159c30..18b0468 100644
--- a/quickstep/res/values-pa/strings.xml
+++ b/quickstep/res/values-pa/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ਪਿੰਨ ਕਰੋ"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"ਫ੍ਰੀਫਾਰਮ"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ਰੂਪ-ਰੇਖਾ"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"ਕੋਈ ਹਾਲੀਆ ਆਈਟਮਾਂ ਨਹੀਂ"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ਬੰਦ ਕਰੋ"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ਐਪ ਵਰਤੋਂ ਦੀਆਂ ਸੈਟਿੰਗਾਂ"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ਸਭ ਕਲੀਅਰ ਕਰੋ"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"ਹਾਲੀਆ ਐਪਾਂ"</string>
 </resources>
diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml
index cf15abd..447cd60 100644
--- a/quickstep/res/values-pl/strings.xml
+++ b/quickstep/res/values-pl/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Podziel ekran"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Przypnij"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Tryb dowolny"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Przegląd"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Brak ostatnich elementów"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zamknij"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ustawienia użycia aplikacji"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Wyczyść wszystko"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Ostatnie aplikacje"</string>
 </resources>
diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml
index 36c7e3c..e7dfedf 100644
--- a/quickstep/res/values-pt-rPT/strings.xml
+++ b/quickstep/res/values-pt-rPT/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Ecrã dividido"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Forma livre"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Vista geral"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Fechar"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Definições de utilização de aplicações"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Limpar tudo"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplicações recentes"</string>
 </resources>
diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml
index 41f53f0..5ebd0bd 100644
--- a/quickstep/res/values-pt/strings.xml
+++ b/quickstep/res/values-pt/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Tela dividida"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixar"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Forma livre"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Visão geral"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Nenhum item recente"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Fechar"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Configurações de uso do app"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Limpar tudo"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Apps recentes"</string>
 </resources>
diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml
index 0c201ba..5d9887d 100644
--- a/quickstep/res/values-ro/strings.xml
+++ b/quickstep/res/values-ro/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Ecran împărțit"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fixați"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Formă liberă"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Recente"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Niciun element recent"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Închideți"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Setări de utilizare a aplicației"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ștergeți tot"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplicații recente"</string>
 </resources>
diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml
index 6a218fc..992683c 100644
--- a/quickstep/res/values-ru/strings.xml
+++ b/quickstep/res/values-ru/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Разделить экран"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Блокировать"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Произвольная форма"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Обзор"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Здесь пока ничего нет."</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Закрыть"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Настройки использования приложения"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Очистить все"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Недавние приложения"</string>
 </resources>
diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml
index c01211a..050a765 100644
--- a/quickstep/res/values-si/strings.xml
+++ b/quickstep/res/values-si/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"බෙදුම් තිරය"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"අමුණන්න"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"දළ විශ්ලේෂණය"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"මෑත අයිතම නැත"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"වසන්න"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"යෙදුම් භාවිත සැකසීම්"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"සියල්ල හිස් කරන්න"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"මෑත යෙදුම්"</string>
 </resources>
diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml
index 78e072b..510220b 100644
--- a/quickstep/res/values-sk/strings.xml
+++ b/quickstep/res/values-sk/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Rozdeliť obrazovku"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pripnúť"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Voľný režim"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Prehľad"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Žiadne nedávne položky"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zavrieť"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavenia využívania aplikácie"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Vymazať všetko"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Nedávne aplikácie"</string>
 </resources>
diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml
index 06eb95d..29d1eec 100644
--- a/quickstep/res/values-sl/strings.xml
+++ b/quickstep/res/values-sl/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Razdeljen zaslon"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Pripni"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Prosta oblika"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Pregled"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Ni nedavnih elementov"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Zapri"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Nastavitve uporabe aplikacij"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Počisti vse"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Nedavne aplikacije"</string>
 </resources>
diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml
index ef9afe0..f2c955c 100644
--- a/quickstep/res/values-sq/strings.xml
+++ b/quickstep/res/values-sq/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Ekrani i ndarë"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Gozhdo"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Formë e lirë"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Përmbledhja"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Nuk ka asnjë artikull të fundit"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Mbyll"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Cilësimet e përdorimit të aplikacionit"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Pastroji të gjitha"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Aplikacionet e fundit"</string>
 </resources>
diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml
index 0077ee2..e3837e7 100644
--- a/quickstep/res/values-sr/strings.xml
+++ b/quickstep/res/values-sr/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Подељени екран"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Закачи"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Слободни облик"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Преглед"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Нема недавних ставки"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Затвори"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Подешавања коришћења апликације"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Обриши све"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Недавне апликације"</string>
 </resources>
diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml
index f05d79f..4eda58c 100644
--- a/quickstep/res/values-sv/strings.xml
+++ b/quickstep/res/values-sv/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Delad skärm"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Fäst"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Fritt format"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Översikt"</string>
     <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="accessibility_app_usage_settings" msgid="6312864233673544149">"Inställningar för appanvändning"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Rensa alla"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Senaste apparna"</string>
 </resources>
diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml
index e6ce953..8888fef 100644
--- a/quickstep/res/values-sw/strings.xml
+++ b/quickstep/res/values-sw/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Gawa skrini"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Bandika"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Muundo huru"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Muhtasari"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Hakuna vipengee vya hivi karibuni"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Funga"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Mipangilio ya matumizi ya programu"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Ondoa zote"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Programu za hivi karibuni"</string>
 </resources>
diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml
index 19518e1..5187564 100644
--- a/quickstep/res/values-ta/strings.xml
+++ b/quickstep/res/values-ta/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"திரைப் பிரிப்பு"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"பின் செய்தல்"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"குறிப்பிட்ட வடிவமில்லாத பயன்முறை"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"மேலோட்டப் பார்வை"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"சமீபத்தியவை எதுவுமில்லை"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"மூடும்"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ஆப்ஸ் உபயோக அமைப்புகள்"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"எல்லாம் அழி"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"சமீபத்திய ஆப்ஸ்"</string>
 </resources>
diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml
index 4c0e5ac..ba9a558 100644
--- a/quickstep/res/values-te/strings.xml
+++ b/quickstep/res/values-te/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"స్క్రీన్‌ని విభజించు"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"పిన్ చేయి"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"సంప్రదాయేతర"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"అవలోకనం"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"ఇటీవలి అంశాలు ఏవీ లేవు"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"మూసివేయండి"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"యాప్ వినియోగ సెట్టింగ్‌లు"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"అన్నీ తీసివేయండి"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"ఇటీవలి యాప్‌లు"</string>
 </resources>
diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml
index 8dfda24..c3a9a81 100644
--- a/quickstep/res/values-th/strings.xml
+++ b/quickstep/res/values-th/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"แยกหน้าจอ"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"ตรึง"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"รูปแบบอิสระ"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"ภาพรวม"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"ไม่มีรายการล่าสุด"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"ปิด"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"การตั้งค่าการใช้แอป"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"ล้างทั้งหมด"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"แอปล่าสุด"</string>
 </resources>
diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml
index ab3cac9..6ceaf21 100644
--- a/quickstep/res/values-tl/strings.xml
+++ b/quickstep/res/values-tl/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Hatiin ang screen"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"I-pin"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Freeform"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Overview"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Walang kamakailang item"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Isara"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Mga setting ng paggamit ng app"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"I-clear lahat"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Mga kamakailang app"</string>
 </resources>
diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml
index 9693413..cbebb26 100644
--- a/quickstep/res/values-tr/strings.xml
+++ b/quickstep/res/values-tr/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Bölünmüş ekran"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Sabitle"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Serbest çalışma"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Genel bakış"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Yeni öğe yok"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Kapat"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Uygulama kullanım ayarları"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Tümünü temizle"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Son uygulamalar"</string>
 </resources>
diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml
index 2afcb31..b9666b2 100644
--- a/quickstep/res/values-uk/strings.xml
+++ b/quickstep/res/values-uk/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Розділити екран"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Закріпити"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Довільна форма"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Огляд"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Немає нещодавніх додатків"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Закрити"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Налаштування використання додатка"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Очистити все"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Нещодавні додатки"</string>
 </resources>
diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml
index f493a2f..69ff632 100644
--- a/quickstep/res/values-ur/strings.xml
+++ b/quickstep/res/values-ur/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"اسپلٹ اسکرین وضع"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"پن کریں"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"فری فارم"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"مجموعی جائزہ"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"کوئی حالیہ آئٹم نہیں"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"بند کریں"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"ایپ کے استعمال کی ترتیبات"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"سبھی کو صاف کریں"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"حالیہ ایپس"</string>
 </resources>
diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml
index 7a78e3b..9edb9a5 100644
--- a/quickstep/res/values-uz/strings.xml
+++ b/quickstep/res/values-uz/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Ekranni ikkiga ajratish"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Mahkamlash"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Erkin shakl"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Nazar"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Yaqinda ishlatilgan ilovalar yo‘q"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Yopish"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Ilovadan foydalanish sozlamalari"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Hammasini tozalash"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Yaqinda ishlatilgan ilovalar"</string>
 </resources>
diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml
index 406faf5..649e44d 100644
--- a/quickstep/res/values-vi/strings.xml
+++ b/quickstep/res/values-vi/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Chia đôi màn hình"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Ghim"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"Dạng tự do"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Tổng quan"</string>
     <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="accessibility_app_usage_settings" msgid="6312864233673544149">"Cài đặt mức sử dụng ứng dụng"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Xóa tất cả"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Ứng dụng gần đây"</string>
 </resources>
diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml
index 71ac114..b27931c 100644
--- a/quickstep/res/values-zh-rCN/strings.xml
+++ b/quickstep/res/values-zh-rCN/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"分屏"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"自由窗口"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"概览"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"近期没有任何内容"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"关闭"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"应用使用设置"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"最近用过的应用"</string>
 </resources>
diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml
index ab29a91..f8fe8de 100644
--- a/quickstep/res/values-zh-rHK/strings.xml
+++ b/quickstep/res/values-zh-rHK/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"分割畫面"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"自由形式"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"概覽"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"最近沒有任何項目"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"關閉"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"應用程式使用情況設定"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"最近使用的應用程式"</string>
 </resources>
diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml
index 1a9448c..ba51932 100644
--- a/quickstep/res/values-zh-rTW/strings.xml
+++ b/quickstep/res/values-zh-rTW/strings.xml
@@ -21,9 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"分割畫面"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"固定"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"自由形式"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"總覽"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"最近沒有任何項目"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"關閉"</string>
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"應用程式使用情況設定"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"全部清除"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"最近使用的應用程式"</string>
 </resources>
diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml
index afbc66f..d04a026 100644
--- a/quickstep/res/values-zu/strings.xml
+++ b/quickstep/res/values-zu/strings.xml
@@ -21,11 +21,11 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="recent_task_option_split_screen" msgid="5353188922202653570">"Hlukanisa isikrini"</string>
     <string name="recent_task_option_pin" msgid="7929860679018978258">"Phina"</string>
+    <string name="recent_task_option_freeform" msgid="48863056265284071">"I-Freeform"</string>
     <string name="accessibility_desc_recent_apps" msgid="1444379410873162882">"Buka konke"</string>
     <string name="recents_empty_message" msgid="7040467240571714191">"Azikho izinto zakamuva"</string>
     <string name="accessibility_close_task" msgid="5354563209433803643">"Vala"</string>
-    <!-- no translation found for accessibility_app_usage_settings (6312864233673544149) -->
-    <skip />
+    <string name="accessibility_app_usage_settings" msgid="6312864233673544149">"Izilungiselelo zokusetshenziswa kohlelo lokusebenza"</string>
     <string name="recents_clear_all" msgid="5328176793634888831">"Sula konke"</string>
     <string name="accessibility_recent_apps" msgid="4058661986695117371">"Izinhlelo zokusebenza zakamuva"</string>
 </resources>
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 49c4492..e0c4e4b 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -19,7 +19,7 @@
     <dimen name="task_thumbnail_top_margin">24dp</dimen>
     <dimen name="task_thumbnail_half_top_margin">12dp</dimen>
     <dimen name="task_thumbnail_icon_size">48dp</dimen>
-    <dimen name="task_corner_radius">2dp</dimen>
+    <dimen name="task_corner_radius">8dp</dimen>
     <dimen name="recents_page_spacing">10dp</dimen>
     <dimen name="recents_clear_all_deadzone_vertical_margin">70dp</dimen>
     <dimen name="quickscrub_adjacent_visible_width">20dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index c712703..7c47956 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -16,7 +16,7 @@
 * limitations under the License.
 */
 -->
-<resources>
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
 
     <!-- Application name -->
     <string name="derived_app_name" translatable="false">Quickstep</string>
@@ -26,6 +26,8 @@
     <string name="recent_task_option_split_screen">Split screen</string>
     <!-- Title for an option to keep an app pinned to the screen until it is unpinned -->
     <string name="recent_task_option_pin">Pin</string>
+    <!-- Title for an option to enter freeform mode for a given app -->
+    <string name="recent_task_option_freeform">Freeform</string>
 
     <!-- Content description for the recent apps panel (not shown on the screen). [CHAR LIMIT=NONE] -->
     <string name="accessibility_desc_recent_apps">Overview</string>
@@ -44,4 +46,24 @@
 
     <!-- Accessibility title for the list of recent apps [CHAR_LIMIT=none] -->
     <string name="accessibility_recent_apps">Recent apps</string>
+
+    <!-- Accessibility title for an app card in Recents for apps that have time limit set
+     [CHAR_LIMIT=none] -->
+    <string name="task_contents_description_with_remaining_time"><xliff:g id="task_description" example="GMail">%1$s</xliff:g>, <xliff:g id="remaining_time" example="7 minutes left today">%2$s</xliff:g></string>
+
+    <!-- Text to show total app usage per day if it is less than 1 minute ("&lt;" is the
+     escaped form of '<'). [CHAR LIMIT=10] -->
+    <string name="shorter_duration_less_than_one_minute">&lt; 1 minute</string>
+
+    <!-- Annotation shown on an app card in Recents, telling that the app was switched to a
+    grayscale because it ran over its time limit [CHAR LIMIT=25] -->
+    <string name="app_in_grayscale">App in grayscale</string>
+
+    <!-- Annotation shown on an app card in Recents, telling that the app has a usage limit set by
+    the user, and a given time is left for it today [CHAR LIMIT=20] -->
+    <string name="time_left_for_app"><xliff:g id="time" example="7 minutes">%1$s</xliff:g> left today</string>
+
+    <!-- Annotation shown on an app card in Recents, telling that the app is in a group that has a
+    usage limit set by the user, and a given time is left for the group today [CHAR LIMIT=20] -->
+    <string name="time_left_for_group"><xliff:g id="time" example="1 hour">%1$s</xliff:g> left for group</string>
 </resources>
\ No newline at end of file
diff --git a/quickstep/res/xml/indexable_launcher_prefs.xml b/quickstep/res/xml/indexable_launcher_prefs.xml
index 30f3100..c7e864f 100644
--- a/quickstep/res/xml/indexable_launcher_prefs.xml
+++ b/quickstep/res/xml/indexable_launcher_prefs.xml
@@ -29,13 +29,4 @@
         android:defaultValue="@bool/allow_rotation"
         android:persistent="true" />
 
-    <ListPreference
-        android:key="pref_override_icon_shape"
-        android:title="@string/icon_shape_override_label"
-        android:summary="@string/icon_shape_override_label_location"
-        android:entries="@array/icon_shape_override_paths_names"
-        android:entryValues="@array/icon_shape_override_paths_values"
-        android:defaultValue=""
-        android:persistent="false" />
-
 </PreferenceScreen>
diff --git a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
index d7bbfe0..264ad5a 100644
--- a/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/LauncherAppTransitionManagerImpl.java
@@ -67,6 +67,7 @@
 import com.android.launcher3.shortcuts.DeepShortcutView;
 import com.android.launcher3.util.MultiValueAlpha;
 import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
+import com.android.quickstep.RecentsModel;
 import com.android.quickstep.util.ClipAnimationHelper;
 import com.android.quickstep.util.MultiValueUpdateListener;
 import com.android.quickstep.util.RemoteAnimationProvider;
@@ -79,8 +80,8 @@
 import com.android.systemui.shared.system.RemoteAnimationDefinitionCompat;
 import com.android.systemui.shared.system.RemoteAnimationRunnerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier.SurfaceParams;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
 /**
@@ -203,10 +204,19 @@
                         mLauncher.getStateManager().setCurrentAnimation(anim);
 
                         Rect windowTargetBounds = getWindowTargetBounds(targetCompats);
-                        playIconAnimators(anim, v, windowTargetBounds);
+                        boolean isAllOpeningTargetTrs = true;
+                        for (int i = 0; i < targetCompats.length; i++) {
+                            RemoteAnimationTargetCompat target = targetCompats[i];
+                            if (target.mode == MODE_OPENING) {
+                                isAllOpeningTargetTrs &= target.isTranslucent;
+                            }
+                            if (!isAllOpeningTargetTrs) break;
+                        }
+                        playIconAnimators(anim, v, windowTargetBounds, !isAllOpeningTargetTrs);
                         if (launcherClosing) {
                             Pair<AnimatorSet, Runnable> launcherContentAnimator =
-                                    getLauncherContentAnimator(true /* isAppOpening */);
+                                    getLauncherContentAnimator(true /* isAppOpening */,
+                                            new float[] {0, mContentTransY});
                             anim.play(launcherContentAnimator.first);
                             anim.addListener(new AnimatorListenerAdapter() {
                                 @Override
@@ -292,7 +302,7 @@
                 ? RECENTS_QUICKSCRUB_LAUNCH_DURATION
                 : RECENTS_LAUNCH_DURATION;
 
-        ClipAnimationHelper helper = new ClipAnimationHelper();
+        ClipAnimationHelper helper = new ClipAnimationHelper(mLauncher);
         target.play(getRecentsWindowAnimator(taskView, skipLauncherChanges, targets, helper)
                 .setDuration(duration));
 
@@ -341,17 +351,16 @@
      *
      * @param isAppOpening True when this is called when an app is opening.
      *                     False when this is called when an app is closing.
+     * @param trans Array that contains the start and end translation values for the content.
      */
-    private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening) {
+    private Pair<AnimatorSet, Runnable> getLauncherContentAnimator(boolean isAppOpening,
+            float[] trans) {
         AnimatorSet launcherAnimator = new AnimatorSet();
         Runnable endListener;
 
         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(ALL_APPS)) {
             // All Apps in portrait mode is full screen, so we only animate AllAppsContainerView.
@@ -428,9 +437,19 @@
     /**
      * Animators for the "floating view" of the view used to launch the target.
      */
-    private void playIconAnimators(AnimatorSet appOpenAnimator, View v, Rect windowTargetBounds) {
+    private void playIconAnimators(AnimatorSet appOpenAnimator, View v, Rect windowTargetBounds,
+            boolean toggleVisibility) {
         final boolean isBubbleTextView = v instanceof BubbleTextView;
-        mFloatingView = new View(mLauncher);
+        if (mFloatingView == null) {
+            mFloatingView = new View(mLauncher);
+        } else {
+            mFloatingView.setTranslationX(0);
+            mFloatingView.setTranslationY(0);
+            mFloatingView.setScaleX(1);
+            mFloatingView.setScaleY(1);
+            mFloatingView.setAlpha(1);
+            mFloatingView.setBackground(null);
+        }
         if (isBubbleTextView && v.getTag() instanceof ItemInfoWithIcon ) {
             // Create a copy of the app icon
             mFloatingView.setBackground(DrawableFactory.INSTANCE.get(mLauncher)
@@ -468,20 +487,20 @@
                 : viewLocationLeft;
         LayoutParams lp = new LayoutParams(rect.width(), rect.height());
         lp.ignoreInsets = true;
-        lp.setMarginStart(viewLocationStart);
+        lp.leftMargin = viewLocationStart;
         lp.topMargin = viewLocationTop;
         mFloatingView.setLayoutParams(lp);
 
         // Set the properties here already to make sure they'are available when running the first
         // animation frame.
-        mFloatingView.setLeft(viewLocationLeft);
-        mFloatingView.setTop(viewLocationTop);
-        mFloatingView.setRight(viewLocationLeft + rect.width());
-        mFloatingView.setBottom(viewLocationTop + rect.height());
+        mFloatingView.layout(viewLocationLeft, viewLocationTop,
+                viewLocationLeft + rect.width(), viewLocationTop + rect.height());
 
         // Swap the two views in place.
-        ((ViewGroup) mDragLayer.getParent()).addView(mFloatingView);
-        v.setVisibility(View.INVISIBLE);
+        ((ViewGroup) mDragLayer.getParent()).getOverlay().add(mFloatingView);
+        if (toggleVisibility) {
+            v.setVisibility(View.INVISIBLE);
+        }
 
         int[] dragLayerBounds = new int[2];
         mDragLayer.getLocationOnScreen(dragLayerBounds);
@@ -547,7 +566,7 @@
                     ((BubbleTextView) v).setStayPressed(false);
                 }
                 v.setVisibility(View.VISIBLE);
-                ((ViewGroup) mDragLayer.getParent()).removeView(mFloatingView);
+                ((ViewGroup) mDragLayer.getParent()).getOverlay().remove(mFloatingView);
             }
         });
     }
@@ -576,8 +595,8 @@
                 MODE_OPENING);
         RemoteAnimationTargetSet closingTargets = new RemoteAnimationTargetSet(targets,
                 MODE_CLOSING);
-        SyncRtSurfaceTransactionApplier surfaceApplier = new SyncRtSurfaceTransactionApplier(
-                mFloatingView);
+        SyncRtSurfaceTransactionApplierCompat surfaceApplier =
+                new SyncRtSurfaceTransactionApplierCompat(mFloatingView);
 
         ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
         appAnimator.setDuration(APP_LAUNCH_DURATION);
@@ -611,6 +630,13 @@
                 float transX0 = floatingViewBounds[0] - offsetX;
                 float transY0 = floatingViewBounds[1] - offsetY;
 
+                // Animate window corner radius from 100% to windowCornerRadius.
+                float windowCornerRadius = RecentsModel.INSTANCE.get(mLauncher)
+                        .getWindowCornerRadius();
+                float circleRadius = iconWidth / 2f;
+                float windowRadius = Utilities.mapRange(easePercent, circleRadius,
+                        windowCornerRadius);
+
                 // Animate the window crop so that it starts off as a square, and then reveals
                 // horizontally.
                 float cropHeight = windowHeight * easePercent + windowWidth * (1 - easePercent);
@@ -625,20 +651,24 @@
                     RemoteAnimationTargetCompat target = targets[i];
 
                     Rect targetCrop;
-                    float alpha;
+                    final float alpha;
+                    final float cornerRadius;
                     if (target.mode == MODE_OPENING) {
                         matrix.setScale(scale, scale);
                         matrix.postTranslate(transX0, transY0);
                         targetCrop = crop;
                         alpha = mAlpha.value;
+                        cornerRadius = windowRadius;
                     } else {
                         matrix.setTranslate(target.position.x, target.position.y);
                         alpha = 1f;
                         targetCrop = target.sourceContainerBounds;
+                        cornerRadius = 0;
                     }
 
                     params[i] = new SurfaceParams(target.leash, alpha, matrix, targetCrop,
-                            RemoteAnimationProvider.getLayer(target, MODE_OPENING));
+                            RemoteAnimationProvider.getLayer(target, MODE_OPENING),
+                            cornerRadius);
                 }
                 surfaceApplier.scheduleApply(params);
             }
@@ -655,10 +685,13 @@
             RemoteAnimationDefinitionCompat definition = new RemoteAnimationDefinitionCompat();
             definition.addRemoteAnimation(WindowManagerWrapper.TRANSIT_WALLPAPER_OPEN,
                     WindowManagerWrapper.ACTIVITY_TYPE_STANDARD,
-                    new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(),
+                    new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(false /* fromUnlock */),
                             CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
 
-            // TODO: Transition for unlock to home TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER
+            definition.addRemoteAnimation(
+                    WindowManagerWrapper.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
+                    new RemoteAnimationAdapterCompat(getWallpaperOpenRunner(true /* fromUnlock */),
+                            CLOSING_TRANSITION_DURATION_MS, 0 /* statusBarTransitionDelay */));
             new ActivityCompat(mLauncher).registerRemoteAnimations(definition);
         }
     }
@@ -671,7 +704,7 @@
      * @return Runner that plays when user goes to Launcher
      *         ie. pressing home, swiping up from nav bar.
      */
-    private RemoteAnimationRunnerCompat getWallpaperOpenRunner() {
+    private RemoteAnimationRunnerCompat getWallpaperOpenRunner(boolean fromUnlock) {
         return new LauncherAnimationRunner(mHandler, false /* startAtFrontOfQueue */) {
             @Override
             public void onCreateAnimation(RemoteAnimationTargetCompat[] targetCompats,
@@ -697,7 +730,9 @@
 
                 if (anim == null) {
                     anim = new AnimatorSet();
-                    anim.play(getClosingWindowAnimators(targetCompats));
+                    anim.play(fromUnlock
+                            ? getUnlockWindowAnimator(targetCompats)
+                            : getClosingWindowAnimators(targetCompats));
 
                     // Normally, we run the launcher content animation when we are transitioning
                     // home, but if home is already visible, then we don't want to animate the
@@ -711,7 +746,21 @@
                             || mLauncher.isForceInvisible()) {
                         // Only register the content animation for cancellation when state changes
                         mLauncher.getStateManager().setCurrentAnimation(anim);
-                        createLauncherResumeAnimation(anim);
+                        if (fromUnlock) {
+                            Pair<AnimatorSet, Runnable> contentAnimator =
+                                    getLauncherContentAnimator(false /* isAppOpening */,
+                                            new float[] {mContentTransY, 0});
+                            contentAnimator.first.setStartDelay(0);
+                            anim.play(contentAnimator.first);
+                            anim.addListener(new AnimatorListenerAdapter() {
+                                @Override
+                                public void onAnimationEnd(Animator animation) {
+                                    contentAnimator.second.run();
+                                }
+                            });
+                        } else {
+                            createLauncherResumeAnimation(anim);
+                        }
                     }
                 }
 
@@ -722,14 +771,40 @@
     }
 
     /**
+     * Animator that controls the transformations of the windows when unlocking the device.
+     */
+    private Animator getUnlockWindowAnimator(RemoteAnimationTargetCompat[] targets) {
+        SyncRtSurfaceTransactionApplierCompat surfaceApplier =
+                new SyncRtSurfaceTransactionApplierCompat(mDragLayer);
+        ValueAnimator unlockAnimator = ValueAnimator.ofFloat(0, 1);
+        unlockAnimator.setDuration(CLOSING_TRANSITION_DURATION_MS);
+        float cornerRadius = RecentsModel.INSTANCE.get(mLauncher).getWindowCornerRadius();
+        unlockAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                SurfaceParams[] params = new SurfaceParams[targets.length];
+                for (int i = targets.length - 1; i >= 0; i--) {
+                    RemoteAnimationTargetCompat target = targets[i];
+                    params[i] = new SurfaceParams(target.leash, 1f, null,
+                            target.sourceContainerBounds,
+                            RemoteAnimationProvider.getLayer(target, MODE_OPENING), cornerRadius);
+                }
+                surfaceApplier.scheduleApply(params);
+            }
+        });
+        return unlockAnimator;
+    }
+
+    /**
      * Animator that controls the transformations of the windows the targets that are closing.
      */
     private Animator getClosingWindowAnimators(RemoteAnimationTargetCompat[] targets) {
-        SyncRtSurfaceTransactionApplier surfaceApplier =
-                new SyncRtSurfaceTransactionApplier(mDragLayer);
+        SyncRtSurfaceTransactionApplierCompat surfaceApplier =
+                new SyncRtSurfaceTransactionApplierCompat(mDragLayer);
         Matrix matrix = new Matrix();
         ValueAnimator closingAnimator = ValueAnimator.ofFloat(0, 1);
         int duration = CLOSING_TRANSITION_DURATION_MS;
+        float windowCornerRadius = RecentsModel.INSTANCE.get(mLauncher).getWindowCornerRadius();
         closingAnimator.setDuration(duration);
         closingAnimator.addUpdateListener(new MultiValueUpdateListener() {
             FloatProp mDy = new FloatProp(0, mClosingWindowTransY, 0, duration, DEACCEL_1_7);
@@ -741,7 +816,8 @@
                 SurfaceParams[] params = new SurfaceParams[targets.length];
                 for (int i = targets.length - 1; i >= 0; i--) {
                     RemoteAnimationTargetCompat target = targets[i];
-                    float alpha;
+                    final float alpha;
+                    final float cornerRadius;
                     if (target.mode == MODE_CLOSING) {
                         matrix.setScale(mScale.value, mScale.value,
                                 target.sourceContainerBounds.centerX(),
@@ -749,13 +825,16 @@
                         matrix.postTranslate(0, mDy.value);
                         matrix.postTranslate(target.position.x, target.position.y);
                         alpha = mAlpha.value;
+                        cornerRadius = windowCornerRadius;
                     } else {
                         matrix.setTranslate(target.position.x, target.position.y);
                         alpha = 1f;
+                        cornerRadius = 0f;
                     }
                     params[i] = new SurfaceParams(target.leash, alpha, matrix,
                             target.sourceContainerBounds,
-                            RemoteAnimationProvider.getLayer(target, MODE_CLOSING));
+                            RemoteAnimationProvider.getLayer(target, MODE_CLOSING),
+                            cornerRadius);
                 }
                 surfaceApplier.scheduleApply(params);
             }
@@ -770,7 +849,8 @@
     private void createLauncherResumeAnimation(AnimatorSet anim) {
         if (mLauncher.isInState(LauncherState.ALL_APPS)) {
             Pair<AnimatorSet, Runnable> contentAnimator =
-                    getLauncherContentAnimator(false /* isAppOpening */);
+                    getLauncherContentAnimator(false /* isAppOpening */,
+                            new float[] {-mContentTransY, 0});
             contentAnimator.first.setStartDelay(LAUNCHER_RESUME_START_DELAY);
             anim.play(contentAnimator.first);
             anim.addListener(new AnimatorListenerAdapter() {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
index 1906286..25e0af2 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/AllAppsState.java
@@ -18,6 +18,7 @@
 import static com.android.launcher3.AbstractFloatingView.TYPE_QUICKSTEP_PREVIEW;
 import static com.android.launcher3.LauncherAnimUtils.ALL_APPS_TRANSITION_MS;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Launcher;
@@ -45,7 +46,11 @@
 
     @Override
     public void onStateEnabled(Launcher launcher) {
-        AbstractFloatingView.closeAllOpenViewsExcept(launcher, TYPE_QUICKSTEP_PREVIEW);
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            AbstractFloatingView.closeAllOpenViews(launcher);
+        } else {
+            AbstractFloatingView.closeAllOpenViewsExcept(launcher, TYPE_QUICKSTEP_PREVIEW);
+        }
         dispatchWindowStateChanged(launcher);
     }
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/BackgroundAppState.java
index fdb13b1..8d28f33 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/BackgroundAppState.java
@@ -41,7 +41,8 @@
         if (launcher.getDeviceProfile().isVerticalBarLayout()) {
             return super.getVerticalProgress(launcher);
         }
-        int transitionLength = LayoutUtils.getShelfTrackingDistance(launcher.getDeviceProfile());
+        int transitionLength = LayoutUtils.getShelfTrackingDistance(launcher,
+                launcher.getDeviceProfile());
         AllAppsTransitionController controller = launcher.getAllAppsController();
         float scrollRange = Math.max(controller.getShiftRange(), 1);
         float progressDelta = (transitionLength / scrollRange);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
new file mode 100644
index 0000000..df9dbe4
--- /dev/null
+++ b/quickstep/src/com/android/launcher3/uioverrides/BaseRecentsViewStateController.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.uioverrides;
+
+import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+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 android.util.FloatProperty;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import androidx.annotation.NonNull;
+
+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.PropertySetter;
+
+/**
+ * State handler for recents view. Manages UI changes and animations for recents view based off the
+ * current {@link LauncherState}.
+ *
+ * @param <T> the recents view
+ */
+public abstract class BaseRecentsViewStateController<T extends View>
+        implements StateHandler {
+    protected final T mRecentsView;
+    protected final Launcher mLauncher;
+
+    public BaseRecentsViewStateController(@NonNull Launcher launcher) {
+        mLauncher = launcher;
+        mRecentsView = launcher.getOverviewPanel();
+    }
+
+    @Override
+    public void setState(@NonNull LauncherState state) {
+        float[] scaleTranslationYFactor = state.getOverviewScaleAndTranslationYFactor(mLauncher);
+        SCALE_PROPERTY.set(mRecentsView, scaleTranslationYFactor[0]);
+        getTranslationYFactorProperty().set(mRecentsView, scaleTranslationYFactor[1]);
+        getContentAlphaProperty().set(mRecentsView, state.overviewUi ? 1f : 0);
+    }
+
+    @Override
+    public final void setStateWithAnimation(@NonNull final LauncherState toState,
+            @NonNull AnimatorSetBuilder builder, @NonNull AnimationConfig config) {
+        if (!config.playAtomicComponent()) {
+            // The entire recents animation is played atomically.
+            return;
+        }
+        setStateWithAnimationInternal(toState, builder, config);
+    }
+
+    /**
+     * Core logic for animating the recents view UI.
+     *
+     * @param toState state to animate to
+     * @param builder animator set builder
+     * @param config current animation config
+     */
+    void setStateWithAnimationInternal(@NonNull final LauncherState toState,
+            @NonNull AnimatorSetBuilder builder, @NonNull AnimationConfig config) {
+        PropertySetter setter = config.getPropertySetter(builder);
+        float[] scaleTranslationYFactor = toState.getOverviewScaleAndTranslationYFactor(mLauncher);
+        Interpolator scaleAndTransYInterpolator = getScaleAndTransYInterpolator(toState, builder);
+        setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleTranslationYFactor[0],
+                scaleAndTransYInterpolator);
+        setter.setFloat(mRecentsView, getTranslationYFactorProperty(), scaleTranslationYFactor[1],
+                scaleAndTransYInterpolator);
+        setter.setFloat(mRecentsView, getContentAlphaProperty(), toState.overviewUi ? 1 : 0,
+                builder.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
+    }
+
+    /**
+     * Get the interpolator to use for the scale and translation Y animation for the view.
+     *
+     * @param toState state to animate to
+     * @param builder animator set builder
+     * @return interpolator for scale and trans Y recents view animation
+     */
+    Interpolator getScaleAndTransYInterpolator(@NonNull final LauncherState toState,
+            @NonNull AnimatorSetBuilder builder) {
+        return builder.getInterpolator(ANIM_OVERVIEW_SCALE, LINEAR);
+    }
+
+    /**
+     * Get property for translation Y factor for the recents view.
+     *
+     * @return the float property for the recents view
+     */
+    abstract FloatProperty getTranslationYFactorProperty();
+
+    /**
+     * Get property for content alpha for the recents view.
+     *
+     * @return the float property for the view's content alpha
+     */
+    abstract FloatProperty getContentAlphaProperty();
+}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
index 8f1d46c..de6f7a7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/OverviewState.java
@@ -18,6 +18,7 @@
 import static com.android.launcher3.AbstractFloatingView.TYPE_QUICKSTEP_PREVIEW;
 import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS;
 import static com.android.launcher3.anim.Interpolators.DEACCEL_2;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.launcher3.states.RotationHelper.REQUEST_ROTATE;
 
 import android.graphics.Rect;
@@ -75,7 +76,11 @@
     public void onStateEnabled(Launcher launcher) {
         RecentsView rv = launcher.getOverviewPanel();
         rv.setOverviewStateEnabled(true);
-        AbstractFloatingView.closeAllOpenViewsExcept(launcher, TYPE_QUICKSTEP_PREVIEW);
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            AbstractFloatingView.closeAllOpenViews(launcher);
+        } else {
+            AbstractFloatingView.closeAllOpenViewsExcept(launcher, TYPE_QUICKSTEP_PREVIEW);
+        }
     }
 
     @Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
index 8684c58..ea0e552 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PortraitStatesTouchController.java
@@ -47,8 +47,6 @@
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.TouchInteractionService;
 import com.android.quickstep.util.LayoutUtils;
-import com.android.quickstep.views.RecentsView;
-import com.android.quickstep.views.TaskView;
 
 /**
  * Touch controller for handling various state transitions in portrait UI.
@@ -67,14 +65,16 @@
      */
     private static final float RECENTS_FADE_THRESHOLD = 0.88f;
 
+    private final PortraitOverviewStateTouchHelper mOverviewPortraitStateTouchHelper;
+
     private InterpolatorWrapper mAllAppsInterpolatorWrapper = new InterpolatorWrapper();
 
     // If true, we will finish the current animation instantly on second touch.
     private boolean mFinishFastOnSecondTouch;
 
-
     public PortraitStatesTouchController(Launcher l) {
         super(l, SwipeDetector.VERTICAL);
+        mOverviewPortraitStateTouchHelper = new PortraitOverviewStateTouchHelper(l);
     }
 
     @Override
@@ -98,22 +98,18 @@
             }
             return false;
         }
-        RecentsView recentsView = mLauncher.getOverviewPanel();
         if (mLauncher.isInState(ALL_APPS)) {
             // In all-apps only listen if the container cannot scroll itself
             if (!mLauncher.getAppsView().shouldContainerScroll(ev)) {
                 return false;
             }
-        } else if (mLauncher.isInState(OVERVIEW) && recentsView.getChildCount() > 0) {
-            // Allow swiping up in the gap between the hotseat and overview.
-            if (ev.getY() < recentsView.getChildAt(0).getBottom()) {
+        } else if (mLauncher.isInState(OVERVIEW)) {
+            if (!mOverviewPortraitStateTouchHelper.canInterceptTouch(ev)) {
                 return false;
             }
         } else {
             // For all other states, only listen if the event originated below the hotseat height
-            DeviceProfile dp = mLauncher.getDeviceProfile();
-            int hotseatHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
-            if (ev.getY() < (mLauncher.getDragLayer().getHeight() - hotseatHeight)) {
+            if (!isTouchOverHotseat(mLauncher, ev)) {
                 return false;
             }
         }
@@ -197,13 +193,12 @@
 
         cancelPendingAnim();
 
-        RecentsView recentsView = mLauncher.getOverviewPanel();
-        TaskView taskView = recentsView.getTaskViewAt(recentsView.getNextPage());
-        if (recentsView.shouldSwipeDownLaunchApp() && mFromState == OVERVIEW && mToState == NORMAL
-                && taskView != null) {
+        if (mFromState == OVERVIEW && mToState == NORMAL
+                && mOverviewPortraitStateTouchHelper.shouldSwipeDownReturnToApp()) {
             // Reset the state manager, when changing the interaction mode
             mLauncher.getStateManager().goToState(OVERVIEW, false /* animate */);
-            mPendingAnimation = recentsView.createTaskLauncherAnimation(taskView, maxAccuracy);
+            mPendingAnimation = mOverviewPortraitStateTouchHelper
+                    .createSwipeDownToTaskAppAnimation(maxAccuracy);
             mPendingAnimation.anim.setInterpolator(Interpolators.LINEAR);
 
             Runnable onCancelRunnable = () -> {
@@ -213,7 +208,8 @@
             mCurrentAnimation = AnimatorPlaybackController.wrap(mPendingAnimation.anim, maxAccuracy,
                     onCancelRunnable);
             mLauncher.getStateManager().setCurrentUserControlledAnimation(mCurrentAnimation);
-            totalShift = LayoutUtils.getShelfTrackingDistance(mLauncher.getDeviceProfile());
+            totalShift = LayoutUtils.getShelfTrackingDistance(mLauncher,
+                    mLauncher.getDeviceProfile());
         } else {
             mCurrentAnimation = mLauncher.getStateManager()
                     .createAnimationToNewWorkspace(mToState, builder, maxAccuracy, this::clearState,
@@ -268,6 +264,19 @@
         }
     }
 
+    /**
+     * Whether the motion event is over the hotseat.
+     *
+     * @param launcher the launcher activity
+     * @param ev the event to check
+     * @return true if the event is over the hotseat
+     */
+    static boolean isTouchOverHotseat(Launcher launcher, MotionEvent ev) {
+        DeviceProfile dp = launcher.getDeviceProfile();
+        int hotseatHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
+        return (ev.getY() >= (launcher.getDragLayer().getHeight() - hotseatHeight));
+    }
+
     private static class InterpolatorWrapper implements Interpolator {
 
         public TimeInterpolator baseInterpolator = LINEAR;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
deleted file mode 100644
index abd2846..0000000
--- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.uioverrides;
-
-import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
-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.CONTENT_ALPHA;
-
-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;
-
-@TargetApi(Build.VERSION_CODES.O)
-public class RecentsViewStateController implements StateHandler {
-
-    private final Launcher mLauncher;
-    private final LauncherRecentsView mRecentsView;
-
-    public RecentsViewStateController(Launcher launcher) {
-        mLauncher = launcher;
-        mRecentsView = launcher.getOverviewPanel();
-    }
-
-    @Override
-    public void setState(LauncherState state) {
-        mRecentsView.setContentAlpha(state.overviewUi ? 1 : 0);
-        float[] scaleTranslationYFactor = state.getOverviewScaleAndTranslationYFactor(mLauncher);
-        SCALE_PROPERTY.set(mRecentsView, scaleTranslationYFactor[0]);
-        mRecentsView.setTranslationYFactor(scaleTranslationYFactor[1]);
-        if (state.overviewUi) {
-            mRecentsView.updateEmptyMessage();
-            mRecentsView.resetTaskVisuals();
-        }
-    }
-
-    @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);
-        Interpolator scaleAndTransYInterpolator = builder.getInterpolator(
-                ANIM_OVERVIEW_SCALE, LINEAR);
-        if (mLauncher.getStateManager().getState() == OVERVIEW && toState == FAST_OVERVIEW) {
-            scaleAndTransYInterpolator = Interpolators.clampToProgress(
-                    QUICK_SCRUB_START_INTERPOLATOR, 0, QUICK_SCRUB_TRANSLATION_Y_FACTOR);
-        }
-        setter.setFloat(mRecentsView, SCALE_PROPERTY, scaleTranslationYFactor[0],
-                scaleAndTransYInterpolator);
-        setter.setFloat(mRecentsView, TRANSLATION_Y_FACTOR, scaleTranslationYFactor[1],
-                scaleAndTransYInterpolator);
-        setter.setFloat(mRecentsView, CONTENT_ALPHA, toState.overviewUi ? 1 : 0,
-                builder.getInterpolator(ANIM_OVERVIEW_FADE, AGGRESSIVE_EASE_IN_OUT));
-
-        if (!toState.overviewUi) {
-            builder.addOnFinishRunnable(mRecentsView::resetTaskVisuals);
-        }
-
-        if (toState.overviewUi) {
-            ValueAnimator updateAnim = ValueAnimator.ofFloat(0, 1);
-            updateAnim.addUpdateListener(valueAnimator -> {
-                // While animating into recents, update the visible task data as needed
-                mRecentsView.loadVisibleTaskData();
-            });
-            updateAnim.setDuration(config.duration);
-            builder.play(updateAnim);
-            mRecentsView.updateEmptyMessage();
-        }
-    }
-}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
index 54269f09..50af4a1 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/TaskViewTouchController.java
@@ -18,6 +18,7 @@
 import static com.android.launcher3.AbstractFloatingView.TYPE_ACCESSIBLE;
 import static com.android.launcher3.Utilities.SINGLE_FRAME_MS;
 import static com.android.launcher3.anim.Interpolators.scrollInterpolatorForVelocity;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -49,7 +50,7 @@
     private static final String TAG = "OverviewSwipeController";
 
     // 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;
+    public static final float SUCCESS_TRANSITION_PROGRESS = 0.5f;
 
     protected final T mActivity;
     private final SwipeDetector mDetector;
@@ -231,6 +232,12 @@
             mFlingBlockCheck.onEvent();
         }
         mCurrentAnimation.setPlayFraction(totalDisplacement * mProgressMultiplier);
+
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            if (mRecentsView.getCurrentPage() != 0 || isGoingUp) {
+                mRecentsView.redrawLiveTile(true);
+            }
+        }
         return true;
     }
 
@@ -243,7 +250,7 @@
             fling = false;
         }
         float progress = mCurrentAnimation.getProgressFraction();
-        float interpolatedProgress = mCurrentAnimation.getInterpolator().getInterpolation(progress);
+        float interpolatedProgress = mCurrentAnimation.getInterpolatedProgress();
         if (fling) {
             logAction = Touch.FLING;
             boolean goingUp = velocity < 0;
@@ -267,6 +274,13 @@
         anim.setFloatValues(nextFrameProgress, goingToEnd ? 1f : 0f);
         anim.setDuration(animationDuration);
         anim.setInterpolator(scrollInterpolatorForVelocity(velocity));
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            anim.addUpdateListener(valueAnimator -> {
+                if (mRecentsView.getCurrentPage() != 0 || mCurrentAnimationIsGoingUp) {
+                    mRecentsView.redrawLiveTile(true);
+                }
+            });
+        }
         anim.start();
     }
 
diff --git a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
index 4e79fed..3aa6482 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/UiFactory.java
@@ -16,10 +16,8 @@
 
 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.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;
@@ -41,13 +39,13 @@
 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.config.FeatureFlags;
 import com.android.launcher3.util.TouchController;
+import com.android.launcher3.util.UiThreadHelper;
+import com.android.launcher3.util.UiThreadHelper.AsyncCommand;
 import com.android.quickstep.OverviewInteractionState;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.util.RemoteFadeOutAnimationListener;
-import com.android.quickstep.views.RecentsView;
 import com.android.systemui.shared.system.ActivityCompat;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
@@ -58,6 +56,9 @@
 
 public class UiFactory {
 
+    private static final AsyncCommand SET_SHELF_HEIGHT_CMD = (visible, height) ->
+            WindowManagerWrapper.getInstance().setShelfHeight(visible != 0, height);
+
     public static TouchController[] createTouchControllers(Launcher launcher) {
         boolean swipeUpEnabled = OverviewInteractionState.INSTANCE.get(launcher)
                 .isSwipeUpGestureEnabled();
@@ -78,7 +79,11 @@
                 && !launcher.getDeviceProfile().isVerticalBarLayout()) {
             list.add(new StatusBarTouchController(launcher));
         }
-        list.add(new LauncherTaskViewController(launcher));
+        TouchController taskSwipeController =
+                RecentsUiFactory.createTaskSwipeController(launcher);
+        if (taskSwipeController != null) {
+            list.add(taskSwipeController);
+        }
         return list.toArray(new TouchController[list.size()]);
     }
 
@@ -88,7 +93,8 @@
 
     public static StateHandler[] getStateHandler(Launcher launcher) {
         return new StateHandler[] {launcher.getAllAppsController(), launcher.getWorkspace(),
-                new RecentsViewStateController(launcher), new BackButtonAlphaHandler(launcher)};
+                RecentsUiFactory.createRecentsViewStateController(launcher),
+                new BackButtonAlphaHandler(launcher)};
     }
 
     /**
@@ -108,8 +114,7 @@
     }
 
     public static void resetOverview(Launcher launcher) {
-        RecentsView recents = launcher.getOverviewPanel();
-        recents.reset();
+        RecentsUiFactory.resetRecents(launcher);
     }
 
     public static void onCreate(Launcher launcher) {
@@ -175,15 +180,13 @@
         LauncherState state = launcher.getStateManager().getState();
         if (!OverviewInteractionState.INSTANCE.get(launcher).swipeGestureInitializing()) {
             DeviceProfile profile = launcher.getDeviceProfile();
-            WindowManagerWrapper.getInstance().setShelfHeight(
-                    (state == NORMAL || state == OVERVIEW) && launcher.isUserActive()
-                            && !profile.isVerticalBarLayout(),
-                    profile.hotseatBarSizePx);
+            boolean visible = (state == NORMAL || state == OVERVIEW) && launcher.isUserActive()
+                    && !profile.isVerticalBarLayout();
+            UiThreadHelper.runAsyncCommand(launcher, SET_SHELF_HEIGHT_CMD,
+                    visible ? 1 : 0, profile.hotseatBarSizePx);
         }
 
-        if (state == NORMAL) {
-            launcher.<RecentsView>getOverviewPanel().setSwipeDownShouldLaunchApp(false);
-        }
+        RecentsUiFactory.onLauncherStateOrResumeChanged(launcher);
     }
 
     public static void onTrimMemory(Context context, int level) {
@@ -237,26 +240,6 @@
     }
 
     public static void prepareToShowOverview(Launcher launcher) {
-        RecentsView overview = launcher.getOverviewPanel();
-        if (overview.getVisibility() != VISIBLE || overview.getContentAlpha() == 0) {
-            SCALE_PROPERTY.set(overview, 1.33f);
-        }
-    }
-
-    private static class LauncherTaskViewController extends TaskViewTouchController<Launcher> {
-
-        public LauncherTaskViewController(Launcher activity) {
-            super(activity);
-        }
-
-        @Override
-        protected boolean isRecentsInteractive() {
-            return mActivity.isInState(OVERVIEW);
-        }
-
-        @Override
-        protected void onUserControlledAnimationCreated(AnimatorPlaybackController animController) {
-            mActivity.getStateManager().setCurrentUserControlledAnimation(animController);
-        }
+        RecentsUiFactory.prepareToShowRecents(launcher);
     }
 }
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
index eaf4183..5afeca7 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
@@ -34,7 +34,16 @@
     }
 
     @Override
-    public void setEnabled(ComponentName component, boolean enabled) {
+    public void setEnabled(ComponentName component) {
+        setState(component, true);
+    }
+
+    @Override
+    public void setDisabled(ComponentName component, int reason) {
+        setState(component, reason == ENABLED);
+    }
+
+    private void setState(ComponentName component, boolean enabled) {
         putBoolean(pluginEnabledKey(component), enabled);
     }
 
@@ -44,6 +53,11 @@
     }
 
     @Override
+    public int getDisableReason(ComponentName componentName) {
+        return isEnabled(componentName) ? ENABLED : DISABLED_MANUALLY;
+    }
+
+    @Override
     public void putBoolean(String key, boolean value) {
         mSharedPrefs.edit().putBoolean(key, value).apply();
     }
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 85eed1f..c3df9c7 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -21,7 +21,7 @@
 import static com.android.launcher3.LauncherState.BACKGROUND_APP;
 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.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS_SPRING;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
 import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
@@ -44,6 +44,8 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.view.View;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
 
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
@@ -53,9 +55,9 @@
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
 import com.android.launcher3.TestProtocol;
-import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.SpringObjectAnimator;
 import com.android.launcher3.compat.AccessibilityManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dragndrop.DragLayer;
@@ -77,9 +79,6 @@
 import java.util.function.BiPredicate;
 import java.util.function.Consumer;
 
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-
 /**
  * Utility class which abstracts out the logical differences between Launcher and RecentsActivity.
  */
@@ -114,6 +113,11 @@
     @Nullable
     T getCreatedActivity();
 
+    default boolean isResumed() {
+        BaseDraggingActivity activity = getCreatedActivity();
+        return activity != null && activity.hasBeenResumed();
+    }
+
     @UiThread
     @Nullable
     RecentsView getVisibleRecentsView();
@@ -145,21 +149,34 @@
      */
     int getContainerType();
 
+    boolean isInLiveTileMode();
+
     class LauncherActivityControllerHelper implements ActivityControlHelper<Launcher> {
 
         @Override
         public LayoutListener createLayoutListener(Launcher activity) {
-            return new LauncherLayoutListener(activity);
+            return LauncherLayoutListener.resetAndGet(activity);
         }
 
         @Override
         public void onQuickInteractionStart(Launcher activity, RunningTaskInfo taskInfo,
                 boolean activityVisible, TouchInteractionLog touchInteractionLog) {
             LauncherState fromState = activity.getStateManager().getState();
-            activity.getStateManager().goToState(FAST_OVERVIEW, activityVisible);
-
             QuickScrubController controller = activity.<RecentsView>getOverviewPanel()
                     .getQuickScrubController();
+            boolean isQuickSwitch = controller.isQuickSwitch();
+            boolean animate = activityVisible;
+            if (isQuickSwitch && fromState == FAST_OVERVIEW && !animate) {
+                // We can already be in FAST_OVERVIEW if createActivityController() was called
+                // before us. This could happen, for instance, when launcher is slow to load when
+                // starting quick switch, causing us to call onQuickScrubStart() on the background
+                // thread. In this case, we also hadn't set isQuickSwitch = true before setting
+                // FAST_OVERVIEW, so we need to reapply FAST_OVERVIEW to take that into account.
+                activity.getStateManager().reapplyState();
+            } else {
+                activity.getStateManager().goToState(FAST_OVERVIEW, animate);
+            }
+
             controller.onQuickScrubStart(activityVisible && !fromState.overviewUi, this,
                     touchInteractionLog);
 
@@ -177,7 +194,7 @@
             int topMargin = context.getResources()
                     .getDimensionPixelSize(R.dimen.task_thumbnail_top_margin);
             int paddingTop = targetRect.rect.top - topMargin - dp.getInsets().top;
-            int paddingBottom = dp.availableHeightPx + dp.getInsets().top - targetRect.rect.bottom;
+            int paddingBottom = dp.heightPx - dp.getInsets().bottom - targetRect.rect.bottom;
 
             return FastOverviewState.OVERVIEW_TRANSLATION_FACTOR * (paddingBottom - paddingTop);
         }
@@ -200,7 +217,7 @@
                 int hotseatInset = dp.isSeascape() ? targetInsets.left : targetInsets.right;
                 return dp.hotseatBarSizePx + hotseatInset;
             } else {
-                return LayoutUtils.getShelfTrackingDistance(dp);
+                return LayoutUtils.getShelfTrackingDistance(context, dp);
             }
         }
 
@@ -279,8 +296,9 @@
 
             AnimatorSet anim = new AnimatorSet();
             if (!activity.getDeviceProfile().isVerticalBarLayout()) {
-                AllAppsTransitionController controller = activity.getAllAppsController();
-                ObjectAnimator shiftAnim = ObjectAnimator.ofFloat(controller, ALL_APPS_PROGRESS,
+                Animator shiftAnim = new SpringObjectAnimator<>(activity.getAllAppsController(),
+                        ALL_APPS_PROGRESS_SPRING, "allAppsSpringFromACH",
+                        activity.getAllAppsController().getShiftRange(),
                         fromState.getVerticalProgress(activity),
                         endState.getVerticalProgress(activity));
                 shiftAnim.setInterpolator(LINEAR);
@@ -297,9 +315,10 @@
                     AnimatorPlaybackController.wrap(anim, transitionLength * 2);
 
             // Since we are changing the start position of the UI, reapply the state, at the end
-            controller.setEndAction(() ->
+            controller.setEndAction(() -> {
                 activity.getStateManager().goToState(
-                        controller.getProgressFraction() > 0.5 ? endState : fromState, false));
+                        controller.getInterpolatedProgress() > 0.5 ? endState : fromState, false);
+            });
             callback.accept(controller);
         }
 
@@ -320,7 +339,7 @@
             float prevRvScale = recentsView.getScaleX();
             float targetRvScale = endState.getOverviewScaleAndTranslationYFactor(launcher)[0];
             SCALE_PROPERTY.set(recentsView, targetRvScale);
-            ClipAnimationHelper clipHelper = new ClipAnimationHelper();
+            ClipAnimationHelper clipHelper = new ClipAnimationHelper(launcher);
             clipHelper.fromTaskThumbnailView(v.getThumbnail(), (RecentsView) v.getParent(), null);
             SCALE_PROPERTY.set(recentsView, prevRvScale);
 
@@ -425,6 +444,13 @@
             return launcher != null ? launcher.getStateManager().getState().containerType
                     : LauncherLogProto.ContainerType.APP;
         }
+
+        @Override
+        public boolean isInLiveTileMode() {
+            Launcher launcher = getCreatedActivity();
+            return launcher != null && launcher.getStateManager().getState() == OVERVIEW &&
+                    launcher.isStarted();
+        }
     }
 
     class FallbackActivityControllerHelper implements ActivityControlHelper<RecentsActivity> {
@@ -541,7 +567,8 @@
                 public void finish() { }
 
                 @Override
-                public void update(boolean shouldFinish, boolean isLongSwipe, RectF currentRect) { }
+                public void update(boolean shouldFinish, boolean isLongSwipe, RectF currentRect,
+                        float cornerRadius) { }
             };
         }
 
@@ -609,6 +636,11 @@
         public int getContainerType() {
             return LauncherLogProto.ContainerType.SIDELOADED_LAUNCHER;
         }
+
+        @Override
+        public boolean isInLiveTileMode() {
+            return false;
+        }
     }
 
     interface LayoutListener {
@@ -619,7 +651,8 @@
 
         void finish();
 
-        void update(boolean shouldFinish, boolean isLongSwipe, RectF currentRect);
+        void update(boolean shouldFinish, boolean isLongSwipe, RectF currentRect,
+                float cornerRadius);
     }
 
     interface ActivityInitListener {
diff --git a/quickstep/src/com/android/quickstep/LauncherSearchIndexablesProvider.java b/quickstep/src/com/android/quickstep/LauncherSearchIndexablesProvider.java
index f5e1f6e..5d6fbe2 100644
--- a/quickstep/src/com/android/quickstep/LauncherSearchIndexablesProvider.java
+++ b/quickstep/src/com/android/quickstep/LauncherSearchIndexablesProvider.java
@@ -29,7 +29,6 @@
 import android.util.Xml;
 
 import com.android.launcher3.R;
-import com.android.launcher3.graphics.IconShapeOverride;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -88,8 +87,6 @@
             } catch (IOException |XmlPullParserException e) {
                 throw new RuntimeException(e);
             }
-        } else if (!IconShapeOverride.isSupported(getContext())) {
-            cursor.addRow(new String[] {IconShapeOverride.KEY_PREFERENCE});
         }
         return cursor;
     }
diff --git a/quickstep/src/com/android/quickstep/LongSwipeHelper.java b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
index 16214dd..80d37ae 100644
--- a/quickstep/src/com/android/quickstep/LongSwipeHelper.java
+++ b/quickstep/src/com/android/quickstep/LongSwipeHelper.java
@@ -19,6 +19,7 @@
 import static com.android.launcher3.LauncherState.ALL_APPS;
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
 import static com.android.quickstep.WindowTransformSwipeHandler.MAX_SWIPE_DURATION;
 import static com.android.quickstep.WindowTransformSwipeHandler.MIN_OVERSHOOT_DURATION;
 
@@ -41,7 +42,6 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.util.FlingBlockCheck;
 import com.android.quickstep.views.RecentsView;
-import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
 
 /**
  * Utility class to handle long swipe from an app.
@@ -113,7 +113,7 @@
                     * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
             duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
 
-            if (blockedFling && !toAllApps) {
+            if (blockedFling && !toAllApps && !QUICKSTEP_SPRINGS.get()) {
                 Interpolators.OvershootParams overshoot = new OvershootParams(currentFraction,
                         currentFraction, endProgress, velocityPxPerMs, (int) mMaxSwipeDistance);
                 duration = (overshoot.duration + duration);
@@ -145,7 +145,12 @@
         ValueAnimator animator = mAnimator.getAnimationPlayer();
         animator.setDuration(duration).setInterpolator(interpolator);
         animator.setFloatValues(currentFraction, endProgress);
-        animator.start();
+
+        if (QUICKSTEP_SPRINGS.get()) {
+            mAnimator.dispatchOnStartWithVelocity(endProgress, velocityPxPerMs);
+        } else {
+            animator.start();
+        }
     }
 
     private void onSwipeAnimationComplete(boolean toAllApps, boolean isFling, Runnable callback) {
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index b11260e..9712eb3 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -21,9 +21,9 @@
 import static android.view.MotionEvent.ACTION_POINTER_UP;
 import static android.view.MotionEvent.ACTION_UP;
 import static android.view.MotionEvent.INVALID_POINTER_ID;
-
-import static com.android.systemui.shared.system.ActivityManagerWrapper
-        .CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+import static com.android.launcher3.util.RaceConditionTracker.ENTER;
+import static com.android.launcher3.util.RaceConditionTracker.EXIT;
+import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
 import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
 
 import android.annotation.TargetApi;
@@ -47,6 +47,7 @@
 import android.view.WindowManager;
 
 import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.util.RaceConditionTracker;
 import com.android.launcher3.util.TraceHelper;
 import com.android.quickstep.util.RemoteAnimationTargetSet;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -70,6 +71,7 @@
 public class OtherActivityTouchConsumer extends ContextWrapper implements TouchConsumer {
 
     private static final long LAUNCHER_DRAW_TIMEOUT_MS = 150;
+    public static final String DOWN_EVT = "OtherActivityTouchConsumer.DOWN";
 
     private final SparseArray<RecentsAnimationState> mAnimationStates = new SparseArray<>();
     private final RunningTaskInfo mRunningTask;
@@ -97,7 +99,7 @@
 
     private VelocityTracker mVelocityTracker;
     private MotionEventQueue mEventQueue;
-    private boolean mIsGoingToHome;
+    private boolean mIsGoingToLauncher;
 
     public OtherActivityTouchConsumer(Context base, RunningTaskInfo runningTaskInfo,
             RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
@@ -135,6 +137,7 @@
         mTouchInteractionLog.addMotionEvent(ev);
         switch (ev.getActionMasked()) {
             case ACTION_DOWN: {
+                RaceConditionTracker.onEvent(DOWN_EVT, ENTER);
                 TraceHelper.beginSection("TouchInt");
                 mActivePointerId = ev.getPointerId(0);
                 mDownPos.set(ev.getX(), ev.getY());
@@ -151,6 +154,7 @@
                 Display display = getSystemService(WindowManager.class).getDefaultDisplay();
                 mDisplayRotation = display.getRotation();
                 WindowManagerWrapper.getInstance().getStableInsets(mStableInsets);
+                RaceConditionTracker.onEvent(DOWN_EVT, EXIT);
                 break;
             }
             case ACTION_POINTER_UP: {
@@ -186,7 +190,7 @@
 
                 if (mPassedInitialSlop && mInteractionHandler != null) {
                     // Move
-                    mInteractionHandler.updateDisplacement(displacement - mStartDisplacement);
+                    dispatchMotion(ev, displacement - mStartDisplacement);
                 }
                 break;
             }
@@ -201,6 +205,14 @@
         }
     }
 
+    private void dispatchMotion(MotionEvent ev, float displacement) {
+        mInteractionHandler.updateDisplacement(displacement);
+        boolean isLandscape = isNavBarOnLeft() || isNavBarOnRight();
+        if (!isLandscape) {
+            mInteractionHandler.dispatchMotionEventToRecentsView(ev);
+        }
+    }
+
     private void notifyGestureStarted() {
         if (mInteractionHandler == null) {
             return;
@@ -291,15 +303,16 @@
      */
     private void finishTouchTracking(MotionEvent ev) {
         if (mPassedInitialSlop && mInteractionHandler != null) {
-            mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement);
+            dispatchMotion(ev, getDisplacement(ev) - mStartDisplacement);
 
             mVelocityTracker.computeCurrentVelocity(1000,
                     ViewConfiguration.get(this).getScaledMaximumFlingVelocity());
 
-            float velocity = isNavBarOnRight() ? mVelocityTracker.getXVelocity(mActivePointerId)
-                    : isNavBarOnLeft() ? -mVelocityTracker.getXVelocity(mActivePointerId)
+            float velocityX = mVelocityTracker.getXVelocity(mActivePointerId);
+            float velocity = isNavBarOnRight() ? velocityX
+                    : isNavBarOnLeft() ? -velocityX
                             : mVelocityTracker.getYVelocity(mActivePointerId);
-            mInteractionHandler.onGestureEnded(velocity);
+            mInteractionHandler.onGestureEnded(velocity, velocityX);
         } else {
             // Since we start touch tracking on DOWN, we may reach this state without actually
             // starting the gesture. In that case, just cleanup immediately.
@@ -320,7 +333,7 @@
         if (mInteractionHandler != null) {
             final WindowTransformSwipeHandler handler = mInteractionHandler;
             mInteractionHandler = null;
-            mIsGoingToHome = handler.mIsGoingToHome;
+            mIsGoingToLauncher = handler.mIsGoingToRecents;
             mMainThreadExecutor.execute(handler::reset);
         }
     }
@@ -370,9 +383,9 @@
             // Deferred gesture, start the animation and gesture tracking once we pass the actual
             // touch slop
             startTouchTrackingForWindowAnimation(ev.getEventTime());
-            mPassedInitialSlop = true;
-            mStartDisplacement = getDisplacement(ev);
         }
+        mPassedInitialSlop = true;
+        mStartDisplacement = getDisplacement(ev);
         notifyGestureStarted();
     }
 
@@ -404,7 +417,7 @@
 
     @Override
     public boolean forceToLauncherConsumer() {
-        return mIsGoingToHome;
+        return mIsGoingToLauncher;
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
index f8f0905..9bbe57a 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java
@@ -66,7 +66,7 @@
 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.SyncRtSurfaceTransactionApplier;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
 import com.android.systemui.shared.system.TransactionCompat;
 
 import java.util.ArrayList;
@@ -326,7 +326,7 @@
                 return anim;
             }
 
-            final ClipAnimationHelper clipHelper = new ClipAnimationHelper();
+            final ClipAnimationHelper clipHelper = new ClipAnimationHelper(mActivity);
 
             // At this point, the activity is already started and laid-out. Get the home-bounds
             // relative to the screen using the rootView of the activity.
@@ -343,14 +343,15 @@
             clipHelper.updateTargetRect(targetRect);
             clipHelper.prepareAnimation(false /* isOpening */);
 
-            SyncRtSurfaceTransactionApplier syncTransactionApplier =
-                    new SyncRtSurfaceTransactionApplier(rootView);
+            ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams()
+                    .setSyncTransactionApplier(new SyncRtSurfaceTransactionApplierCompat(rootView));
             ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1);
             valueAnimator.setDuration(RECENTS_LAUNCH_DURATION);
             valueAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
-            valueAnimator.addUpdateListener((v) ->
-                    clipHelper.applyTransform(targetSet, (float) v.getAnimatedValue(),
-                            syncTransactionApplier));
+            valueAnimator.addUpdateListener((v) -> {
+                params.setProgress((float) v.getAnimatedValue());
+                clipHelper.applyTransform(targetSet, params);
+            });
 
             if (targetSet.isAnimatingHome()) {
                 // If we are animating home, fade in the opening targets
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index c44ccd3..db0150e 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -21,6 +21,8 @@
 import static com.android.launcher3.anim.Interpolators.DEACCEL_3;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_TASK_STABILIZER;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -123,14 +125,22 @@
         mActivityControlHelper = controlHelper;
         mTouchInteractionLog = touchInteractionLog;
 
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            if (mRecentsView.getRunningTaskView() != null) {
+                mRecentsView.getRunningTaskView().setShowScreenshot(false);
+            }
+        }
+
         if (mIsQuickSwitch) {
             mShouldSwitchToNext = true;
             mPrevProgressDelta = 0;
-            if (mRecentsView.getTaskViewCount() > 0) {
-                mRecentsView.getTaskViewAt(0).setFullscreen(true);
+            TaskView runningTaskView = mRecentsView.getRunningTaskView();
+            TaskView nextTaskView = mRecentsView.getNextTaskView();
+            if (runningTaskView != null) {
+                runningTaskView.setFullscreenProgress(1);
             }
-            if (mRecentsView.getTaskViewCount() > 1) {
-                mRecentsView.getTaskViewAt(1).setFullscreen(true);
+            if (nextTaskView != null) {
+                nextTaskView.setFullscreenProgress(1);
             }
         }
 
@@ -161,11 +171,13 @@
                     mWaitingForTaskLaunch = false;
                     if (mIsQuickSwitch) {
                         mIsQuickSwitch = false;
-                        if (mRecentsView.getTaskViewCount() > 0) {
-                            mRecentsView.getTaskViewAt(0).setFullscreen(false);
+                        TaskView runningTaskView = mRecentsView.getRunningTaskView();
+                        TaskView nextTaskView = mRecentsView.getNextTaskView();
+                        if (runningTaskView != null) {
+                            runningTaskView.setFullscreenProgress(0);
                         }
-                        if (mRecentsView.getTaskViewCount() > 1) {
-                            mRecentsView.getTaskViewAt(1).setFullscreen(false);
+                        if (nextTaskView != null) {
+                            nextTaskView.setFullscreenProgress(0);
                         }
                     }
 
@@ -267,12 +279,12 @@
 
     public void onQuickScrubProgress(float progress) {
         if (mIsQuickSwitch) {
-            TaskView currentPage = mRecentsView.getTaskViewAt(0);
-            TaskView nextPage = mRecentsView.getTaskViewAt(1);
+            TaskView currentPage = mRecentsView.getRunningTaskView();
+            TaskView nextPage = mRecentsView.getNextTaskView();
             if (currentPage == null || nextPage == null) {
                 return;
             }
-            if (!mFinishedTransitionToQuickScrub) {
+            if (!mFinishedTransitionToQuickScrub || mStartProgress <= 0) {
                 mStartProgress = mEndProgress = progress;
             } else {
                 float progressDelta = progress - mEndProgress;
@@ -285,16 +297,20 @@
                 }
                 mPrevPrevProgressDelta = mPrevProgressDelta;
                 mPrevProgressDelta = progressDelta;
-                float scrollDiff = nextPage.getWidth() + mRecentsView.getPageSpacing();
-                int scrollDir = mRecentsView.isRtl() ? -1 : 1;
-                int linearScrollDiff = (int) (progress * scrollDiff * scrollDir);
-                float accelScrollDiff = ACCEL.getInterpolation(progress) * scrollDiff * scrollDir;
+                int startScroll = mRecentsView.getScrollForPage(
+                        mRecentsView.indexOfChild(currentPage));
+                int scrollDiff = mRecentsView.getScrollForPage(mRecentsView.indexOfChild(nextPage))
+                        - startScroll;
+
+                int linearScrollDiff = (int) (progress * scrollDiff);
                 currentPage.setZoomScale(1 - DEACCEL_3.getInterpolation(progress)
                         * TaskView.EDGE_SCALE_DOWN_FACTOR);
-                currentPage.setTranslationX(linearScrollDiff + accelScrollDiff);
+                if (!ENABLE_TASK_STABILIZER.get()) {
+                    float accelScrollDiff = ACCEL.getInterpolation(progress) * scrollDiff;
+                    currentPage.setTranslationX(linearScrollDiff + accelScrollDiff);
+                }
                 nextPage.setTranslationZ(1);
                 nextPage.setTranslationY(currentPage.getTranslationY());
-                int startScroll = mRecentsView.isRtl() ? mRecentsView.getMaxScrollX() : 0;
                 mRecentsView.setScrollX(startScroll + linearScrollDiff);
             }
             return;
@@ -333,6 +349,7 @@
         if (action != null) {
             action.run();
         }
+        mRecentsView.setEnableDrawingLiveTile(true);
     }
 
     public void onTaskRemoved(int taskId) {
@@ -354,9 +371,16 @@
                     : mStartedFromHome
                         ? QUICK_SCRUB_FROM_HOME_START_DURATION
                         : QUICK_SCRUB_FROM_APP_START_DURATION;
-            int pageToGoTo = mStartedFromHome || mIsQuickSwitch
-                    ? 0
-                    : mRecentsView.getNextPage() + 1;
+            final int pageToGoTo;
+            if (mStartedFromHome) {
+                pageToGoTo = 0;
+            } else if (mIsQuickSwitch) {
+                TaskView tv = mRecentsView.getRunningTaskView();
+                pageToGoTo = tv != null ? mRecentsView.indexOfChild(tv)
+                        : mRecentsView.getNextPage();
+            } else {
+                pageToGoTo = mRecentsView.getNextPage() + 1;
+            }
             goToPageWithHaptic(pageToGoTo, duration, true /* forceHaptic */,
                     QUICK_SCRUB_START_INTERPOLATOR);
         }
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index fec38bf..cedd952 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -16,8 +16,10 @@
 
 package com.android.quickstep;
 
+import android.annotation.TargetApi;
 import android.app.ActivityManager;
 import android.content.Context;
+import android.os.Build;
 import android.os.Process;
 import android.util.SparseBooleanArray;
 import com.android.launcher3.MainThreadExecutor;
@@ -36,16 +38,20 @@
 /**
  * Manages the recent task list from the system, caching it as necessary.
  */
+@TargetApi(Build.VERSION_CODES.P)
 public class RecentTasksList extends TaskStackChangeListener {
 
     private final KeyguardManagerCompat mKeyguardManager;
     private final MainThreadExecutor mMainThreadExecutor;
     private final BackgroundExecutor mBgThreadExecutor;
+    private final TaskListStabilizer mStabilizer = new TaskListStabilizer();
 
     // The list change id, increments as the task list changes in the system
     private int mChangeId;
     // The last change id when the list was last loaded completely, must be <= the list change id
     private int mLastLoadedId;
+    // The last change id was loaded with keysOnly  = true
+    private boolean mLastLoadHadKeysOnly;
 
     ArrayList<Task> mTasks = new ArrayList<>();
 
@@ -57,41 +63,43 @@
     }
 
     /**
-     * Asynchronously fetches the list of recent tasks.
+     * Fetches the task keys skipping any local cache.
+     */
+    public void getTaskKeys(int numTasks, Consumer<ArrayList<Task>> callback) {
+        // Kick off task loading in the background
+        mBgThreadExecutor.submit(() -> {
+            ArrayList<Task> tasks = loadTasksInBackground(numTasks, true /* loadKeysOnly */);
+            mMainThreadExecutor.execute(() -> callback.accept(tasks));
+        });
+    }
+
+    /**
+     * Asynchronously fetches the list of recent tasks, reusing cached list if available.
      *
-     * @param numTasks The maximum number of tasks to fetch
      * @param loadKeysOnly Whether to load other associated task data, or just the key
      * @param callback The callback to receive the list of recent tasks
      * @return The change id of the current task list
      */
-    public synchronized int getTasks(int numTasks, boolean loadKeysOnly,
-            Consumer<ArrayList<Task>> callback) {
+    public synchronized int getTasks(boolean loadKeysOnly, Consumer<ArrayList<Task>> callback) {
         final int requestLoadId = mChangeId;
-        final int numLoadTasks = numTasks > 0
-                ? numTasks
-                : Integer.MAX_VALUE;
+        Runnable resultCallback = callback == null
+                ? () -> { }
+                : () -> callback.accept(mStabilizer.reorder(mTasks));
 
-        if (mLastLoadedId == mChangeId) {
+        if (mLastLoadedId == mChangeId && (!mLastLoadHadKeysOnly || loadKeysOnly)) {
             // The list is up to date, callback with the same list
-            mMainThreadExecutor.execute(() -> {
-                if (callback != null) {
-                    callback.accept(mTasks);
-                }
-            });
+            mMainThreadExecutor.execute(resultCallback);
         }
 
         // Kick off task loading in the background
         mBgThreadExecutor.submit(() -> {
-            ArrayList<Task> tasks = loadTasksInBackground(numLoadTasks,
-                    loadKeysOnly);
+            ArrayList<Task> tasks = loadTasksInBackground(Integer.MAX_VALUE, loadKeysOnly);
 
             mMainThreadExecutor.execute(() -> {
                 mTasks = tasks;
                 mLastLoadedId = requestLoadId;
-
-                if (callback != null) {
-                    callback.accept(tasks);
-                }
+                mLastLoadHadKeysOnly = loadKeysOnly;
+                resultCallback.run();
             });
         });
 
diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java
index ef735e1..deedd32 100644
--- a/quickstep/src/com/android/quickstep/RecentsActivity.java
+++ b/quickstep/src/com/android/quickstep/RecentsActivity.java
@@ -44,7 +44,6 @@
 import com.android.launcher3.LauncherAnimationRunner;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.badge.BadgeInfo;
 import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.util.SystemUiController;
 import com.android.launcher3.util.Themes;
@@ -156,11 +155,6 @@
     }
 
     @Override
-    public BadgeInfo getBadgeInfoForItem(ItemInfo info) {
-        return null;
-    }
-
-    @Override
     public ActivityOptions getActivityLaunchOptions(final View v) {
         if (!(v instanceof TaskView)) {
             return null;
@@ -189,7 +183,7 @@
             RemoteAnimationTargetCompat[] targets) {
         AnimatorSet target = new AnimatorSet();
         boolean activityClosing = taskIsATargetWithMode(targets, getTaskId(), MODE_CLOSING);
-        ClipAnimationHelper helper = new ClipAnimationHelper();
+        ClipAnimationHelper helper = new ClipAnimationHelper(this);
         target.play(getRecentsWindowAnimator(taskView, !activityClosing, targets, helper)
                 .setDuration(RECENTS_LAUNCH_DURATION));
 
@@ -211,9 +205,6 @@
     }
 
     @Override
-    public void invalidateParent(ItemInfo info) { }
-
-    @Override
     protected void onStart() {
         // Set the alpha to 1 before calling super, as it may get set back to 0 due to
         // onActivityStart callback.
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
index 2f3cb5f..60bd9fb 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationWrapper.java
@@ -97,11 +97,11 @@
     }
 
     /**
-     * @param onFinishComplete A callback that runs after the animation controller has finished
-     *                         on the background thread.
+     * @param onFinishComplete A callback that runs on the main thread after the animation
+     *                         controller has finished on the background thread.
      */
-    public void finish(boolean toHome, Runnable onFinishComplete) {
-        if (!toHome) {
+    public void finish(boolean toRecents, Runnable onFinishComplete) {
+        if (!toRecents) {
             mExecutorService.submit(() -> finishBg(false, onFinishComplete));
             return;
         }
@@ -119,16 +119,17 @@
         });
     }
 
-    protected void finishBg(boolean toHome, Runnable onFinishComplete) {
+    protected void finishBg(boolean toRecents, Runnable onFinishComplete) {
         RecentsAnimationControllerCompat controller = mController;
         mController = null;
-        TraceHelper.endSection("RecentsController", "Finish " + controller + ", toHome=" + toHome);
+        TraceHelper.endSection("RecentsController", "Finish " + controller
+                + ", toRecents=" + toRecents);
         if (controller != null) {
             controller.setInputConsumerEnabled(false);
-            controller.finish(toHome);
+            controller.finish(toRecents);
 
             if (onFinishComplete != null) {
-                onFinishComplete.run();
+                mMainThreadExecutor.execute(onFinishComplete);
             }
         }
     }
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 2e4d4d2..442b106 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -45,6 +45,9 @@
  */
 @TargetApi(Build.VERSION_CODES.O)
 public class RecentsModel extends TaskStackChangeListener {
+
+    private static final String TAG = "RecentsModel";
+
     // We do not need any synchronization for this variable as its only written on UI thread.
     public static final MainThreadInitializedObject<RecentsModel> INSTANCE =
             new MainThreadInitializedObject<>(c -> new RecentsModel(c));
@@ -62,6 +65,8 @@
     private final TaskIconCache mIconCache;
     private final TaskThumbnailCache mThumbnailCache;
 
+    private float mWindowCornerRadius = -1;
+
     private RecentsModel(Context context) {
         mContext = context;
 
@@ -92,7 +97,7 @@
      * @return the request id associated with this call.
      */
     public int getTasks(Consumer<ArrayList<Task>> callback) {
-        return mTaskList.getTasks(-1, false /* loadKeysOnly */, callback);
+        return mTaskList.getTasks(false /* loadKeysOnly */, callback);
     }
 
     /**
@@ -118,7 +123,7 @@
      *                 called on the UI thread.
      */
     public void findTaskWithId(int taskId, Consumer<Task.TaskKey> callback) {
-        mTaskList.getTasks(-1, true /* loadKeysOnly */, (tasks) -> {
+        mTaskList.getTasks(true /* loadKeysOnly */, (tasks) -> {
             for (Task task : tasks) {
                 if (task.key.id == taskId) {
                     callback.accept(task.key);
@@ -144,7 +149,7 @@
 
         // Keep the cache up to date with the latest thumbnails
         int runningTaskId = RecentsModel.getRunningTaskId();
-        mTaskList.getTasks(mThumbnailCache.getCacheSize(), true /* keysOnly */, (tasks) -> {
+        mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), tasks -> {
             for (Task task : tasks) {
                 if (task.key.id == runningTaskId) {
                     // Skip the running task, it's not going to have an up-to-date snapshot by the
@@ -174,6 +179,26 @@
         return mSystemUiProxy;
     }
 
+    public float getWindowCornerRadius() {
+        // The window corner radius is expressed in pixels and won't change if the
+        // display density changes. It's safe to cache the value.
+        if (mWindowCornerRadius == -1) {
+            if (mSystemUiProxy != null) {
+                try {
+                    mWindowCornerRadius = mSystemUiProxy.getWindowCornerRadius();
+                } catch (RemoteException e) {
+                    Log.w(TAG, "Connection to ISystemUIProxy was lost, ignoring window corner "
+                            + "radius");
+                    return 0;
+                }
+            } else {
+                Log.w(TAG, "ISystemUIProxy is null, ignoring window corner radius");
+                return 0;
+            }
+        }
+        return mWindowCornerRadius;
+    }
+
     public void onTrimMemory(int level) {
         if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
             mThumbnailCache.getHighResLoadingState().setVisible(false);
diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java
index afa58fa..612c00e 100644
--- a/quickstep/src/com/android/quickstep/TaskIconCache.java
+++ b/quickstep/src/com/android/quickstep/TaskIconCache.java
@@ -27,7 +27,7 @@
 import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.icons.HandlerRunnable;
+import com.android.launcher3.icons.cache.HandlerRunnable;
 import com.android.launcher3.util.Preconditions;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.model.TaskKeyLruCache;
diff --git a/quickstep/src/com/android/quickstep/TaskListStabilizer.java b/quickstep/src/com/android/quickstep/TaskListStabilizer.java
new file mode 100644
index 0000000..3eb26b4
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TaskListStabilizer.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import static com.android.launcher3.config.FeatureFlags.ENABLE_TASK_STABILIZER;
+
+import android.app.ActivityManager.RecentTaskInfo;
+import android.content.ComponentName;
+import android.os.Process;
+import android.os.SystemClock;
+import android.util.Log;
+
+import com.android.launcher3.util.IntArray;
+import com.android.systemui.shared.recents.model.Task;
+import com.android.systemui.shared.recents.model.Task.TaskKey;
+import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.TaskStackChangeListener;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class TaskListStabilizer {
+
+    private static final long TASK_CACHE_TIMEOUT_MS = 5000;
+
+    private static final int INVALID_TASK_ID = -1;
+
+    private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
+
+        @Override
+        public void onTaskCreated(int taskId, ComponentName componentName) {
+            onTaskCreatedInternal(taskId);
+        }
+
+        @Override
+        public void onTaskMovedToFront(int taskId) {
+            onTaskMovedToFrontInternal(taskId);
+        }
+
+        @Override
+        public void onTaskRemoved(int taskId) {
+            onTaskRemovedInternal(taskId);
+        }
+    };
+
+    // Task ids ordered based on recency, 0th index is the latest task
+    private final IntArray mOrderedTaskIds;
+
+    // Wrapper objects used for sorting tasks
+    private final ArrayList<TaskWrapper> mTaskWrappers = new ArrayList<>();
+
+    // Information about recent task re-order which has not been applied yet
+    private int mScheduledMoveTaskId = INVALID_TASK_ID;
+    private long mScheduledMoveTime = 0;
+
+    public TaskListStabilizer() {
+        if (ENABLE_TASK_STABILIZER.get()) {
+            // Initialize the task ids map
+            List<RecentTaskInfo> rawTasks = ActivityManagerWrapper.getInstance().getRecentTasks(
+                    Integer.MAX_VALUE, Process.myUserHandle().getIdentifier());
+            mOrderedTaskIds = new IntArray(rawTasks.size());
+            for (RecentTaskInfo info : rawTasks) {
+                mOrderedTaskIds.add(new TaskKey(info).id);
+            }
+
+            ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
+        } else {
+            mOrderedTaskIds = null;
+        }
+    }
+
+    private synchronized void onTaskCreatedInternal(int taskId) {
+        applyScheduledMoveUnchecked();
+        mOrderedTaskIds.add(taskId);
+    }
+
+    private synchronized void onTaskRemovedInternal(int taskId) {
+        applyScheduledMoveUnchecked();
+        mOrderedTaskIds.removeValue(taskId);
+    }
+
+    private void applyScheduledMoveUnchecked() {
+        if (mScheduledMoveTaskId != INVALID_TASK_ID) {
+            // Mode the scheduled task to front
+            mOrderedTaskIds.removeValue(mScheduledMoveTaskId);
+            mOrderedTaskIds.add(mScheduledMoveTaskId);
+            mScheduledMoveTaskId = INVALID_TASK_ID;
+        }
+    }
+
+    /**
+     * Checks if the scheduled move has timed out and moves the task to front accordingly.
+     */
+    private void applyScheduledMoveIfTime() {
+        if (mScheduledMoveTaskId != INVALID_TASK_ID
+                && (SystemClock.uptimeMillis() - mScheduledMoveTime) > TASK_CACHE_TIMEOUT_MS) {
+            applyScheduledMoveUnchecked();
+        }
+    }
+
+    private synchronized void onTaskMovedToFrontInternal(int taskId) {
+        applyScheduledMoveIfTime();
+        mScheduledMoveTaskId = taskId;
+        mScheduledMoveTime = SystemClock.uptimeMillis();
+    }
+
+
+    public synchronized ArrayList<Task> reorder(ArrayList<Task> tasks) {
+        if (!ENABLE_TASK_STABILIZER.get()) {
+            return tasks;
+        }
+
+        applyScheduledMoveIfTime();
+
+        // Ensure that we have enough wrappers
+        int taskCount = tasks.size();
+        for (int i = taskCount - mTaskWrappers.size(); i > 0; i--) {
+            mTaskWrappers.add(new TaskWrapper());
+        }
+
+        List<TaskWrapper> listToSort = mTaskWrappers.size() == taskCount
+                ? mTaskWrappers : mTaskWrappers.subList(0, taskCount);
+        int missingTaskIndex = -taskCount;
+
+        for (int i = 0; i < taskCount; i++){
+            TaskWrapper wrapper = listToSort.get(i);
+            wrapper.task = tasks.get(i);
+            wrapper.index = mOrderedTaskIds.indexOf(wrapper.task.key.id);
+
+            // Ensure that missing tasks are put in the front, in the order they appear in the
+            // original list
+            if (wrapper.index < 0) {
+                wrapper.index = missingTaskIndex;
+                missingTaskIndex++;
+            }
+        }
+        Collections.sort(listToSort);
+
+        ArrayList<Task> result = new ArrayList<>(taskCount);
+        for (int i = 0; i < taskCount; i++) {
+            result.add(listToSort.get(i).task);
+        }
+        return result;
+    }
+
+    private static class TaskWrapper implements Comparable<TaskWrapper> {
+        Task task;
+        int index;
+
+        @Override
+        public int compareTo(TaskWrapper other) {
+            return Integer.compare(index, other.index);
+        }
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
index 59a937f..cc49d46 100644
--- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
+++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java
@@ -16,16 +16,13 @@
 
 package com.android.quickstep;
 
-import android.content.Context;
 import android.graphics.Matrix;
 import android.view.View;
 
-import androidx.annotation.AnyThread;
-
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.R;
-import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.util.MainThreadInitializedObject;
 import com.android.launcher3.util.ResourceBasedOverride;
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.Task;
@@ -34,11 +31,12 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import androidx.annotation.AnyThread;
+
 /**
  * Factory class to create and add an overlays on the TaskView
  */
 public class TaskOverlayFactory implements ResourceBasedOverride {
-    private static TaskOverlayFactory sInstance;
 
     /** Note that these will be shown in order from top to bottom, if available for the task. */
     private static final TaskSystemShortcut[] MENU_OPTIONS = new TaskSystemShortcut[]{
@@ -46,16 +44,12 @@
             new TaskSystemShortcut.SplitScreen(),
             new TaskSystemShortcut.Pin(),
             new TaskSystemShortcut.Install(),
+            new TaskSystemShortcut.Freeform()
     };
 
-    public static TaskOverlayFactory get(Context context) {
-        Preconditions.assertUIThread();
-        if (sInstance == null) {
-            sInstance = Overrides.getObject(TaskOverlayFactory.class,
-                    context.getApplicationContext(), R.string.task_overlay_factory_class);
-        }
-        return sInstance;
-    }
+    public static final MainThreadInitializedObject<TaskOverlayFactory> INSTANCE =
+            new MainThreadInitializedObject<>(c -> Overrides.getObject(TaskOverlayFactory.class,
+                    c, R.string.task_overlay_factory_class));
 
     @AnyThread
     public boolean needAssist() {
diff --git a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
index a8eb321..42a28fb 100644
--- a/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
+++ b/quickstep/src/com/android/quickstep/TaskSystemShortcut.java
@@ -18,6 +18,8 @@
 
 import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
 
+import android.app.Activity;
+import android.app.ActivityOptions;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.graphics.Bitmap;
@@ -33,6 +35,8 @@
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.ItemInfo;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.popup.SystemShortcut;
@@ -46,6 +50,7 @@
 import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecCompat;
 import com.android.systemui.shared.recents.view.AppTransitionAnimationSpecsFuture;
 import com.android.systemui.shared.recents.view.RecentsTransition;
+import com.android.systemui.shared.system.ActivityCompat;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.ActivityOptionsCompat;
 import com.android.systemui.shared.system.WindowManagerWrapper;
@@ -102,19 +107,23 @@
         }
     }
 
-    public static class SplitScreen extends TaskSystemShortcut {
+    public static abstract class MultiWindow extends TaskSystemShortcut {
 
         private Handler mHandler;
 
-        public SplitScreen() {
-            super(R.drawable.ic_split_screen, R.string.recent_task_option_split_screen);
+        public MultiWindow(int iconRes, int textRes) {
+            super(iconRes, textRes);
             mHandler = new Handler(Looper.getMainLooper());
         }
 
+        protected abstract boolean isAvailable(BaseDraggingActivity activity);
+        protected abstract ActivityOptions makeLaunchOptions(Activity activity);
+        protected abstract boolean onActivityStarted(BaseDraggingActivity activity);
+
         @Override
         public View.OnClickListener getOnClickListener(
                 BaseDraggingActivity activity, TaskView taskView) {
-            if (activity.getDeviceProfile().isMultiWindowMode) {
+            if (!isAvailable(activity)) {
                 return null;
             }
             final Task task  = taskView.getTask();
@@ -153,22 +162,13 @@
 
                 dismissTaskMenuView(activity);
 
-                final int navBarPosition = WindowManagerWrapper.getInstance().getNavBarPosition();
-                if (navBarPosition == WindowManagerWrapper.NAV_BAR_POS_INVALID) {
-                    return;
-                }
-                boolean dockTopOrLeft = navBarPosition != WindowManagerWrapper.NAV_BAR_POS_LEFT;
-                if (ActivityManagerWrapper.getInstance().startActivityFromRecents(taskId,
-                        ActivityOptionsCompat.makeSplitScreenOptions(dockTopOrLeft))) {
-                    ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(activity).getSystemUiProxy();
-                    try {
-                        sysUiProxy.onSplitScreenInvoked();
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "Failed to notify SysUI of split screen: ", e);
+                ActivityOptions options = makeLaunchOptions(activity);
+                if (options != null
+                        && ActivityManagerWrapper.getInstance().startActivityFromRecents(taskId,
+                                options)) {
+                    if (!onActivityStarted(activity)) {
                         return;
                     }
-                    activity.getUserEventDispatcher().logActionOnControl(TAP,
-                            LauncherLogProto.ControlType.SPLIT_SCREEN_TARGET);
                     // Add a device profile change listener to kick off animating the side tasks
                     // once we enter multiwindow mode and relayout
                     activity.addOnDeviceProfileChangeListener(onDeviceProfileChangeListener);
@@ -205,12 +205,73 @@
                         }
                     };
                     WindowManagerWrapper.getInstance().overridePendingAppTransitionMultiThumbFuture(
-                            future, animStartedListener, mHandler, true /* scaleUp */);
+                            future, animStartedListener, mHandler, true /* scaleUp */,
+                            v.getDisplay().getDisplayId());
                 }
             });
         }
     }
 
+    public static class SplitScreen extends MultiWindow {
+        public SplitScreen() {
+            super(R.drawable.ic_split_screen, R.string.recent_task_option_split_screen);
+        }
+
+        @Override
+        protected boolean isAvailable(BaseDraggingActivity activity) {
+            // Don't show menu-item if already in multi-window
+            return !activity.getDeviceProfile().isMultiWindowMode;
+        }
+
+        @Override
+        protected ActivityOptions makeLaunchOptions(Activity activity) {
+            final ActivityCompat act = new ActivityCompat(activity);
+            final int navBarPosition = WindowManagerWrapper.getInstance().getNavBarPosition(
+                    act.getDisplayId());
+            if (navBarPosition == WindowManagerWrapper.NAV_BAR_POS_INVALID) {
+                return null;
+            }
+            boolean dockTopOrLeft = navBarPosition != WindowManagerWrapper.NAV_BAR_POS_LEFT;
+            return ActivityOptionsCompat.makeSplitScreenOptions(dockTopOrLeft);
+        }
+
+        @Override
+        protected boolean onActivityStarted(BaseDraggingActivity activity) {
+            ISystemUiProxy sysUiProxy = RecentsModel.INSTANCE.get(activity).getSystemUiProxy();
+            try {
+                sysUiProxy.onSplitScreenInvoked();
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failed to notify SysUI of split screen: ", e);
+                return false;
+            }
+            activity.getUserEventDispatcher().logActionOnControl(TAP,
+                    LauncherLogProto.ControlType.SPLIT_SCREEN_TARGET);
+            return true;
+        }
+    }
+
+    public static class Freeform extends MultiWindow {
+        public Freeform() {
+            super(R.drawable.ic_split_screen, R.string.recent_task_option_freeform);
+        }
+
+        @Override
+        protected boolean isAvailable(BaseDraggingActivity activity) {
+            return ActivityManagerWrapper.getInstance().supportsFreeformMultiWindow(activity);
+        }
+
+        @Override
+        protected ActivityOptions makeLaunchOptions(Activity activity) {
+            return ActivityOptionsCompat.makeFreeformOptions();
+        }
+
+        @Override
+        protected boolean onActivityStarted(BaseDraggingActivity activity) {
+            Launcher.getLauncher(activity).getStateManager().goToState(LauncherState.NORMAL);
+            return true;
+        }
+    }
+
     public static class Pin extends TaskSystemShortcut {
 
         private static final String TAG = Pin.class.getSimpleName();
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
index 61a191f..7a216ed 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
@@ -23,7 +23,7 @@
 import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.icons.HandlerRunnable;
+import com.android.launcher3.icons.cache.HandlerRunnable;
 import com.android.launcher3.util.Preconditions;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.model.TaskKeyLruCache;
diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java
index 5cae2b9..c2777e7 100644
--- a/quickstep/src/com/android/quickstep/TaskUtils.java
+++ b/quickstep/src/com/android/quickstep/TaskUtils.java
@@ -43,7 +43,7 @@
 import com.android.quickstep.views.TaskView;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
 
 import java.util.List;
 
@@ -59,7 +59,6 @@
      */
     public static CharSequence getTitle(Context context, Task task) {
         LauncherAppsCompat launcherAppsCompat = LauncherAppsCompat.getInstance(context);
-        UserManagerCompat userManagerCompat = UserManagerCompat.getInstance(context);
         PackageManager packageManager = context.getPackageManager();
         UserHandle user = UserHandle.of(task.key.userId);
         ApplicationInfo applicationInfo = launcherAppsCompat.getApplicationInfo(
@@ -68,7 +67,7 @@
             Log.e(TAG, "Failed to get title for task " + task);
             return "";
         }
-        return userManagerCompat.getBadgedLabelForUser(
+        return packageManager.getUserBadgedLabel(
             applicationInfo.loadLabel(packageManager), user);
     }
 
@@ -146,8 +145,9 @@
      */
     public static ValueAnimator getRecentsWindowAnimator(TaskView v, boolean skipViewChanges,
             RemoteAnimationTargetCompat[] targets, final ClipAnimationHelper inOutHelper) {
-        SyncRtSurfaceTransactionApplier syncTransactionApplier =
-                new SyncRtSurfaceTransactionApplier(v);
+        ClipAnimationHelper.TransformParams params = new ClipAnimationHelper.TransformParams()
+                .setSyncTransactionApplier(new SyncRtSurfaceTransactionApplierCompat(v));
+        
         final ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1);
         appAnimator.setInterpolator(TOUCH_RESPONSE_INTERPOLATOR);
         appAnimator.addUpdateListener(new MultiValueUpdateListener() {
@@ -175,8 +175,8 @@
 
             @Override
             public void onUpdate(float percent) {
-                RectF taskBounds = inOutHelper.applyTransform(mTargetSet, 1 - percent,
-                        syncTransactionApplier);
+                params.setProgress(1 - percent);
+                RectF taskBounds = inOutHelper.applyTransform(mTargetSet, params);
                 if (!skipViewChanges) {
                     float scale = taskBounds.width() / mThumbnailRect.width();
                     v.setScaleX(scale);
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index b1a214d..8b6867f 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -22,6 +22,7 @@
 import static android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT;
 import static android.view.MotionEvent.ACTION_UP;
 
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.systemui.shared.system.ActivityManagerWrapper
         .CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
@@ -202,7 +203,7 @@
         mEventQueue = new MotionEventQueue(mMainThreadChoreographer, TouchConsumer.NO_OP);
         mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this);
         mOverviewCallbacks = OverviewCallbacks.get(this);
-        mTaskOverlayFactory = TaskOverlayFactory.get(this);
+        mTaskOverlayFactory = TaskOverlayFactory.INSTANCE.get(this);
         mTouchInteractionLog = new TouchInteractionLog();
         mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer();
         mInputConsumer.registerInputConsumer();
@@ -249,18 +250,23 @@
         if (runningTaskInfo == null && !forceToLauncher) {
             return TouchConsumer.NO_OP;
         } else if (forceToLauncher ||
-                runningTaskInfo.topActivity.equals(mOverviewCommandHelper.overviewComponent)) {
+                mOverviewCommandHelper.getActivityControlHelper().isResumed()) {
             return OverviewTouchConsumer.newInstance(
                     mOverviewCommandHelper.getActivityControlHelper(), false, mTouchInteractionLog);
+        } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
+                mOverviewCommandHelper.getActivityControlHelper().isInLiveTileMode()) {
+            return OverviewTouchConsumer.newInstance(
+                    mOverviewCommandHelper.getActivityControlHelper(), false, mTouchInteractionLog,
+                    false /* waitForWindowAvailable */);
         } else {
             if (tracker == null) {
                 tracker = VelocityTracker.obtain();
             }
             return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
-                            mOverviewCommandHelper.overviewIntent,
-                            mOverviewCommandHelper.getActivityControlHelper(), mMainThreadExecutor,
-                            mBackgroundThreadChoreographer, downHitTarget, mOverviewCallbacks,
-                            mTaskOverlayFactory, mInputConsumer, tracker, mTouchInteractionLog);
+                    mOverviewCommandHelper.overviewIntent,
+                    mOverviewCommandHelper.getActivityControlHelper(), mMainThreadExecutor,
+                    mBackgroundThreadChoreographer, downHitTarget, mOverviewCallbacks,
+                    mTaskOverlayFactory, mInputConsumer, tracker, mTouchInteractionLog);
         }
     }
 
@@ -298,9 +304,11 @@
         private float mLastProgress = 0;
         private boolean mStartPending = false;
         private boolean mEndPending = false;
+        private boolean mWaitForWindowAvailable;
 
         OverviewTouchConsumer(ActivityControlHelper<T> activityHelper, T activity,
-                boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog) {
+                boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog,
+                boolean waitForWindowAvailable) {
             mActivityHelper = activityHelper;
             mActivity = activity;
             mTarget = activity.getDragLayer();
@@ -311,6 +319,8 @@
                     .getQuickScrubController();
             mTouchInteractionLog = touchInteractionLog;
             mTouchInteractionLog.setTouchConsumer(this);
+
+            mWaitForWindowAvailable = waitForWindowAvailable;
         }
 
         @Override
@@ -433,7 +443,11 @@
                 }
             };
 
-            mActivityHelper.executeOnWindowAvailable(mActivity, action);
+            if (mWaitForWindowAvailable) {
+                mActivityHelper.executeOnWindowAvailable(mActivity, action);
+            } else {
+                action.run();
+            }
         }
 
         @Override
@@ -461,12 +475,19 @@
 
         public static TouchConsumer newInstance(ActivityControlHelper activityHelper,
                 boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog) {
+            return newInstance(activityHelper, startingInActivityBounds, touchInteractionLog,
+                    true /* waitForWindowAvailable */);
+        }
+
+        public static TouchConsumer newInstance(ActivityControlHelper activityHelper,
+                boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog,
+                boolean waitForWindowAvailable) {
             BaseDraggingActivity activity = activityHelper.getCreatedActivity();
             if (activity == null) {
                 return TouchConsumer.NO_OP;
             }
             return new OverviewTouchConsumer(activityHelper, activity, startingInActivityBounds,
-                    touchInteractionLog);
+                    touchInteractionLog, waitForWindowAvailable);
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index a604da0..d7720ee 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -22,6 +22,8 @@
 import static com.android.launcher3.anim.Interpolators.DEACCEL;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
 import static com.android.launcher3.anim.Interpolators.OVERSHOOT_1_2;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
+import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
 import static com.android.quickstep.QuickScrubController.QUICK_SCRUB_FROM_APP_START_DURATION;
 import static com.android.quickstep.QuickScrubController.QUICK_SWITCH_FROM_APP_START_DURATION;
 import static com.android.quickstep.TouchConsumer.INTERACTION_NORMAL;
@@ -46,11 +48,16 @@
 import android.os.UserHandle;
 import android.util.Log;
 import android.view.HapticFeedbackConstants;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewTreeObserver.OnDrawListener;
 import android.view.WindowManager;
 import android.view.animation.Interpolator;
 
+import androidx.annotation.AnyThread;
+import androidx.annotation.UiThread;
+import androidx.annotation.WorkerThread;
+
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
@@ -84,16 +91,12 @@
 import com.android.systemui.shared.system.LatencyTrackerCompat;
 import com.android.systemui.shared.system.RecentsAnimationControllerCompat;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
 import com.android.systemui.shared.system.WindowCallbacksCompat;
 
 import java.util.StringJoiner;
 import java.util.function.BiFunction;
 
-import androidx.annotation.AnyThread;
-import androidx.annotation.UiThread;
-import androidx.annotation.WorkerThread;
-
 @TargetApi(Build.VERSION_CODES.O)
 public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
     private static final String TAG = WindowTransformSwipeHandler.class.getSimpleName();
@@ -110,7 +113,7 @@
 
     // Interaction finish states
     private static final int STATE_SCALED_CONTROLLER_RECENTS = 1 << 5;
-    private static final int STATE_SCALED_CONTROLLER_APP = 1 << 6;
+    private static final int STATE_SCALED_CONTROLLER_LAST_TASK = 1 << 6;
 
     private static final int STATE_HANDLER_INVALIDATED = 1 << 7;
     private static final int STATE_GESTURE_STARTED_QUICKSTEP = 1 << 8;
@@ -128,7 +131,8 @@
     private static final int STATE_SCREENSHOT_VIEW_SHOWN = 1 << 17;
 
     private static final int STATE_RESUME_LAST_TASK = 1 << 18;
-    private static final int STATE_ASSIST_DATA_RECEIVED = 1 << 19;
+    private static final int STATE_START_NEW_TASK = 1 << 19;
+    private static final int STATE_ASSIST_DATA_RECEIVED = 1 << 20;
 
 
     private static final int LAUNCHER_UI_STATES =
@@ -143,6 +147,9 @@
             STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_LAUNCHER_STARTED
                     | STATE_APP_CONTROLLER_RECEIVED | STATE_SCREENSHOT_CAPTURED;
 
+    private static final int QUICK_SCRUB_START_UI_STATE = STATE_LAUNCHER_STARTED
+            | STATE_QUICK_SCRUB_START | STATE_APP_CONTROLLER_RECEIVED;
+
     // For debugging, keep in sync with above states
     private static final String[] STATES = new String[] {
             "STATE_LAUNCHER_PRESENT",
@@ -151,7 +158,7 @@
             "STATE_ACTIVITY_MULTIPLIER_COMPLETE",
             "STATE_APP_CONTROLLER_RECEIVED",
             "STATE_SCALED_CONTROLLER_RECENTS",
-            "STATE_SCALED_CONTROLLER_APP",
+            "STATE_SCALED_CONTROLLER_LAST_TASK",
             "STATE_HANDLER_INVALIDATED",
             "STATE_GESTURE_STARTED_QUICKSTEP",
             "STATE_GESTURE_STARTED_QUICKSCRUB",
@@ -164,6 +171,7 @@
             "STATE_SCREENSHOT_CAPTURED",
             "STATE_SCREENSHOT_VIEW_SHOWN",
             "STATE_RESUME_LAST_TASK",
+            "STATE_START_NEW_TASK",
             "STATE_ASSIST_DATA_RECEIVED",
     };
 
@@ -171,14 +179,15 @@
     public static final long MIN_SWIPE_DURATION = 80;
     public static final long MIN_OVERSHOOT_DURATION = 120;
 
-    public static final float MIN_PROGRESS_FOR_OVERVIEW = 0.5f;
+    public static final float MIN_PROGRESS_FOR_OVERVIEW = 0.7f;
     private static final float SWIPE_DURATION_MULTIPLIER =
             Math.min(1 / MIN_PROGRESS_FOR_OVERVIEW, 1 / (1 - MIN_PROGRESS_FOR_OVERVIEW));
 
-    private final ClipAnimationHelper mClipAnimationHelper = new ClipAnimationHelper();
+    private final ClipAnimationHelper mClipAnimationHelper;
+    private final ClipAnimationHelper.TransformParams mTransformParams;
 
     protected Runnable mGestureEndCallback;
-    protected boolean mIsGoingToHome;
+    protected boolean mIsGoingToRecents;
     private DeviceProfile mDp;
     private int mTransitionDragLength;
 
@@ -187,6 +196,7 @@
     // 1 => preview snapShot is completely aligned with the recents view and hotseat is completely
     // visible.
     private final AnimatedFloat mCurrentShift = new AnimatedFloat(this::updateFinalShift);
+    private boolean mDispatchedDownEvent;
     // To avoid UI jump when gesture is started, we offset the animation by the threshold.
     private float mShiftAtGestureStart = 0;
 
@@ -213,7 +223,7 @@
     private T mActivity;
     private LayoutListener mLayoutListener;
     private RecentsView mRecentsView;
-    private SyncRtSurfaceTransactionApplier mSyncTransactionApplier;
+    private SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
     private QuickScrubController mQuickScrubController;
     private AnimationFactory mAnimationFactory = (t, i) -> { };
 
@@ -255,6 +265,8 @@
         mTouchInteractionLog = touchInteractionLog;
         mRecentsAnimationWrapper = new RecentsAnimationWrapper(inputConsumer,
                 this::createNewTouchProxyHandler);
+        mClipAnimationHelper = new ClipAnimationHelper(context);
+        mTransformParams = new ClipAnimationHelper.TransformParams();
 
         initStateCallbacks();
     }
@@ -293,10 +305,12 @@
         mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_APP_CONTROLLER_RECEIVED,
                 this::sendRemoteAnimationsToAnimationFactory);
 
-        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SCALED_CONTROLLER_APP,
+        mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SCALED_CONTROLLER_LAST_TASK,
                 this::resumeLastTaskForQuickstep);
         mStateCallback.addCallback(STATE_RESUME_LAST_TASK | STATE_APP_CONTROLLER_RECEIVED,
                 this::resumeLastTask);
+        mStateCallback.addCallback(STATE_START_NEW_TASK | STATE_APP_CONTROLLER_RECEIVED,
+                this::startNewTask);
 
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
                         | STATE_ACTIVITY_MULTIPLIER_COMPLETE
@@ -305,7 +319,7 @@
 
         mStateCallback.addCallback(STATE_SCREENSHOT_CAPTURED | STATE_GESTURE_COMPLETED
                         | STATE_SCALED_CONTROLLER_RECENTS,
-                this::finishCurrentTransitionToHome);
+                this::finishCurrentTransitionToRecents);
 
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
                         | STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_SCALED_CONTROLLER_RECENTS
@@ -322,11 +336,10 @@
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
                 this::invalidateHandlerWithLauncher);
         mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED
-                | STATE_SCALED_CONTROLLER_APP,
+                | STATE_SCALED_CONTROLLER_LAST_TASK,
                 this::notifyTransitionCancelled);
 
-        mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
-                        | STATE_APP_CONTROLLER_RECEIVED, this::onQuickScrubStartUi);
+        mStateCallback.addCallback(QUICK_SCRUB_START_UI_STATE, this::onQuickScrubStartUi);
         mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
                 | STATE_SCALED_CONTROLLER_RECENTS, this::onFinishedTransitionToQuickScrub);
         mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_CURRENT_TASK_FINISHED
@@ -335,9 +348,11 @@
         mStateCallback.addCallback(LONG_SWIPE_ENTER_STATE, this::checkLongSwipeCanEnter);
         mStateCallback.addCallback(LONG_SWIPE_START_STATE, this::checkLongSwipeCanStart);
 
-        mStateCallback.addChangeHandler(STATE_APP_CONTROLLER_RECEIVED | STATE_LAUNCHER_PRESENT
-                | STATE_SCREENSHOT_VIEW_SHOWN | STATE_CAPTURE_SCREENSHOT,
-                (b) -> mRecentsView.setRunningTaskHidden(!b));
+        if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            mStateCallback.addChangeHandler(STATE_APP_CONTROLLER_RECEIVED | STATE_LAUNCHER_PRESENT
+                            | STATE_SCREENSHOT_VIEW_SHOWN | STATE_CAPTURE_SCREENSHOT,
+                    (b) -> mRecentsView.setRunningTaskHidden(!b));
+        }
     }
 
     private void executeOnUiThread(Runnable action) {
@@ -403,7 +418,16 @@
         }
 
         mRecentsView = activity.getOverviewPanel();
-        mSyncTransactionApplier = new SyncRtSurfaceTransactionApplier(mRecentsView);
+        SyncRtSurfaceTransactionApplierCompat.create(mRecentsView, (applier) -> {
+            mSyncTransactionApplier = applier;
+        });
+        mRecentsView.setOnScrollChangeListener((v, scrollX, scrollY, oldScrollX, oldScrollY) -> {
+            if (!mBgLongSwipeMode) {
+                updateFinalShift();
+            }
+        });
+        mRecentsView.setRecentsAnimationWrapper(mRecentsAnimationWrapper);
+        mRecentsView.setClipAnimationHelper(mClipAnimationHelper);
         mQuickScrubController = mRecentsView.getQuickScrubController();
         mLayoutListener = mActivityControlHelper.createLayoutListener(mActivity);
 
@@ -456,6 +480,7 @@
     }
 
     private void setupRecentsViewUi() {
+        mRecentsView.setEnableDrawingLiveTile(false);
         mRecentsView.showTask(mRunningTaskId);
         mRecentsView.setRunningTaskHidden(true);
         mRecentsView.setRunningTaskIconScaledDown(true);
@@ -529,15 +554,39 @@
         } else {
             offsetX = res.getDimensionPixelSize(R.dimen.recents_page_spacing)
                     + tempRect.rect.width();
-            float distanceToReachEdge = mDp.widthPx / 2 + tempRect.rect.width() / 2 +
-                    res.getDimensionPixelSize(R.dimen.recents_page_spacing);
-            float interpolation = Math.min(1, offsetX / distanceToReachEdge);
-            scale = TaskView.getCurveScaleForInterpolation(interpolation);
+            scale = getTaskCurveScaleForOffsetX(offsetX, tempRect.rect.width());
         }
         mClipAnimationHelper.offsetTarget(scale, Utilities.isRtl(res) ? -offsetX : offsetX, offsetY,
                 QuickScrubController.QUICK_SCRUB_START_INTERPOLATOR);
     }
 
+    private float getTaskCurveScaleForOffsetX(float offsetX, float taskWidth) {
+        float distanceToReachEdge = mDp.widthPx / 2 + taskWidth / 2 +
+                mContext.getResources().getDimensionPixelSize(R.dimen.recents_page_spacing);
+        float interpolation = Math.min(1, offsetX / distanceToReachEdge);
+        return TaskView.getCurveScaleForInterpolation(interpolation);
+    }
+
+    @WorkerThread
+    public void dispatchMotionEventToRecentsView(MotionEvent event) {
+        if (mRecentsView == null) {
+            return;
+        }
+        // Pass the motion events to RecentsView to allow scrolling during swipe up.
+        if (mDispatchedDownEvent) {
+            mRecentsView.dispatchTouchEvent(event);
+        } else {
+            // The first event we dispatch should be ACTION_DOWN.
+            mDispatchedDownEvent = true;
+            MotionEvent downEvent = MotionEvent.obtain(event);
+            downEvent.setAction(MotionEvent.ACTION_DOWN);
+            int flags = downEvent.getEdgeFlags();
+            downEvent.setEdgeFlags(flags | TouchInteractionService.EDGE_NAV_BAR);
+            mRecentsView.dispatchTouchEvent(downEvent);
+            downEvent.recycle();
+        }
+    }
+
     @WorkerThread
     public void updateDisplacement(float displacement) {
         // We are moving in the negative x/y direction
@@ -582,11 +631,23 @@
 
         RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
         if (controller != null) {
-
-            mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet, shift,
-                    Looper.myLooper() == mMainThreadHandler.getLooper()
+            float offsetX = 0;
+            if (mRecentsView != null && mInteractionType == INTERACTION_NORMAL) {
+                int startScroll = mRecentsView.getScrollForPage(mRecentsView.indexOfChild(
+                        mRecentsView.getRunningTaskView()));
+                offsetX = startScroll - mRecentsView.getScrollX();
+                offsetX *= mRecentsView.getScaleX();
+            }
+            float offsetScale = getTaskCurveScaleForOffsetX(offsetX,
+                    mClipAnimationHelper.getTargetRect().width());
+            SyncRtSurfaceTransactionApplierCompat syncTransactionApplier
+                    = Looper.myLooper() == mMainThreadHandler.getLooper()
                             ? mSyncTransactionApplier
-                            : null);
+                            : null;
+            mTransformParams.setProgress(shift).setOffsetX(offsetX).setOffsetScale(offsetScale)
+                    .setSyncTransactionApplier(syncTransactionApplier);
+            mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet,
+                    mTransformParams);
 
             boolean passedThreshold = shift > 1 - UPDATE_SYSUI_FLAGS_THRESHOLD;
             mRecentsAnimationWrapper.setAnimationTargetsBehindSystemBars(!passedThreshold);
@@ -599,9 +660,13 @@
     }
 
     private void updateFinalShiftUi() {
-        if (mRecentsAnimationWrapper.getController() != null && mLayoutListener != null) {
-            mLayoutListener.update(mCurrentShift.value > 1, mUiLongSwipeMode,
-                    mClipAnimationHelper.getCurrentRectWithInsets());
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            if (mRecentsAnimationWrapper.getController() != null && mLayoutListener != null) {
+                mLayoutListener.open();
+                mLayoutListener.update(mCurrentShift.value > 1, mUiLongSwipeMode,
+                        mClipAnimationHelper.getCurrentRectWithInsets(),
+                        mClipAnimationHelper.getCurrentCornerRadius());
+            }
         }
 
         final boolean passed = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
@@ -612,6 +677,18 @@
                     HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
             }
         }
+        // Update insets of the adjacent tasks, as we might switch to them.
+        int runningTaskIndex = mRecentsView == null ? -1 : mRecentsView.getRunningTaskIndex();
+        if (mInteractionType == INTERACTION_NORMAL && runningTaskIndex >= 0) {
+            TaskView nextTaskView = mRecentsView.getTaskViewAt(runningTaskIndex + 1);
+            TaskView prevTaskView = mRecentsView.getTaskViewAt(runningTaskIndex - 1);
+            if (nextTaskView != null) {
+                nextTaskView.setFullscreenProgress(1 - mCurrentShift.value);
+            }
+            if (prevTaskView != null) {
+                prevTaskView.setFullscreenProgress(1 - mCurrentShift.value);
+            }
+        }
 
         if (mLauncherTransitionController == null || mLauncherTransitionController
                 .getAnimationPlayer().isStarted()) {
@@ -700,7 +777,7 @@
     }
 
     @WorkerThread
-    public void onGestureEnded(float endVelocity) {
+    public void onGestureEnded(float endVelocity, float velocityX) {
         float flingThreshold = mContext.getResources()
                 .getDimension(R.dimen.quickstep_fling_threshold_velocity);
         boolean isFling = mGestureStarted && Math.abs(endVelocity) > flingThreshold;
@@ -709,9 +786,9 @@
         mLogAction = isFling ? Touch.FLING : Touch.SWIPE;
 
         if (mBgLongSwipeMode) {
-            executeOnUiThread(() -> onLongSwipeGestureFinishUi(endVelocity, isFling));
+            executeOnUiThread(() -> onLongSwipeGestureFinishUi(endVelocity, isFling, velocityX));
         } else {
-            handleNormalGestureEnd(endVelocity, isFling);
+            handleNormalGestureEnd(endVelocity, isFling, velocityX);
         }
     }
 
@@ -721,38 +798,47 @@
         if (mLauncherTransitionController != null) {
             mLauncherTransitionController.getAnimationPlayer().end();
         }
-        // Hide the task view, if not already hidden
-        setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
+        if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            // Hide the task view, if not already hidden
+            setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
+        }
 
         return OverviewTouchConsumer.newInstance(mActivityControlHelper, true,
                 mTouchInteractionLog);
     }
 
-    private void handleNormalGestureEnd(float endVelocity, boolean isFling) {
+    private void handleNormalGestureEnd(float endVelocity, boolean isFling, float velocityX) {
         float velocityPxPerMs = endVelocity / 1000;
+        float velocityXPxPerMs = velocityX / 1000;
         long duration = MAX_SWIPE_DURATION;
         float currentShift = mCurrentShift.value;
-        final boolean goingToHome;
+        final boolean goingToRecents;
         float endShift;
         final float startShift;
         Interpolator interpolator = DEACCEL;
+        final int nextPage = mRecentsView != null ? mRecentsView.getNextPage() : -1;
+        final int runningTaskIndex = mRecentsView != null ? mRecentsView.getRunningTaskIndex() : -1;
+        boolean goingToNewTask = mRecentsView != null && nextPage != runningTaskIndex;
+        final boolean reachedOverviewThreshold = currentShift >= MIN_PROGRESS_FOR_OVERVIEW;
         if (!isFling) {
-            goingToHome = currentShift >= MIN_PROGRESS_FOR_OVERVIEW && mGestureStarted;
-            endShift = goingToHome ? 1 : 0;
+            goingToRecents = reachedOverviewThreshold && mGestureStarted;
+            endShift = goingToRecents ? 1 : 0;
             long expectedDuration = Math.abs(Math.round((endShift - currentShift)
                     * MAX_SWIPE_DURATION * SWIPE_DURATION_MULTIPLIER));
             duration = Math.min(MAX_SWIPE_DURATION, expectedDuration);
             startShift = currentShift;
-            interpolator = goingToHome ? OVERSHOOT_1_2 : DEACCEL;
+            interpolator = goingToRecents ? OVERSHOOT_1_2 : DEACCEL;
         } else {
-            goingToHome = endVelocity < 0;
-            endShift = goingToHome ? 1 : 0;
+            // If user scrolled to a new task, only go to recents if they already passed
+            // the overview threshold. Otherwise, we'll snap to the new task and launch it.
+            goingToRecents = endVelocity < 0 && (!goingToNewTask || reachedOverviewThreshold);
+            endShift = goingToRecents ? 1 : 0;
             startShift = Utilities.boundToRange(currentShift - velocityPxPerMs
                     * SINGLE_FRAME_MS / mTransitionDragLength, 0, 1);
             float minFlingVelocity = mContext.getResources()
                     .getDimension(R.dimen.quickstep_fling_min_velocity);
             if (Math.abs(endVelocity) > minFlingVelocity && mTransitionDragLength > 0) {
-                if (goingToHome) {
+                if (goingToRecents) {
                     Interpolators.OvershootParams overshoot = new Interpolators.OvershootParams(
                             startShift, endShift, endShift, velocityPxPerMs, mTransitionDragLength);
                     endShift = overshoot.end;
@@ -770,11 +856,31 @@
                 }
             }
         }
-        if (goingToHome) {
+        if (goingToRecents) {
             mRecentsAnimationWrapper.enableTouchProxy();
+        } else if (goingToNewTask) {
+            // We aren't goingToRecents, and user scrolled/flung to a new task; snap to the closest
+            // task in that direction and launch it (in startNewTask()).
+            int taskToLaunch = runningTaskIndex + (nextPage > runningTaskIndex ? 1 : - 1);
+            if (taskToLaunch >= mRecentsView.getTaskViewCount()) {
+                // Scrolled to Clear all button, snap back to current task and resume it.
+                mRecentsView.snapToPage(runningTaskIndex, Math.toIntExact(duration));
+                goingToNewTask = false;
+            } else {
+                float distance = Math.abs(mRecentsView.getScrollForPage(taskToLaunch)
+                        - mRecentsView.getScrollX());
+                int durationX = (int) Math.abs(distance / velocityXPxPerMs);
+                if (durationX > MAX_SWIPE_DURATION) {
+                    durationX = Math.toIntExact(MAX_SWIPE_DURATION);
+                }
+                interpolator = Interpolators.scrollInterpolatorForVelocity(velocityXPxPerMs);
+                mRecentsView.snapToPage(taskToLaunch, durationX, interpolator);
+                duration = Math.max(duration, durationX);
+            }
         }
 
-        animateToProgress(startShift, endShift, duration, interpolator, goingToHome);
+        animateToProgress(startShift, endShift, duration, interpolator, goingToRecents,
+                goingToNewTask, velocityPxPerMs);
     }
 
     private void doLogGesture(boolean toLauncher) {
@@ -799,23 +905,28 @@
     }
 
     /** Animates to the given progress, where 0 is the current app and 1 is overview. */
-    private void animateToProgress(float start, float end, long duration,
-            Interpolator interpolator, boolean goingToHome) {
+    private void animateToProgress(float start, float end, long duration, Interpolator interpolator,
+            boolean goingToRecents, boolean goingToNewTask, float velocityPxPerMs) {
         mRecentsAnimationWrapper.runOnInit(() -> animateToProgressInternal(start, end, duration,
-                interpolator, goingToHome));
+                interpolator, goingToRecents, goingToNewTask, velocityPxPerMs));
     }
 
     private void animateToProgressInternal(float start, float end, long duration,
-            Interpolator interpolator, boolean goingToHome) {
-        mIsGoingToHome = goingToHome;
+            Interpolator interpolator, boolean goingToRecents, boolean goingToNewTask,
+            float velocityPxPerMs) {
+        mIsGoingToRecents = goingToRecents;
         ObjectAnimator anim = mCurrentShift.animateToValue(start, end).setDuration(duration);
         anim.setInterpolator(interpolator);
         anim.addListener(new AnimationSuccessListener() {
             @Override
             public void onAnimationSuccess(Animator animator) {
-                setStateOnUiThread(mIsGoingToHome
-                        ? (STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT
-                        | STATE_SCREENSHOT_VIEW_SHOWN) : STATE_SCALED_CONTROLLER_APP);
+                int recentsState = STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT
+                        | STATE_SCREENSHOT_VIEW_SHOWN;
+                setStateOnUiThread(mIsGoingToRecents
+                        ? recentsState
+                        : goingToNewTask
+                            ? STATE_START_NEW_TASK
+                            : STATE_SCALED_CONTROLLER_LAST_TASK);
             }
         });
         anim.start();
@@ -826,6 +937,7 @@
                 return;
             }
             if (start == end || duration <= 0) {
+                mLauncherTransitionController.dispatchSetInterpolator(t -> end);
                 mLauncherTransitionController.getAnimationPlayer().end();
             } else {
                 // Adjust start progress and duration in case we are on a different thread.
@@ -839,7 +951,12 @@
                 mLauncherTransitionController.dispatchSetInterpolator(Interpolators.mapToProgress(
                         interpolator, adjustedStart, end));
                 mLauncherTransitionController.getAnimationPlayer().setDuration(adjustedDuration);
-                mLauncherTransitionController.getAnimationPlayer().start();
+
+                if (QUICKSTEP_SPRINGS.get()) {
+                    mLauncherTransitionController.dispatchOnStartWithVelocity(end, velocityPxPerMs);
+                } else {
+                    mLauncherTransitionController.getAnimationPlayer().start();
+                }
             }
         });
     }
@@ -853,10 +970,22 @@
 
     @UiThread
     private void resumeLastTask() {
-        mRecentsAnimationWrapper.finish(false /* toHome */, null);
+        mRecentsAnimationWrapper.finish(false /* toRecents */, null);
         mTouchInteractionLog.finishRecentsAnimation(false);
     }
 
+    @UiThread
+    private void startNewTask() {
+        // Launch the task user scrolled to (mRecentsView.getNextPage()).
+        mRecentsAnimationWrapper.finish(true /* toRecents */, () -> {
+            mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false,
+                    result -> setStateOnUiThread(STATE_HANDLER_INVALIDATED),
+                    mMainThreadHandler);
+        });
+        mTouchInteractionLog.finishRecentsAnimation(false);
+        doLogGesture(false /* toLauncher */);
+    }
+
     public void reset() {
         if (mInteractionType != INTERACTION_QUICK_SCRUB) {
             // Only invalidate the handler if we are not quick scrubbing, otherwise, it will be
@@ -874,6 +1003,10 @@
 
         mActivityInitListener.unregister();
         mTaskSnapshot = null;
+
+        if (mRecentsView != null) {
+            mRecentsView.setOnScrollChangeListener(null);
+        }
     }
 
     private void invalidateHandlerWithLauncher() {
@@ -898,57 +1031,66 @@
     }
 
     public void layoutListenerClosed() {
+        mRecentsView.setRunningTaskHidden(false);
         if (mWasLauncherAlreadyVisible && mLauncherTransitionController != null) {
             mLauncherTransitionController.setPlayFraction(1);
         }
-        mRecentsView.setRunningTaskHidden(false);
+        mRecentsView.setEnableDrawingLiveTile(true);
     }
 
     private void switchToScreenshot() {
-        boolean finishTransitionPosted = false;
-        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);
-            if (taskView != null) {
-                // Defer finishing the animation until the next launcher frame with the
-                // new thumbnail
-                finishTransitionPosted = new WindowCallbacksCompat(taskView) {
-
-                    // The number of frames to defer until we actually finish the animation
-                    private int mDeferFrameCount = 2;
-
-                    @Override
-                    public void onPostDraw(Canvas canvas) {
-                        if (mDeferFrameCount > 0) {
-                            mDeferFrameCount--;
-                            // Workaround, detach and reattach to invalidate the root node for
-                            // another draw
-                            detach();
-                            attach();
-                            taskView.invalidate();
-                            return;
-                        }
-
-                        setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
-                        detach();
-                    }
-                }.attach();
-            }
-        }
-        if (!finishTransitionPosted) {
-            // If we haven't posted a draw callback, set the state immediately.
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
             setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
+        } else {
+            boolean finishTransitionPosted = false;
+            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);
+                if (taskView != null) {
+                    // Defer finishing the animation until the next launcher frame with the
+                    // new thumbnail
+                    finishTransitionPosted = new WindowCallbacksCompat(taskView) {
+
+                        // The number of frames to defer until we actually finish the animation
+                        private int mDeferFrameCount = 2;
+
+                        @Override
+                        public void onPostDraw(Canvas canvas) {
+                            if (mDeferFrameCount > 0) {
+                                mDeferFrameCount--;
+                                // Workaround, detach and reattach to invalidate the root node for
+                                // another draw
+                                detach();
+                                attach();
+                                taskView.invalidate();
+                                return;
+                            }
+
+                            setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
+                            detach();
+                        }
+                    }.attach();
+                }
+            }
+            if (!finishTransitionPosted) {
+                // If we haven't posted a draw callback, set the state immediately.
+                setStateOnUiThread(STATE_SCREENSHOT_CAPTURED);
+            }
         }
     }
 
-    private void finishCurrentTransitionToHome() {
-        synchronized (mRecentsAnimationWrapper) {
-            mRecentsAnimationWrapper.finish(true /* toHome */,
-                    () -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
+    private void finishCurrentTransitionToRecents() {
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            setStateOnUiThread(STATE_CURRENT_TASK_FINISHED);
+        } else {
+            synchronized (mRecentsAnimationWrapper) {
+                mRecentsAnimationWrapper.finish(true /* toRecents */,
+                        () -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
+            }
         }
         mTouchInteractionLog.finishRecentsAnimation(true);
     }
@@ -984,7 +1126,8 @@
         long duration = FeatureFlags.QUICK_SWITCH.get()
                 ? QUICK_SWITCH_FROM_APP_START_DURATION
                 : QUICK_SCRUB_FROM_APP_START_DURATION;
-        animateToProgress(mCurrentShift.value, 1f, duration, LINEAR, true /* goingToHome */);
+        animateToProgress(mCurrentShift.value, 1f, duration, LINEAR, true /* goingToRecents */,
+                false /* goingToNewTask */, 1f);
     }
 
     private void onQuickScrubStartUi() {
@@ -997,7 +1140,6 @@
             mLauncherTransitionController.getAnimationPlayer().end();
             mLauncherTransitionController = null;
         }
-        mLayoutListener.finish();
 
         mActivityControlHelper.onQuickInteractionStart(mActivity, mRunningTaskInfo, false,
                 mTouchInteractionLog);
@@ -1010,14 +1152,22 @@
         if (mQuickScrubBlocked) {
             return;
         }
+        mLayoutListener.finish();
         mQuickScrubController.onFinishedTransitionToQuickScrub();
 
         mRecentsView.animateUpRunningTaskIconScale();
         if (mQuickScrubController.isQuickSwitch()) {
+            // Adjust the running task so that it is centered and fills the screen.
             TaskView runningTask = mRecentsView.getRunningTaskView();
             if (runningTask != null) {
-                runningTask.setTranslationY(-mActivity.getResources().getDimension(
-                        R.dimen.task_thumbnail_half_top_margin) * 1f / mRecentsView.getScaleX());
+                float insetHeight = mDp.heightPx - mDp.getInsets().top - mDp.getInsets().bottom;
+                // Usually insetDiff will be 0, unless we allow apps to draw under the insets. In
+                // that case (insetDiff != 0), we need to center in the system-specified available
+                // height rather than launcher's inset height by adding half the insetDiff.
+                float insetDiff = mDp.availableHeightPx - insetHeight;
+                float topMargin = mActivity.getResources().getDimension(
+                        R.dimen.task_thumbnail_half_top_margin);
+                runningTask.setTranslationY((insetDiff / 2 - topMargin) / mRecentsView.getScaleX());
             }
         }
         RecentsModel.INSTANCE.get(mContext).onOverviewShown(false, TAG);
@@ -1026,7 +1176,7 @@
     public void onQuickScrubProgress(float progress) {
         mCurrentQuickScrubProgress = progress;
         if (Looper.myLooper() != Looper.getMainLooper() || mQuickScrubController == null
-                || mQuickScrubBlocked) {
+                || mQuickScrubBlocked || !mStateCallback.hasStates(QUICK_SCRUB_START_UI_STATE)) {
             return;
         }
         mQuickScrubController.onQuickScrubProgress(progress);
@@ -1127,17 +1277,19 @@
         mLongSwipeController = mActivityControlHelper.getLongSwipeController(
                 mActivity, mRunningTaskId);
         onLongSwipeDisplacementUpdated();
-        setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
+        if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
+        }
     }
 
-    private void onLongSwipeGestureFinishUi(float velocity, boolean isFling) {
+    private void onLongSwipeGestureFinishUi(float velocity, boolean isFling, float velocityX) {
         if (!mUiLongSwipeMode || mLongSwipeController == null) {
             mUiLongSwipeMode = false;
-            handleNormalGestureEnd(velocity, isFling);
+            handleNormalGestureEnd(velocity, isFling, velocityX);
             return;
         }
         mUiLongSwipeMode = false;
-        finishCurrentTransitionToHome();
+        finishCurrentTransitionToRecents();
         mLongSwipeController.end(velocity, isFling,
                 () -> setStateOnUiThread(STATE_HANDLER_INVALIDATED));
 
diff --git a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
index 57a0e8f..84033cb 100644
--- a/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
+++ b/quickstep/src/com/android/quickstep/util/ClipAnimationHelper.java
@@ -16,11 +16,13 @@
 package com.android.quickstep.util;
 
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 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;
 
 import android.annotation.TargetApi;
+import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Matrix.ScaleToFit;
@@ -31,6 +33,8 @@
 import android.os.RemoteException;
 import android.view.animation.Interpolator;
 
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.BaseDraggingActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
@@ -43,15 +47,13 @@
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.recents.utilities.RectFEvaluator;
 import com.android.systemui.shared.system.RemoteAnimationTargetCompat;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier;
-import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplier.SurfaceParams;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams;
 import com.android.systemui.shared.system.TransactionCompat;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
 import java.util.function.BiFunction;
 
-import androidx.annotation.Nullable;
-
 /**
  * Utility class to handle window clip animation
  */
@@ -72,6 +74,9 @@
     // if the aspect ratio of the target is smaller than the aspect ratio of the source rect. In
     // app window coordinates.
     private final RectF mSourceWindowClipInsets = new RectF();
+    // The insets to be used for clipping the app window. For live tile, we don't transform the clip
+    // relative to the target rect.
+    private final RectF mSourceWindowClipInsetsForLiveTile = new RectF();
 
     // The bounds of launcher (not including insets) in device coordinates
     public final Rect mHomeStackBounds = new Rect();
@@ -82,7 +87,13 @@
     private final Matrix mTmpMatrix = new Matrix();
     private final RectF mTmpRectF = new RectF();
     private final RectF mCurrentRectWithInsets = new RectF();
+    // Corner radius of windows, in pixels
+    private final float mWindowCornerRadius;
+    // Corner radius of windows when they're in overview mode.
+    private final float mTaskCornerRadius;
 
+    // Corner radius currently applied to transformed window.
+    private float mCurrentCornerRadius;
     private float mTargetScale = 1f;
     private float mOffsetScale = 1f;
     private Interpolator mInterpolator = LINEAR;
@@ -95,6 +106,11 @@
     private BiFunction<RemoteAnimationTargetCompat, Float, Float> mTaskAlphaCallback =
             (t, a1) -> a1;
 
+    public ClipAnimationHelper(Context context) {
+        mTaskCornerRadius = context.getResources().getDimension(R.dimen.task_corner_radius);
+        mWindowCornerRadius  = RecentsModel.INSTANCE.get(context).getWindowCornerRadius();
+    }
+
     private void updateSourceStack(RemoteAnimationTargetCompat target) {
         mSourceInsets.set(target.contentInsets);
         mSourceStackBounds.set(target.sourceContainerBounds);
@@ -132,6 +148,7 @@
                 Math.max(scaledTargetRect.top, 0),
                 Math.max(mSourceStackBounds.width() - scaledTargetRect.right, 0),
                 Math.max(mSourceStackBounds.height() - scaledTargetRect.bottom, 0));
+        mSourceWindowClipInsetsForLiveTile.set(mSourceWindowClipInsets);
         mSourceRect.set(scaledTargetRect);
     }
 
@@ -139,57 +156,64 @@
         mBoostModeTargetLayers = isOpening ? MODE_OPENING : MODE_CLOSING;
     }
 
-    public RectF applyTransform(RemoteAnimationTargetSet targetSet, float progress,
-            @Nullable SyncRtSurfaceTransactionApplier syncTransactionApplier) {
-        RectF currentRect;
-        mTmpRectF.set(mTargetRect);
-        Utilities.scaleRectFAboutCenter(mTmpRectF, mTargetScale);
-        float offsetYProgress = mOffsetYInterpolator.getInterpolation(progress);
-        progress = mInterpolator.getInterpolation(progress);
-        currentRect =  mRectFEvaluator.evaluate(progress, mSourceRect, mTmpRectF);
+    public RectF applyTransform(RemoteAnimationTargetSet targetSet, TransformParams params) {
+        if (params.currentRect == null) {
+            RectF currentRect;
+            mTmpRectF.set(mTargetRect);
+            Utilities.scaleRectFAboutCenter(mTmpRectF, mTargetScale * params.offsetScale);
+            float offsetYProgress = mOffsetYInterpolator.getInterpolation(params.progress);
+            float progress = mInterpolator.getInterpolation(params.progress);
+            currentRect = mRectFEvaluator.evaluate(progress, mSourceRect, mTmpRectF);
+            currentRect.offset(params.offsetX, 0);
 
-        synchronized (mTargetOffset) {
-            // Stay lined up with the center of the target, since it moves for quick scrub.
-            currentRect.offset(mTargetOffset.x * mOffsetScale * progress,
-                    mTargetOffset.y  * offsetYProgress);
+            synchronized (mTargetOffset) {
+                // Stay lined up with the center of the target, since it moves for quick scrub.
+                currentRect.offset(mTargetOffset.x * mOffsetScale * progress,
+                        mTargetOffset.y  * offsetYProgress);
+            }
+
+            final RectF sourceWindowClipInsets = params.forLiveTile
+                    ? mSourceWindowClipInsetsForLiveTile : mSourceWindowClipInsets;
+            mClipRectF.left = sourceWindowClipInsets.left * progress;
+            mClipRectF.top = sourceWindowClipInsets.top * progress;
+            mClipRectF.right =
+                    mSourceStackBounds.width() - (sourceWindowClipInsets.right * progress);
+            mClipRectF.bottom =
+                    mSourceStackBounds.height() - (sourceWindowClipInsets.bottom * progress);
+            params.setCurrentRectAndTargetAlpha(currentRect, 1);
         }
 
-        mClipRectF.left = mSourceWindowClipInsets.left * progress;
-        mClipRectF.top = mSourceWindowClipInsets.top * progress;
-        mClipRectF.right =
-                mSourceStackBounds.width() - (mSourceWindowClipInsets.right * progress);
-        mClipRectF.bottom =
-                mSourceStackBounds.height() - (mSourceWindowClipInsets.bottom * progress);
-
-        SurfaceParams[] params = new SurfaceParams[targetSet.unfilteredApps.length];
+        SurfaceParams[] surfaceParams = new SurfaceParams[targetSet.unfilteredApps.length];
         for (int i = 0; i < targetSet.unfilteredApps.length; i++) {
             RemoteAnimationTargetCompat app = targetSet.unfilteredApps[i];
             mTmpMatrix.setTranslate(app.position.x, app.position.y);
             Rect crop = app.sourceContainerBounds;
             float alpha = 1f;
-            int layer;
+            int layer = RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers);
+            float cornerRadius = 0f;
+            float scale = params.currentRect.width() / crop.width();
             if (app.mode == targetSet.targetMode) {
                 if (app.activityType != RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
-                    mTmpMatrix.setRectToRect(mSourceRect, currentRect, ScaleToFit.FILL);
+                    mTmpMatrix.setRectToRect(mSourceRect, params.currentRect, ScaleToFit.FILL);
                     mTmpMatrix.postTranslate(app.position.x, app.position.y);
                     mClipRectF.roundOut(crop);
+                    cornerRadius = Utilities.mapRange(params.progress, mWindowCornerRadius,
+                            mTaskCornerRadius);
+                    mCurrentCornerRadius = cornerRadius;
                 }
-
-                if (app.isNotInRecents
-                        || app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) {
-                    alpha = 1 - progress;
-                }
-
-                alpha = mTaskAlphaCallback.apply(app, alpha);
-                layer = RemoteAnimationProvider.getLayer(app, mBoostModeTargetLayers);
-            } else {
+                alpha = mTaskAlphaCallback.apply(app, params.targetAlpha);
+            } else if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
                 crop = null;
                 layer = Integer.MAX_VALUE;
             }
-            params[i] = new SurfaceParams(app.leash, alpha, mTmpMatrix, crop, layer);
+
+            // Since radius is in Surface space, but we draw the rounded corners in screen space, we
+            // have to undo the scale.
+            surfaceParams[i] = new SurfaceParams(app.leash, alpha, mTmpMatrix, crop, layer,
+                    cornerRadius / scale);
         }
-        applyParams(syncTransactionApplier, params);
-        return currentRect;
+        applySurfaceParams(params.syncTransactionApplier, surfaceParams);
+        return params.currentRect;
     }
 
     public RectF getCurrentRectWithInsets() {
@@ -197,14 +221,14 @@
         return mCurrentRectWithInsets;
     }
 
-    private void applyParams(@Nullable SyncRtSurfaceTransactionApplier syncTransactionApplier,
-            SurfaceParams[] params) {
+    private void applySurfaceParams(@Nullable SyncRtSurfaceTransactionApplierCompat
+            syncTransactionApplier, SurfaceParams[] params) {
         if (syncTransactionApplier != null) {
             syncTransactionApplier.scheduleApply(params);
         } else {
             TransactionCompat t = new TransactionCompat();
             for (SurfaceParams param : params) {
-                SyncRtSurfaceTransactionApplier.applyParams(t, param);
+                SyncRtSurfaceTransactionApplierCompat.applyParams(t, param);
             }
             t.setEarlyWakeup();
             t.apply();
@@ -309,13 +333,14 @@
         canvas.concat(mTmpMatrix);
         canvas.translate(mTargetRect.left, mTargetRect.top);
 
+        float scale = mTargetRect.width() / mSourceRect.width();
         float insetProgress = (1 - progress);
         ttv.drawOnCanvas(canvas,
                 -mSourceWindowClipInsets.left * insetProgress,
                 -mSourceWindowClipInsets.top * insetProgress,
                 ttv.getMeasuredWidth() + mSourceWindowClipInsets.right * insetProgress,
                 ttv.getMeasuredHeight() + mSourceWindowClipInsets.bottom * insetProgress,
-                ttv.getCornerRadius() * progress);
+                Utilities.mapRange(progress, mWindowCornerRadius * scale, ttv.getCornerRadius()));
     }
 
     public RectF getTargetRect() {
@@ -325,4 +350,62 @@
     public RectF getSourceRect() {
         return mSourceRect;
     }
+
+    public float getCurrentCornerRadius() {
+        return mCurrentCornerRadius;
+    }
+
+    public static class TransformParams {
+        float progress;
+        float offsetX;
+        float offsetScale;
+        @Nullable RectF currentRect;
+        float targetAlpha;
+        boolean forLiveTile;
+
+        SyncRtSurfaceTransactionApplierCompat syncTransactionApplier;
+
+        public TransformParams() {
+            progress = 0;
+            offsetX = 0;
+            offsetScale = 1;
+            currentRect = null;
+            targetAlpha = 0;
+            forLiveTile = false;
+        }
+
+        public TransformParams setProgress(float progress) {
+            this.progress = progress;
+            this.currentRect = null;
+            return this;
+        }
+
+        public TransformParams setCurrentRectAndTargetAlpha(RectF currentRect, float targetAlpha) {
+            this.currentRect = currentRect;
+            this.targetAlpha = targetAlpha;
+            this.progress = 1;
+            return this;
+        }
+
+        public TransformParams setOffsetX(float offsetX) {
+            this.offsetX = offsetX;
+            return this;
+        }
+
+        public TransformParams setOffsetScale(float offsetScale) {
+            this.offsetScale = offsetScale;
+            return this;
+        }
+
+        public TransformParams setForLiveTile(boolean forLiveTile) {
+            this.forLiveTile = forLiveTile;
+            return this;
+        }
+
+        public TransformParams setSyncTransactionApplier(
+                SyncRtSurfaceTransactionApplierCompat applier) {
+            this.syncTransactionApplier = applier;
+            return this;
+        }
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index 6ca0dce..ed585c1 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -21,14 +21,15 @@
 import android.content.res.Resources;
 import android.graphics.Rect;
 
-import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.R;
-
-import java.lang.annotation.Retention;
-
 import androidx.annotation.AnyThread;
 import androidx.annotation.IntDef;
 
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
+
+import java.lang.annotation.Retention;
+
 public class LayoutUtils {
 
     private static final int MULTI_WINDOW_STRATEGY_HALF_SCREEN = 1;
@@ -112,7 +113,14 @@
                 Math.round(x + outWidth), Math.round(y + outHeight));
     }
 
-    public static int getShelfTrackingDistance(DeviceProfile dp) {
+    public static int getShelfTrackingDistance(Context context, DeviceProfile dp) {
+        if (FeatureFlags.SWIPE_HOME.get()) {
+            // Track the bottom of the window rather than the top of the shelf.
+            int shelfHeight = dp.hotseatBarSizePx + dp.getInsets().bottom;
+            int spaceBetweenShelfAndRecents = (int) context.getResources().getDimension(
+                    R.dimen.task_card_vert_space);
+            return shelfHeight + spaceBetweenShelfAndRecents;
+        }
         // Start from a third of bottom inset to provide some shelf overlap.
         return dp.hotseatBarSizePx + dp.getInsets().bottom / 3 - dp.edgeMarginPx * 2;
     }
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
index 48b07a7..10283bf 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewDrawable.java
@@ -53,6 +53,7 @@
     private final RecentsView mParent;
     private final View mIconView;
     private final int[] mIconPos;
+    private final TaskView mTaskView;
 
     private final TaskThumbnailView mThumbnailView;
 
@@ -65,13 +66,14 @@
 
     public TaskViewDrawable(TaskView tv, RecentsView parent) {
         mParent = parent;
+        mTaskView = tv;
         mIconView = tv.getIconView();
         mIconPos = new int[2];
         mIconScale = mIconView.getScaleX();
         Utilities.getDescendantCoordRelativeToAncestor(mIconView, parent, mIconPos, true);
 
         mThumbnailView = tv.getThumbnail();
-        mClipAnimationHelper = new ClipAnimationHelper();
+        mClipAnimationHelper = new ClipAnimationHelper(parent.getContext());
         mClipAnimationHelper.fromTaskThumbnailView(mThumbnailView, parent);
     }
 
@@ -139,4 +141,8 @@
     public int getOpacity() {
         return PixelFormat.TRANSLUCENT;
     }
+
+    public TaskView getTaskView() {
+        return mTaskView;
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
new file mode 100644
index 0000000..aafd725
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java
@@ -0,0 +1,225 @@
+/*
+ * 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 android.app.ActivityOptions;
+import android.content.ActivityNotFoundException;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.LauncherApps;
+import android.content.res.Resources;
+import android.icu.text.MeasureFormat;
+import android.icu.text.MeasureFormat.FormatWidth;
+import android.icu.util.Measure;
+import android.icu.util.MeasureUnit;
+import android.os.UserHandle;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import androidx.annotation.StringRes;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.systemui.shared.recents.model.Task;
+
+import java.lang.reflect.Method;
+import java.time.Duration;
+import java.util.Locale;
+
+public final class DigitalWellBeingToast extends LinearLayout {
+    public interface InitializeCallback {
+        void call(float saturation, String contentDescription);
+    }
+
+    private static final String TAG = DigitalWellBeingToast.class.getSimpleName();
+
+    private Task mTask;
+    private ImageView mImage;
+    private TextView mText;
+
+    public DigitalWellBeingToast(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setLayoutDirection(Utilities.isRtl(getResources()) ?
+                View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
+        setOnClickListener((view) -> openAppUsageSettings());
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+
+        mText = findViewById(R.id.digital_well_being_remaining_time);
+        mImage = findViewById(R.id.digital_well_being_hourglass);
+    }
+
+    public void initialize(Task task, InitializeCallback callback) {
+        mTask = task;
+        Utilities.THREAD_POOL_EXECUTOR.execute(() -> {
+            long appUsageLimitTimeMs = -1;
+            long appRemainingTimeMs = -1;
+            boolean isGroupLimit = true;
+
+            try {
+                final Method getAppUsageLimit = LauncherApps.class.getMethod(
+                        "getAppUsageLimit",
+                        String.class,
+                        UserHandle.class);
+                final Object usageLimit = getAppUsageLimit.invoke(
+                        getContext().getSystemService(LauncherApps.class),
+                        task.getTopComponent().getPackageName(),
+                        UserHandle.of(task.key.userId));
+
+                if (usageLimit != null) {
+                    final Class appUsageLimitClass = usageLimit.getClass();
+                    appUsageLimitTimeMs = (long) appUsageLimitClass.getMethod("getTotalUsageLimit").
+                            invoke(usageLimit);
+                    appRemainingTimeMs = (long) appUsageLimitClass.getMethod("getUsageRemaining").
+                            invoke(usageLimit);
+                    isGroupLimit = (boolean) appUsageLimitClass.getMethod("isGroupLimit").
+                            invoke(usageLimit);
+                }
+            } catch (Exception e) {
+                // Do nothing
+            }
+
+            final long appUsageLimitTimeMsFinal = appUsageLimitTimeMs;
+            final long appRemainingTimeMsFinal = appRemainingTimeMs;
+            final boolean isGroupLimitFinal = isGroupLimit;
+
+            post(() -> {
+                if (appUsageLimitTimeMsFinal < 0) {
+                    setVisibility(GONE);
+                } else {
+                    setVisibility(VISIBLE);
+                    mText.setText(getText(appRemainingTimeMsFinal, isGroupLimitFinal));
+                    mImage.setImageResource(appRemainingTimeMsFinal > 0 ?
+                            R.drawable.hourglass_top : R.drawable.hourglass_bottom);
+                }
+
+                callback.call(
+                        appUsageLimitTimeMsFinal >= 0 && appRemainingTimeMsFinal <= 0 ? 0 : 1,
+                        getContentDescriptionForTask(
+                                task, appUsageLimitTimeMsFinal,
+                                appRemainingTimeMsFinal,
+                                isGroupLimitFinal));
+            });
+        });
+    }
+
+    private String getReadableDuration(
+            Duration duration,
+            FormatWidth formatWidthHourAndMinute,
+            @StringRes int durationLessThanOneMinuteStringId,
+            boolean forceFormatWidth) {
+        int hours = Math.toIntExact(duration.toHours());
+        int minutes = Math.toIntExact(duration.minusHours(hours).toMinutes());
+
+        // Apply formatWidthHourAndMinute if both the hour part and the minute part are non-zero.
+        if (hours > 0 && minutes > 0) {
+            return MeasureFormat.getInstance(Locale.getDefault(), formatWidthHourAndMinute)
+                    .formatMeasures(
+                            new Measure(hours, MeasureUnit.HOUR),
+                            new Measure(minutes, MeasureUnit.MINUTE));
+        }
+
+        // Apply formatWidthHourOrMinute if only the hour part is non-zero (unless forced).
+        if (hours > 0) {
+            return MeasureFormat.getInstance(
+                    Locale.getDefault(),
+                    forceFormatWidth ? formatWidthHourAndMinute : FormatWidth.WIDE)
+                    .formatMeasures(new Measure(hours, MeasureUnit.HOUR));
+        }
+
+        // Apply formatWidthHourOrMinute if only the minute part is non-zero (unless forced).
+        if (minutes > 0) {
+            return MeasureFormat.getInstance(
+                    Locale.getDefault()
+                    , forceFormatWidth ? formatWidthHourAndMinute : FormatWidth.WIDE)
+                    .formatMeasures(new Measure(minutes, MeasureUnit.MINUTE));
+        }
+
+        // Use a specific string for usage less than one minute but non-zero.
+        if (duration.compareTo(Duration.ZERO) > 0) {
+            return getResources().getString(durationLessThanOneMinuteStringId);
+        }
+
+        // Otherwise, return 0-minute string.
+        return MeasureFormat.getInstance(
+                Locale.getDefault(), forceFormatWidth ? formatWidthHourAndMinute : FormatWidth.WIDE)
+                .formatMeasures(new Measure(0, MeasureUnit.MINUTE));
+    }
+
+    private String getReadableDuration(
+            Duration duration,
+            FormatWidth formatWidthHourAndMinute,
+            @StringRes int durationLessThanOneMinuteStringId) {
+        return getReadableDuration(
+                duration,
+                formatWidthHourAndMinute,
+                durationLessThanOneMinuteStringId,
+                /* forceFormatWidth= */ false);
+    }
+
+    private String getShorterReadableDuration(Duration duration) {
+        return getReadableDuration(
+                duration, FormatWidth.NARROW, R.string.shorter_duration_less_than_one_minute);
+    }
+
+    private String getText(long remainingTime, boolean isGroupLimit) {
+        final Resources resources = getResources();
+        return (remainingTime <= 0) ?
+                resources.getString(R.string.app_in_grayscale) :
+                resources.getString(
+                        isGroupLimit ? R.string.time_left_for_group : R.string.time_left_for_app,
+                        getShorterReadableDuration(Duration.ofMillis(remainingTime)));
+    }
+
+    public void openAppUsageSettings() {
+        final Intent intent = new Intent(TaskView.SEE_TIME_IN_APP_TEMPLATE)
+                .putExtra(Intent.EXTRA_PACKAGE_NAME,
+                        mTask.getTopComponent().getPackageName()).addFlags(
+                        Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+        try {
+            final Launcher launcher = Launcher.getLauncher(getContext());
+            final ActivityOptions options = ActivityOptions.makeScaleUpAnimation(
+                    this, 0, 0,
+                    getWidth(), getHeight());
+            launcher.startActivity(intent, options.toBundle());
+            launcher.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP,
+                    LauncherLogProto.ControlType.APP_USAGE_SETTINGS, this);
+        } catch (ActivityNotFoundException e) {
+            Log.e(TAG, "Failed to open app usage settings for task "
+                    + mTask.getTopComponent().getPackageName(), e);
+        }
+    }
+
+    private String getContentDescriptionForTask(
+            Task task, long appUsageLimitTimeMs, long appRemainingTimeMs, boolean isGroupLimit) {
+        return appUsageLimitTimeMs >= 0 ?
+                getResources().getString(
+                        R.string.task_contents_description_with_remaining_time,
+                        task.titleDescription,
+                        getText(appRemainingTimeMs, isGroupLimit)) :
+                task.titleDescription;
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java b/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java
index c12a579..a8205cd 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherLayoutListener.java
@@ -16,6 +16,7 @@
 package com.android.quickstep.views;
 
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.launcher3.states.RotationHelper.REQUEST_NONE;
 
 import android.graphics.Canvas;
@@ -39,32 +40,61 @@
 public class LauncherLayoutListener extends AbstractFloatingView
         implements Insettable, LayoutListener {
 
+    public static LauncherLayoutListener resetAndGet(Launcher launcher) {
+        LauncherRecentsView lrv = launcher.getOverviewPanel();
+        LauncherLayoutListener listener = lrv.mLauncherLayoutListener;
+        if (listener.isOpen()) {
+            listener.close(false);
+        }
+        listener.setHandler(null);
+        return listener;
+    }
+
     private final Launcher mLauncher;
     private final Paint mPaint = new Paint();
     private WindowTransformSwipeHandler mHandler;
     private RectF mCurrentRect;
+    private float mCornerRadius;
 
-    public LauncherLayoutListener(Launcher launcher) {
+    private boolean mWillNotDraw;
+
+    /**
+     * package private
+     */
+    LauncherLayoutListener(Launcher launcher) {
         super(launcher, null);
         mLauncher = launcher;
         mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
         setLayoutParams(new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+
+        mWillNotDraw = willNotDraw();
+        super.setWillNotDraw(false);
     }
 
     @Override
-    public void update(boolean shouldFinish, boolean isLongSwipe, RectF currentRect) {
-        if (shouldFinish) {
-            finish();
+    public void update(boolean shouldFinish, boolean isLongSwipe, RectF currentRect,
+                  float cornerRadius) {
+        if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            if (shouldFinish) {
+                finish();
+            }
             return;
         }
 
         mCurrentRect = currentRect;
+        mCornerRadius = cornerRadius;
 
         setWillNotDraw(mCurrentRect == null || isLongSwipe);
         invalidate();
     }
 
     @Override
+    public void setWillNotDraw(boolean willNotDraw) {
+        // Prevent super call as that causes additional relayout.
+        mWillNotDraw = willNotDraw;
+    }
+
+    @Override
     public void setHandler(WindowTransformSwipeHandler handler) {
         mHandler = handler;
     }
@@ -121,6 +151,8 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        canvas.drawRect(mCurrentRect, mPaint);
+        if (!mWillNotDraw) {
+            canvas.drawRoundRect(mCurrentRect, mCornerRadius, mCornerRadius, mPaint);
+        }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
index 697bb4f..722c721 100644
--- a/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -15,10 +15,12 @@
  */
 package com.android.quickstep.views;
 
+import static com.android.launcher3.AbstractFloatingView.TYPE_QUICKSTEP_PREVIEW;
 import static com.android.launcher3.LauncherAppTransitionManagerImpl.ALL_APPS_PROGRESS_OFF_SCREEN;
 import static com.android.launcher3.LauncherState.ALL_APPS_HEADER_EXTRA;
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PROGRESS;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
@@ -32,6 +34,8 @@
 import android.view.View;
 import android.view.ViewDebug;
 
+import com.android.launcher3.AbstractFloatingView;
+import com.android.launcher3.BaseActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherState;
@@ -40,6 +44,7 @@
 import com.android.launcher3.views.ScrimView;
 import com.android.quickstep.OverviewInteractionState;
 import com.android.quickstep.util.ClipAnimationHelper;
+import com.android.quickstep.util.ClipAnimationHelper.TransformParams;
 import com.android.quickstep.util.LayoutUtils;
 
 /**
@@ -62,9 +67,16 @@
                 }
             };
 
+    /**
+     * A ratio representing the view's relative placement within its padded space. For example, 0
+     * is top aligned and 0.5 is centered vertically.
+     */
     @ViewDebug.ExportedProperty(category = "launcher")
     private float mTranslationYFactor;
 
+    private final TransformParams mTransformParams = new TransformParams();
+    final LauncherLayoutListener mLauncherLayoutListener;
+
     public LauncherRecentsView(Context context) {
         this(context, null);
     }
@@ -76,11 +88,17 @@
     public LauncherRecentsView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         setContentAlpha(0);
+        mLauncherLayoutListener = new LauncherLayoutListener(BaseActivity.fromContext(context));
     }
 
     @Override
     protected void startHome() {
-        mActivity.getStateManager().goToState(NORMAL);
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            takeScreenshotAndFinishRecentsAnimation(true,
+                    () -> mActivity.getStateManager().goToState(NORMAL));
+        } else {
+            mActivity.getStateManager().goToState(NORMAL);
+        }
     }
 
     @Override
@@ -92,6 +110,9 @@
     public void setTranslationYFactor(float translationFactor) {
         mTranslationYFactor = translationFactor;
         setTranslationY(computeTranslationYForFactor(mTranslationYFactor));
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            redrawLiveTile(false);
+        }
     }
 
     public float computeTranslationYForFactor(float translationYFactor) {
@@ -168,4 +189,45 @@
     public boolean shouldUseMultiWindowTaskSizeStrategy() {
         return mActivity.isInMultiWindowModeCompat();
     }
+
+    @Override
+    public void scrollTo(int x, int y) {
+        super.scrollTo(x, y);
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile) {
+            redrawLiveTile(true);
+        }
+    }
+
+    @Override
+    public void redrawLiveTile(boolean mightNeedToRefill) {
+        AbstractFloatingView layoutListener = AbstractFloatingView.getTopOpenViewWithType(
+                mActivity, TYPE_QUICKSTEP_PREVIEW);
+        if (layoutListener != null && layoutListener.isOpen()) {
+            return;
+        }
+        if (mRecentsAnimationWrapper == null || mClipAnimationHelper == null) {
+            return;
+        }
+        TaskView taskView = getRunningTaskView();
+        if (taskView != null) {
+            taskView.getThumbnail().getGlobalVisibleRect(mTempRect);
+            int offsetX = (int) (mTaskWidth * taskView.getScaleX() * getScaleX()
+                    - mTempRect.width());
+            int offsetY = (int) (mTaskHeight * taskView.getScaleY() * getScaleY()
+                    - mTempRect.height());
+            if (((mCurrentPage != 0) || mightNeedToRefill) && offsetX > 0) {
+                mTempRect.right += offsetX;
+            }
+            if (mightNeedToRefill && offsetY > 0) {
+                mTempRect.top -= offsetY;
+            }
+            mTempRectF.set(mTempRect);
+            mTransformParams.setCurrentRectAndTargetAlpha(mTempRectF, taskView.getAlpha())
+                    .setSyncTransactionApplier(mSyncTransactionApplier);
+            if (mRecentsAnimationWrapper.targetSet != null) {
+                mClipAnimationHelper.applyTransform(mRecentsAnimationWrapper.targetSet,
+                        mTransformParams);
+            }
+        }
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index cbbd181..5cbae65 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -17,14 +17,17 @@
 package com.android.quickstep.views;
 
 import static com.android.launcher3.BaseActivity.STATE_HANDLER_INVISIBILITY_FLAGS;
+import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
 import static com.android.launcher3.anim.Interpolators.ACCEL;
 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.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
+import static com.android.launcher3.uioverrides.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
+import static com.android.quickstep.util.ClipAnimationHelper.TransformParams;
 import static com.android.launcher3.util.SystemUiController.UI_STATE_OVERVIEW;
 import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId;
-import static com.android.quickstep.WindowTransformSwipeHandler.MIN_PROGRESS_FOR_OVERVIEW;
-
+import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
 import android.animation.Animator;
 import android.animation.AnimatorSet;
 import android.animation.LayoutTransition;
@@ -40,6 +43,7 @@
 import android.graphics.Canvas;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Handler;
@@ -61,9 +65,12 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.widget.ListView;
 
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Insettable;
+import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.PagedView;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -74,8 +81,10 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
 import com.android.launcher3.util.PendingAnimation;
 import com.android.launcher3.util.Themes;
+import com.android.launcher3.util.ViewPool;
 import com.android.quickstep.OverviewCallbacks;
 import com.android.quickstep.QuickScrubController;
+import com.android.quickstep.RecentsAnimationWrapper;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.TaskThumbnailCache;
 import com.android.quickstep.TaskUtils;
@@ -86,19 +95,21 @@
 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.RecentsAnimationControllerCompat;
+import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
 import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.shared.system.WindowCallbacksCompat;
 
 import java.util.ArrayList;
 import java.util.function.Consumer;
 
-import androidx.annotation.Nullable;
-
 /**
  * A list of recent tasks.
  */
 @TargetApi(Build.VERSION_CODES.P)
 public abstract class RecentsView<T extends BaseActivity> extends PagedView implements Insettable,
-        TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback {
+        TaskThumbnailCache.HighResLoadingState.HighResLoadingStateChangedCallback,
+        InvariantDeviceProfile.OnIDPChangeListener {
 
     private static final String TAG = RecentsView.class.getSimpleName();
 
@@ -115,7 +126,14 @@
                 }
             };
 
-    private final Rect mTempRect = new Rect();
+    protected RecentsAnimationWrapper mRecentsAnimationWrapper;
+    protected ClipAnimationHelper mClipAnimationHelper;
+    protected SyncRtSurfaceTransactionApplierCompat mSyncTransactionApplier;
+    protected int mTaskWidth;
+    protected int mTaskHeight;
+    protected boolean mEnableDrawingLiveTile = false;
+    protected final Rect mTempRect = new Rect();
+    protected final RectF mTempRectF = new RectF();
 
     private static final int DISMISS_TASK_DURATION = 300;
     private static final int ADDITION_TASK_DURATION = 200;
@@ -137,6 +155,10 @@
     // Keeps track of the previously known visible tasks for purposes of loading/unloading task data
     private final SparseBooleanArray mHasVisibleTaskData = new SparseBooleanArray();
 
+    private final InvariantDeviceProfile mIdp;
+
+    private final ViewPool<TaskView> mTaskViewPool;
+
     /**
      * TODO: Call reloadIdNeeded in onTaskStackChanged.
      */
@@ -279,10 +301,15 @@
         mActivity = (T) BaseActivity.fromContext(context);
         mQuickScrubController = new QuickScrubController(mActivity, this);
         mModel = RecentsModel.INSTANCE.get(context);
+        mIdp = InvariantDeviceProfile.INSTANCE.get(context);
+
         mClearAllButton = (ClearAllButton) LayoutInflater.from(context)
                 .inflate(R.layout.overview_clear_all_button, this, false);
         mClearAllButton.setOnClickListener(this::dismissAllTasks);
 
+        mTaskViewPool = new ViewPool<>(context, this, R.layout.task, 20 /* max size */,
+                10 /* initial size */);
+
         mIsRtl = !Utilities.isRtl(getResources());
         setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR);
         mTaskTopMargin = getResources()
@@ -321,12 +348,23 @@
     }
 
     @Override
+    public void onIdpChanged(int changeFlags, InvariantDeviceProfile idp) {
+        if ((changeFlags & CHANGE_FLAG_ICON_PARAMS) == 0) {
+            return;
+        }
+        mModel.getIconCache().clear();
+        reset();
+    }
+
+    @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         updateTaskStackListenerState();
         mModel.getThumbnailCache().getHighResLoadingState().addCallback(this);
         mActivity.addMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
         ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
+        mSyncTransactionApplier = new SyncRtSurfaceTransactionApplierCompat(this);
+        mIdp.addOnChangeListener(this);
     }
 
     @Override
@@ -336,6 +374,8 @@
         mModel.getThumbnailCache().getHighResLoadingState().removeCallback(this);
         mActivity.removeMultiWindowModeChangedListener(mMultiWindowModeChangedListener);
         ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
+        mSyncTransactionApplier = null;
+        mIdp.removeOnChangeListener(this);
     }
 
     @Override
@@ -350,6 +390,7 @@
                 mHasVisibleTaskData.delete(task.key.id);
                 taskView.onTaskListVisibilityChanged(false /* visible */);
             }
+            mTaskViewPool.recycle(taskView);
         }
     }
 
@@ -422,7 +463,8 @@
                         final boolean clearAllButtonDeadZoneConsumed =
                                 mClearAllButton.getAlpha() == 1
                                         && mClearAllButtonDeadZoneRect.contains(x, y);
-                        if (!clearAllButtonDeadZoneConsumed
+                        final boolean cameFromNavBar = (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0;
+                        if (!clearAllButtonDeadZoneConsumed && !cameFromNavBar
                                 && !mTaskViewDeadZoneRect.contains(x + getScrollX(), y)) {
                             mTouchDownToStartHome = true;
                         }
@@ -452,10 +494,6 @@
 
         int oldChildCount = getChildCount();
 
-        // Ensure there are as many views as there are tasks in the stack (adding and trimming as
-        // necessary)
-        final LayoutInflater inflater = LayoutInflater.from(getContext());
-
         // Unload existing visible task data
         unloadVisibleTaskData();
 
@@ -468,7 +506,7 @@
                 removeView(mClearAllButton);
             }
             for (int i = getChildCount(); i < requiredTaskCount; i++) {
-                addView(inflater.inflate(R.layout.task, this, false));
+                addView(mTaskViewPool.getView());
             }
             while (getChildCount() > requiredTaskCount) {
                 removeView(getChildAt(getChildCount() - 1));
@@ -485,6 +523,11 @@
             final TaskView taskView = (TaskView) getChildAt(pageIndex);
             taskView.bind(task);
         }
+        TaskView runningTaskView = getRunningTaskView();
+        if (runningTaskView != null) {
+            setCurrentPage(indexOfChild(runningTaskView));
+        }
+
         if (mIgnoreResetTaskId != -1 && getTaskView(mIgnoreResetTaskId) != ignoreRestTaskView) {
             // If the taskView mapping is changing, do not preserve the visuals. Since we are
             // mostly preserving the first task, and new taskViews are added to the end, it should
@@ -544,12 +587,14 @@
         mInsets.set(insets);
         DeviceProfile dp = mActivity.getDeviceProfile();
         getTaskSize(dp, mTempRect);
+        mTaskWidth = mTempRect.width();
+        mTaskHeight = mTempRect.height();
 
         // Keep this logic in sync with ActivityControlHelper.getTranslationYForQuickScrub.
         mTempRect.top -= mTaskTopMargin;
         setPadding(mTempRect.left - mInsets.left, mTempRect.top - mInsets.top,
-                dp.availableWidthPx + mInsets.left - mTempRect.right,
-                dp.availableHeightPx + mInsets.top - mTempRect.bottom);
+                dp.widthPx - mInsets.right - mTempRect.right,
+                dp.heightPx - mInsets.bottom - mTempRect.bottom);
     }
 
     protected abstract void getTaskSize(DeviceProfile dp, Rect outRect);
@@ -677,11 +722,15 @@
     protected abstract void startHome();
 
     public void reset() {
+        setRunningTaskViewShowScreenshot(false);
         mRunningTaskId = -1;
         mRunningTaskTileHidden = false;
         mIgnoreResetTaskId = -1;
         mTaskListChangeId = -1;
 
+        mRecentsAnimationWrapper = null;
+        mClipAnimationHelper = null;
+
         unloadVisibleTaskData();
         setCurrentPage(0);
 
@@ -708,8 +757,7 @@
     public void showTask(int runningTaskId) {
         if (getChildCount() == 0) {
             // Add an empty view for now until the task plan is loaded and applied
-            final TaskView taskView = (TaskView) LayoutInflater.from(getContext())
-                    .inflate(R.layout.task, this, false);
+            final TaskView taskView = mTaskViewPool.getView();
             addView(taskView);
             addView(mClearAllButton);
 
@@ -728,6 +776,11 @@
         return getTaskView(mRunningTaskId);
     }
 
+    public int getRunningTaskIndex() {
+        TaskView tv = getRunningTaskView();
+        return tv == null ? -1 : indexOfChild(tv);
+    }
+
     /**
      * Hides the tile associated with {@link #mRunningTaskId}
      */
@@ -748,29 +801,40 @@
 
         setRunningTaskIconScaledDown(false);
         setRunningTaskHidden(false);
+        setRunningTaskViewShowScreenshot(true);
         mRunningTaskId = runningTaskId;
+        setRunningTaskViewShowScreenshot(false);
         setRunningTaskIconScaledDown(runningTaskIconScaledDown);
         setRunningTaskHidden(runningTaskTileHidden);
 
-        setCurrentPage(0);
+        setCurrentPage(getRunningTaskIndex());
 
         // Load the tasks (if the loading is already
         mTaskListChangeId = mModel.getTasks(this::applyLoadPlan);
     }
 
+    private void setRunningTaskViewShowScreenshot(boolean showScreenshot) {
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            TaskView runningTaskView = getRunningTaskView();
+            if (runningTaskView != null) {
+                runningTaskView.setShowScreenshot(showScreenshot);
+            }
+        }
+    }
+
     public void showNextTask() {
         TaskView runningTaskView = getRunningTaskView();
         if (runningTaskView == null) {
             // Launch the first task
             if (getTaskViewCount() > 0) {
-                ((TaskView) getChildAt(0)).launchTask(true /* animate */);
+                getTaskViewAt(0).launchTask(true /* animate */);
             }
         } else {
-            // Get the next launch task
-            int runningTaskIndex = indexOfChild(runningTaskView);
-            int nextTaskIndex = Math.max(0, Math.min(getTaskViewCount() - 1, runningTaskIndex + 1));
-            if (nextTaskIndex < getTaskViewCount()) {
-                ((TaskView) getChildAt(nextTaskIndex)).launchTask(true /* animate */);
+            TaskView nextTaskView = getNextTaskView();
+            if (nextTaskView != null) {
+                nextTaskView.launchTask(true /* animate */);
+            } else {
+                runningTaskView.launchTask(true /* animate */);
             }
         }
     }
@@ -893,8 +957,8 @@
 
     public PendingAnimation createTaskDismissAnimation(TaskView taskView, boolean animateTaskView,
             boolean shouldRemoveTask, long duration) {
-        if (FeatureFlags.IS_DOGFOOD_BUILD && mPendingAnimation != null) {
-            throw new IllegalStateException("Another pending animation is still running");
+        if (mPendingAnimation != null) {
+            mPendingAnimation.finish(false, Touch.SWIPE);
         }
         AnimatorSet anim = new AnimatorSet();
         PendingAnimation pendingAnimation = new PendingAnimation(anim);
@@ -965,26 +1029,40 @@
         }
 
         mPendingAnimation = pendingAnimation;
-        mPendingAnimation.addEndListener((onEndListener) -> {
-           if (onEndListener.isSuccess) {
-               if (shouldRemoveTask) {
-                   removeTask(taskView.getTask(), draggedIndex, onEndListener, true);
-               }
-               int pageToSnapTo = mCurrentPage;
-               if (draggedIndex < pageToSnapTo || pageToSnapTo == (getTaskViewCount() - 1)) {
-                   pageToSnapTo -= 1;
-               }
-               removeView(taskView);
+        mPendingAnimation.addEndListener(new Consumer<PendingAnimation.OnEndListener>() {
+            @Override
+            public void accept(PendingAnimation.OnEndListener onEndListener) {
+                if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
+                        taskView.isRunningTask() && onEndListener.isSuccess) {
+                    finishRecentsAnimation(true /* toHome */, () -> onEnd(onEndListener));
+                } else {
+                    onEnd(onEndListener);
+                }
+            }
 
-               if (getTaskViewCount() == 0) {
-                   removeView(mClearAllButton);
-                   startHome();
-               } else {
-                   snapToPageImmediately(pageToSnapTo);
-               }
-           }
-           resetTaskVisuals();
-           mPendingAnimation = null;
+            private void onEnd(PendingAnimation.OnEndListener onEndListener) {
+                if (onEndListener.isSuccess) {
+                    if (shouldRemoveTask) {
+                        removeTask(taskView.getTask(), draggedIndex, onEndListener, true);
+                    }
+
+                    int pageToSnapTo = mCurrentPage;
+                    if (draggedIndex < pageToSnapTo ||
+                            pageToSnapTo == (getTaskViewCount() - 1)) {
+                        pageToSnapTo -= 1;
+                    }
+                    removeView(taskView);
+
+                    if (getTaskViewCount() == 0) {
+                        removeView(mClearAllButton);
+                        startHome();
+                    } else {
+                        snapToPageImmediately(pageToSnapTo);
+                    }
+                }
+                resetTaskVisuals();
+                mPendingAnimation = null;
+            }
         });
         return pendingAnimation;
     }
@@ -1143,6 +1221,19 @@
         child.setAlpha(mContentAlpha);
     }
 
+    /**
+     * @return The most recent task that is older than the currently running task. If there is
+     * currently no running task or there is no task older than it, then return null.
+     */
+    @Nullable
+    public TaskView getNextTaskView() {
+        TaskView runningTaskView = getRunningTaskView();
+        if (runningTaskView == null) {
+            return null;
+        }
+        return getTaskViewAt(indexOfChild(runningTaskView) + 1);
+    }
+
     public TaskView getTaskViewAt(int index) {
         View child = getChildAt(index);
         return child == mClearAllButton ? null : (TaskView) child;
@@ -1264,12 +1355,14 @@
                         toScale, toTranslationY);
                 scaleAndTranslation[1] = -scaleAndTranslation[1];
                 anim.play(createAnimForChild(adjacentTask, scaleAndTranslation));
+                anim.play(ObjectAnimator.ofFloat(adjacentTask, TaskView.FULLSCREEN_PROGRESS, 1));
             }
             if (taskIndex + 1 < getTaskViewCount()) {
                 TaskView adjacentTask = getTaskViewAt(taskIndex + 1);
                 float[] scaleAndTranslation = getAdjacentScaleAndTranslation(centerTask,
                         toScale, toTranslationY);
                 anim.play(createAnimForChild(adjacentTask, scaleAndTranslation));
+                anim.play(ObjectAnimator.ofFloat(adjacentTask, TaskView.FULLSCREEN_PROGRESS, 1));
             }
         } else {
             // We are launching an adjacent task, so parallax the center and other adjacent task.
@@ -1317,20 +1410,38 @@
         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);
+        drawableAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+            TransformParams mParams = new TransformParams();
 
-            // Passing the threshold from taskview to fullscreen app will vibrate
-            final boolean passed = animator.getAnimatedFraction() >= MIN_PROGRESS_FOR_OVERVIEW;
-            if (passed != passedOverviewThreshold[0]) {
-                passedOverviewThreshold[0] = passed;
-                performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
-                        HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+            @Override
+            public void onAnimationUpdate(ValueAnimator 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);
+                if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+                    if (mRecentsAnimationWrapper.targetSet != null
+                            && drawable.getTaskView().isRunningTask()) {
+                        mParams.setProgress(1 - animator.getAnimatedFraction())
+                                .setSyncTransactionApplier(mSyncTransactionApplier)
+                                .setForLiveTile(true);
+                        drawable.getClipAnimationHelper().applyTransform(
+                                mRecentsAnimationWrapper.targetSet, mParams);
+                    } else {
+                        redrawLiveTile(true);
+                    }
+                }
+
+                // Passing the threshold from taskview to fullscreen app will vibrate
+                final boolean passed = animator.getAnimatedFraction() >=
+                        SUCCESS_TRANSITION_PROGRESS;
+                if (passed != passedOverviewThreshold[0]) {
+                    passedOverviewThreshold[0] = passed;
+                    performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
+                            HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
+                }
             }
         });
 
@@ -1429,4 +1540,74 @@
     protected boolean isPageOrderFlipped() {
         return true;
     }
+
+    public void setEnableDrawingLiveTile(boolean enableDrawingLiveTile) {
+        mEnableDrawingLiveTile = enableDrawingLiveTile;
+    }
+
+    public void redrawLiveTile(boolean mightNeedToRefill) { }
+
+    public void setRecentsAnimationWrapper(RecentsAnimationWrapper recentsAnimationWrapper) {
+        mRecentsAnimationWrapper = recentsAnimationWrapper;
+    }
+
+    public void setClipAnimationHelper(ClipAnimationHelper clipAnimationHelper) {
+        mClipAnimationHelper = clipAnimationHelper;
+    }
+
+    public void finishRecentsAnimation(boolean toHome, Runnable onFinishComplete) {
+        if (mRecentsAnimationWrapper == null) {
+            if (onFinishComplete != null) {
+                onFinishComplete.run();
+            }
+            return;
+        }
+
+        mRecentsAnimationWrapper.finish(toHome, onFinishComplete);
+    }
+
+    public void takeScreenshotAndFinishRecentsAnimation(boolean toHome, Runnable onFinishComplete) {
+        if (mRecentsAnimationWrapper == null || getRunningTaskView() == null) {
+            if (onFinishComplete != null) {
+                onFinishComplete.run();
+            }
+            return;
+        }
+
+        RecentsAnimationControllerCompat controller = mRecentsAnimationWrapper.getController();
+        if (controller != null) {
+            // Update the screenshot of the task
+            ThumbnailData taskSnapshot = controller.screenshotTask(mRunningTaskId);
+            TaskView taskView = updateThumbnail(mRunningTaskId, taskSnapshot);
+            if (taskView != null) {
+                taskView.setShowScreenshot(true);
+                // Defer finishing the animation until the next launcher frame with the
+                // new thumbnail
+                new WindowCallbacksCompat(taskView) {
+
+                    // The number of frames to defer until we actually finish the animation
+                    private int mDeferFrameCount = 2;
+
+                    @Override
+                    public void onPostDraw(Canvas canvas) {
+                        if (mDeferFrameCount > 0) {
+                            mDeferFrameCount--;
+                            // Workaround, detach and reattach to invalidate the root node for
+                            // another draw
+                            detach();
+                            attach();
+                            taskView.invalidate();
+                            return;
+                        }
+
+                        detach();
+                        mRecentsAnimationWrapper.finish(toHome, () -> {
+                            onFinishComplete.run();
+                            mRunningTaskId = -1;
+                        });
+                    }
+                }.attach();
+            }
+        }
+    }
 }
diff --git a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
index 8965575..d2b3bcc 100644
--- a/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
+++ b/quickstep/src/com/android/quickstep/views/ShelfScrimView.java
@@ -18,8 +18,7 @@
 import static com.android.launcher3.LauncherState.OVERVIEW;
 import static com.android.launcher3.anim.Interpolators.ACCEL;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
-
-import static androidx.core.graphics.ColorUtils.setAlphaComponent;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
 import android.content.Context;
 import android.graphics.Canvas;
@@ -141,7 +140,7 @@
 
             int alpha = Math.round(Utilities.mapToRange(
                     mProgress, mMidProgress, 1, mMidAlpha, 0, ACCEL));
-            mShelfColor = setAlphaComponent(mEndScrim, alpha);
+            mShelfColor = setColorAlphaBound(mEndScrim, alpha);
         } else {
             mDragHandleOffset += mShiftRange * (mMidProgress - mProgress);
 
@@ -149,12 +148,12 @@
             int alpha = Math.round(
                     Utilities.mapToRange(mProgress, (float) 0, mMidProgress, (float) mEndAlpha,
                             (float) mMidAlpha, Interpolators.clampToProgress(ACCEL, 0.5f, 1f)));
-            mShelfColor = setAlphaComponent(mEndScrim, alpha);
+            mShelfColor = setColorAlphaBound(mEndScrim, alpha);
 
             int remainingScrimAlpha = Math.round(
                     Utilities.mapToRange(mProgress, (float) 0, mMidProgress, mMaxScrimAlpha,
                             (float) 0, LINEAR));
-            mRemainingScreenColor = setAlphaComponent(mScrimColor, remainingScrimAlpha);
+            mRemainingScreenColor = setColorAlphaBound(mScrimColor, remainingScrimAlpha);
         }
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuView.java b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
index 667165b..bea646a 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuView.java
@@ -16,6 +16,7 @@
 
 package com.android.quickstep.views;
 
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.quickstep.views.TaskThumbnailView.DIM_ALPHA;
 
 import android.animation.Animator;
@@ -206,7 +207,13 @@
                 R.layout.task_view_menu_option, this, false);
         menuOption.setIconAndLabelFor(
                 menuOptionView.findViewById(R.id.icon), menuOptionView.findViewById(R.id.text));
-        menuOptionView.setOnClickListener(onClickListener);
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            menuOptionView.setOnClickListener(
+                    view -> mTaskView.getRecentsView().takeScreenshotAndFinishRecentsAnimation(true,
+                            () -> onClickListener.onClick(view)));
+        } else {
+            menuOptionView.setOnClickListener(onClickListener);
+        }
         mOptionLayout.addView(menuOptionView);
     }
 
diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
index c92c8d6..8169d73 100644
--- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java
@@ -16,23 +16,29 @@
 
 package com.android.quickstep.views;
 
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.systemui.shared.system.WindowManagerWrapper.WINDOWING_MODE_FULLSCREEN;
+
 import android.content.Context;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.BitmapShader;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.LightingColorFilter;
+import android.graphics.ColorFilter;
+import android.graphics.ColorMatrix;
+import android.graphics.ColorMatrixColorFilter;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
 import android.graphics.Shader;
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Property;
 import android.view.View;
-import android.view.ViewGroup;
+
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.R;
@@ -50,8 +56,8 @@
  */
 public class TaskThumbnailView extends View {
 
-    private static final LightingColorFilter[] sDimFilterCache = new LightingColorFilter[256];
-    private static final LightingColorFilter[] sHighlightFilterCache = new LightingColorFilter[256];
+    private final static ColorMatrix COLOR_MATRIX = new ColorMatrix();
+    private final static ColorMatrix SATURATION_COLOR_MATRIX = new ColorMatrix();
 
     public static final Property<TaskThumbnailView, Float> DIM_ALPHA =
             new FloatProperty<TaskThumbnailView>("dimAlpha") {
@@ -73,11 +79,14 @@
     private final boolean mIsDarkTextTheme;
     private final Paint mPaint = new Paint();
     private final Paint mBackgroundPaint = new Paint();
+    private final Paint mClearPaint = new Paint();
+    private final Paint mDimmingPaintAfterClearing = new Paint();
 
     private final Matrix mMatrix = new Matrix();
 
     private float mClipBottom = -1;
     private Rect mScaledInsets = new Rect();
+    private boolean mIsRotated;
 
     private Task mTask;
     private ThumbnailData mThumbnailData;
@@ -85,6 +94,7 @@
 
     private float mDimAlpha = 1f;
     private float mDimAlphaMultiplier = 1f;
+    private float mSaturation = 1f;
 
     public TaskThumbnailView(Context context) {
         this(context, null);
@@ -97,15 +107,21 @@
     public TaskThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
         mCornerRadius = getResources().getDimension(R.dimen.task_corner_radius);
-        mOverlay = TaskOverlayFactory.get(context).createOverlay(this);
+        mOverlay = TaskOverlayFactory.INSTANCE.get(context).createOverlay(this);
         mPaint.setFilterBitmap(true);
         mBackgroundPaint.setColor(Color.WHITE);
+        mClearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+        mDimmingPaintAfterClearing.setColor(Color.BLACK);
         mActivity = BaseActivity.fromContext(context);
         mIsDarkTextTheme = Themes.getAttrBoolean(mActivity, R.attr.isWorkspaceDarkText);
     }
 
-    public void bind() {
+    public void bind(Task task) {
         mOverlay.reset();
+        mTask = task;
+        int color = task == null ? Color.BLACK : task.colorBackground | 0xFF000000;
+        mPaint.setColor(color);
+        mBackgroundPaint.setColor(color);
     }
 
     /**
@@ -113,10 +129,6 @@
      */
     public void setThumbnail(Task task, ThumbnailData thumbnailData) {
         mTask = task;
-        int color = task == null ? Color.BLACK : task.colorBackground | 0xFF000000;
-        mPaint.setColor(color);
-        mBackgroundPaint.setColor(color);
-
         if (thumbnailData != null && thumbnailData.thumbnail != null) {
             Bitmap bm = thumbnailData.thumbnail;
             bm.prepareToDraw();
@@ -140,7 +152,7 @@
 
     /**
      * Sets the alpha of the dim layer on top of this view.
-     *
+     * <p>
      * If dimAlpha is 0, no dimming is applied; if dimAlpha is 1, the thumbnail will be black.
      */
     public void setDimAlpha(float dimAlpha) {
@@ -148,6 +160,11 @@
         updateThumbnailPaintFilter();
     }
 
+    public void setSaturation(float saturation) {
+        mSaturation = saturation;
+        updateThumbnailPaintFilter();
+    }
+
     public float getDimAlpha() {
         return mDimAlpha;
     }
@@ -179,13 +196,18 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        if (((TaskView) getParent()).isFullscreen()) {
+        float fullscreenProgress = ((TaskView) getParent()).getFullscreenProgress();
+        if (mIsRotated) {
+            // Don't show insets in the wrong orientation.
+            fullscreenProgress = 0;
+        }
+        if (fullscreenProgress > 0) {
             // Draw the insets if we're being drawn fullscreen (we do this for quick switch).
             drawOnCanvas(canvas,
-                    -mScaledInsets.left,
-                    -mScaledInsets.top,
-                    getMeasuredWidth() + mScaledInsets.right,
-                    getMeasuredHeight() + mScaledInsets.bottom,
+                    -mScaledInsets.left * fullscreenProgress,
+                    -mScaledInsets.top * fullscreenProgress,
+                    getMeasuredWidth() + mScaledInsets.right * fullscreenProgress,
+                    getMeasuredHeight() + mScaledInsets.bottom * fullscreenProgress,
                     mCornerRadius);
         } else {
             drawOnCanvas(canvas, 0, 0, getMeasuredWidth(), getMeasuredHeight(), mCornerRadius);
@@ -198,6 +220,15 @@
 
     public void drawOnCanvas(Canvas canvas, float x, float y, float width, float height,
             float cornerRadius) {
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            if (mTask != null && getTaskView().isRunningTask() && !getTaskView().showScreenshot()) {
+                canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius, mClearPaint);
+                canvas.drawRoundRect(x, y, width, height, cornerRadius, cornerRadius,
+                        mDimmingPaintAfterClearing);
+                return;
+            }
+        }
+
         // Draw the background in all cases, except when the thumbnail data is opaque
         final boolean drawBackgroundOnly = mTask == null || mTask.isLocked || mBitmapShader == null
                 || mThumbnailData == null;
@@ -218,12 +249,17 @@
         }
     }
 
+    protected TaskView getTaskView() {
+        return (TaskView) getParent();
+    }
+
     private void updateThumbnailPaintFilter() {
         int mul = (int) ((1 - mDimAlpha * mDimAlphaMultiplier) * 255);
+        ColorFilter filter = getColorFilter(mul, mIsDarkTextTheme, mSaturation);
+        mBackgroundPaint.setColorFilter(filter);
+        mDimmingPaintAfterClearing.setAlpha(255 - mul);
         if (mBitmapShader != null) {
-            LightingColorFilter filter = getDimmingColorFilter(mul, mIsDarkTextTheme);
             mPaint.setColorFilter(filter);
-            mBackgroundPaint.setColorFilter(filter);
         } else {
             mPaint.setColorFilter(null);
             mPaint.setColor(Color.argb(255, mul, mul, mul));
@@ -232,11 +268,11 @@
     }
 
     private void updateThumbnailMatrix() {
-        boolean rotate = false;
+        mIsRotated = false;
         mClipBottom = -1;
         if (mBitmapShader != null && mThumbnailData != null) {
             float scale = mThumbnailData.scale;
-            Rect thumbnailInsets  = mThumbnailData.insets;
+            Rect thumbnailInsets = mThumbnailData.insets;
             final float thumbnailWidth = mThumbnailData.thumbnail.getWidth() -
                     (thumbnailInsets.left + thumbnailInsets.right) * scale;
             final float thumbnailHeight = mThumbnailData.thumbnail.getHeight() -
@@ -253,12 +289,12 @@
                 final Configuration configuration =
                         getContext().getResources().getConfiguration();
                 // Rotate the screenshot if not in multi-window mode
-                rotate = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
+                mIsRotated = FeatureFlags.OVERVIEW_USE_SCREENSHOT_ORIENTATION &&
                         configuration.orientation != mThumbnailData.orientation &&
                         !mActivity.isInMultiWindowModeCompat() &&
                         mThumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN;
                 // Scale the screenshot to always fit the width of the card.
-                thumbnailScale = rotate
+                thumbnailScale = mIsRotated
                         ? getMeasuredWidth() / thumbnailHeight
                         : getMeasuredWidth() / thumbnailWidth;
             }
@@ -266,7 +302,7 @@
             mScaledInsets.set(thumbnailInsets);
             Utilities.scaleRect(mScaledInsets, thumbnailScale);
 
-            if (rotate) {
+            if (mIsRotated) {
                 int rotationDir = profile.isVerticalBarLayout() && !profile.isSeascape() ? -1 : 1;
                 mMatrix.setRotate(90 * rotationDir);
                 int newLeftInset = rotationDir == 1 ? thumbnailInsets.bottom : thumbnailInsets.top;
@@ -290,7 +326,7 @@
             mMatrix.postScale(thumbnailScale, thumbnailScale);
             mBitmapShader.setLocalMatrix(mMatrix);
 
-            float bitmapHeight = Math.max((rotate ? thumbnailWidth : thumbnailHeight)
+            float bitmapHeight = Math.max((mIsRotated ? thumbnailWidth : thumbnailHeight)
                     * thumbnailScale, 0);
             if (Math.round(bitmapHeight) < getMeasuredHeight()) {
                 mClipBottom = bitmapHeight;
@@ -298,7 +334,7 @@
             mPaint.setShader(mBitmapShader);
         }
 
-        if (rotate) {
+        if (mIsRotated) {
             // The overlay doesn't really work when the screenshot is rotated, so don't add it.
             mOverlay.reset();
         } else {
@@ -313,25 +349,34 @@
         updateThumbnailMatrix();
     }
 
-    private static LightingColorFilter getDimmingColorFilter(int intensity, boolean shouldLighten) {
+    /**
+     * @param intensity multiplier for color values. 0 - make black (white if shouldLighten), 255 -
+     *                  leave unchanged.
+     */
+    private static ColorFilter getColorFilter(int intensity, boolean shouldLighten,
+            float saturation) {
         intensity = Utilities.boundToRange(intensity, 0, 255);
-        if (intensity == 255) {
+
+        if (intensity == 255 && saturation == 1) {
             return null;
         }
-        if (shouldLighten) {
-            if (sHighlightFilterCache[intensity] == null) {
-                int colorAdd = 255 - intensity;
-                sHighlightFilterCache[intensity] = new LightingColorFilter(
-                        Color.argb(255, intensity, intensity, intensity),
-                        Color.argb(255, colorAdd, colorAdd, colorAdd));
-            }
-            return sHighlightFilterCache[intensity];
-        } else {
-            if (sDimFilterCache[intensity] == null) {
-                sDimFilterCache[intensity] = new LightingColorFilter(
-                        Color.argb(255, intensity, intensity, intensity), 0);
-            }
-            return sDimFilterCache[intensity];
+
+        final float intensityScale = intensity / 255f;
+        COLOR_MATRIX.setScale(intensityScale, intensityScale, intensityScale, 1);
+
+        if (saturation != 1) {
+            SATURATION_COLOR_MATRIX.setSaturation(saturation);
+            COLOR_MATRIX.postConcat(SATURATION_COLOR_MATRIX);
         }
+
+        if (shouldLighten) {
+            final float[] colorArray = COLOR_MATRIX.getArray();
+            final int colorAdd = 255 - intensity;
+            colorArray[4] = colorAdd;
+            colorArray[9] = colorAdd;
+            colorArray[14] = colorAdd;
+        }
+
+        return new ColorMatrixColorFilter(COLOR_MATRIX);
     }
 }
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java
index 1e787a2..ad63c24 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/src/com/android/quickstep/views/TaskView.java
@@ -21,13 +21,13 @@
 import static com.android.launcher3.BaseActivity.fromContext;
 import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.app.ActivityOptions;
-import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Resources;
@@ -46,12 +46,13 @@
 import android.widget.Toast;
 
 import com.android.launcher3.BaseDraggingActivity;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.anim.Interpolators;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
+import com.android.launcher3.util.PendingAnimation;
+import com.android.launcher3.util.ViewPool.Reusable;
 import com.android.quickstep.RecentsModel;
 import com.android.quickstep.TaskIconCache;
 import com.android.quickstep.TaskOverlayFactory;
@@ -70,7 +71,7 @@
 /**
  * A task in the Recents view.
  */
-public class TaskView extends FrameLayout implements PageCallbacks {
+public class TaskView extends FrameLayout implements PageCallbacks, Reusable {
 
     private static final String TAG = TaskView.class.getSimpleName();
 
@@ -91,6 +92,7 @@
 
     public static final long SCALE_ICON_DURATION = 120;
     private static final long DIM_ANIM_DURATION = 700;
+    private static final long TASK_LAUNCH_ANIM_DURATION = 200;
 
     public static final Property<TaskView, Float> ZOOM_SCALE =
             new FloatProperty<TaskView>("zoomScale") {
@@ -105,18 +107,31 @@
                 }
             };
 
+    public static final FloatProperty<TaskView> FULLSCREEN_PROGRESS =
+            new FloatProperty<TaskView>("fullscreenProgress") {
+                @Override
+                public void setValue(TaskView taskView, float v) {
+                    taskView.setFullscreenProgress(v);
+                }
+
+                @Override
+                public Float get(TaskView taskView) {
+                    return taskView.mFullscreenProgress;
+                }
+            };
+
     private static final FloatProperty<TaskView> FOCUS_TRANSITION =
             new FloatProperty<TaskView>("focusTransition") {
-        @Override
-        public void setValue(TaskView taskView, float v) {
-            taskView.setIconAndDimTransitionProgress(v);
-        }
+                @Override
+                public void setValue(TaskView taskView, float v) {
+                    taskView.setIconAndDimTransitionProgress(v, false /* invert */);
+                }
 
-        @Override
-        public Float get(TaskView taskView) {
-            return taskView.mFocusTransitionProgress;
-        }
-    };
+                @Override
+                public Float get(TaskView taskView) {
+                    return taskView.mFocusTransitionProgress;
+                }
+            };
 
     static final Intent SEE_TIME_IN_APP_TEMPLATE =
             new Intent("com.android.settings.action.TIME_SPENT_IN_APP");
@@ -140,19 +155,20 @@
     private TaskThumbnailView mSnapshotView;
     private TaskMenuView mMenuView;
     private IconView mIconView;
+    private DigitalWellBeingToast mDigitalWellBeingToast;
     private float mCurveScale;
     private float mZoomScale;
-    private boolean mIsFullscreen;
+    private float mFullscreenProgress;
 
     private Animator mIconAndDimAnimator;
     private float mFocusTransitionProgress = 1;
 
+    private boolean mShowScreenshot;
+
     // The current background requests to load the task thumbnail and icon
     private TaskThumbnailCache.ThumbnailLoadRequest mThumbnailLoadRequest;
     private TaskIconCache.IconLoadRequest mIconLoadRequest;
 
-    private long mAppRemainingTimeMs = -1;
-
     public TaskView(Context context) {
         this(context, null);
     }
@@ -167,7 +183,15 @@
             if (getTask() == null) {
                 return;
             }
-            launchTask(true /* animate */);
+            if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+                if (isRunningTask()) {
+                    createLaunchAnimationForRunningTask().start();
+                } else {
+                    launchTask(true /* animate */);
+                }
+            } else {
+                launchTask(true /* animate */);
+            }
 
             fromContext(context).getUserEventDispatcher().logTaskLaunchOrDismiss(
                     Touch.TAP, Direction.NONE, getRecentsView().indexOfChild(this),
@@ -183,6 +207,7 @@
         super.onFinishInflate();
         mSnapshotView = findViewById(R.id.snapshot);
         mIconView = findViewById(R.id.icon);
+        mDigitalWellBeingToast = findViewById(R.id.digital_well_being_toast);
     }
 
     /**
@@ -190,7 +215,7 @@
      */
     public void bind(Task task) {
         mTask = task;
-        mSnapshotView.bind();
+        mSnapshotView.bind(task);
     }
 
     public Task getTask() {
@@ -209,8 +234,17 @@
         return mSnapshotView.getTaskOverlay();
     }
 
-    private boolean hasRemainingTime() {
-        return mAppRemainingTimeMs > 0;
+    public AnimatorPlaybackController createLaunchAnimationForRunningTask() {
+        final PendingAnimation pendingAnimation =
+                getRecentsView().createTaskLauncherAnimation(this, TASK_LAUNCH_ANIM_DURATION);
+        pendingAnimation.anim.setInterpolator(Interpolators.ZOOM_IN);
+        AnimatorPlaybackController currentAnimation = AnimatorPlaybackController
+                .wrap(pendingAnimation.anim, TASK_LAUNCH_ANIM_DURATION, null);
+        currentAnimation.setEndAction(() -> {
+            pendingAnimation.finish(true, Touch.SWIPE);
+            launchTask(false);
+        });
+        return currentAnimation;
     }
 
     public void launchTask(boolean animate) {
@@ -223,6 +257,21 @@
 
     public void launchTask(boolean animate, Consumer<Boolean> resultCallback,
             Handler resultCallbackHandler) {
+        if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
+            if (isRunningTask()) {
+                getRecentsView().finishRecentsAnimation(false,
+                        () -> resultCallbackHandler.post(() -> resultCallback.accept(true)));
+            } else {
+                getRecentsView().takeScreenshotAndFinishRecentsAnimation(true,
+                        () -> launchTaskInternal(animate, resultCallback, resultCallbackHandler));
+            }
+        } else {
+            launchTaskInternal(animate, resultCallback, resultCallbackHandler);
+        }
+    }
+
+    private void launchTaskInternal(boolean animate, Consumer<Boolean> resultCallback,
+            Handler resultCallbackHandler) {
         if (mTask != null) {
             final ActivityOptions opts;
             if (animate) {
@@ -266,8 +315,13 @@
                     (task) -> mSnapshotView.setThumbnail(task, task.thumbnail));
             mIconLoadRequest = iconCache.updateIconInBackground(mTask,
                     (task) -> {
-                        setContentDescription(task.titleDescription);
                         setIcon(task.icon);
+                        mDigitalWellBeingToast.initialize(
+                                mTask,
+                                (saturation, contentDescription) -> {
+                                    setContentDescription(contentDescription);
+                                    mSnapshotView.setSaturation(saturation);
+                                });
                     });
         } else {
             if (mThumbnailLoadRequest != null) {
@@ -300,15 +354,22 @@
             });
         } else {
             mIconView.setDrawable(null);
+            mIconView.setOnClickListener(null);
             mIconView.setOnLongClickListener(null);
         }
     }
 
-    private void setIconAndDimTransitionProgress(float progress) {
+    private void setIconAndDimTransitionProgress(float progress, boolean invert) {
+        if (invert) {
+            progress = 1 - progress;
+        }
         mFocusTransitionProgress = progress;
         mSnapshotView.setDimAlphaMultipler(progress);
-        float scale = FAST_OUT_SLOW_IN.getInterpolation(Utilities.boundToRange(
-                progress * DIM_ANIM_DURATION / SCALE_ICON_DURATION,  0, 1));
+        float iconScalePercentage = (float) SCALE_ICON_DURATION / DIM_ANIM_DURATION;
+        float lowerClamp = invert ? 1f - iconScalePercentage : 0;
+        float upperClamp = invert ? 1 : iconScalePercentage;
+        float scale = Interpolators.clampToProgress(FAST_OUT_SLOW_IN, lowerClamp, upperClamp)
+                .getInterpolation(progress);
         mIconView.setScaleX(scale);
         mIconView.setScaleY(scale);
     }
@@ -329,13 +390,17 @@
     }
 
     protected void setIconScaleAndDim(float iconScale) {
+        setIconScaleAndDim(iconScale, false);
+    }
+
+    private void setIconScaleAndDim(float iconScale, boolean invert) {
         if (mIconAndDimAnimator != null) {
             mIconAndDimAnimator.cancel();
         }
-        setIconAndDimTransitionProgress(iconScale);
+        setIconAndDimTransitionProgress(iconScale, invert);
     }
 
-    public void resetVisualProperties() {
+    private void resetViewTransforms() {
         setZoomScale(1);
         setTranslationX(0f);
         setTranslationY(0f);
@@ -344,6 +409,20 @@
         setIconScaleAndDim(1);
     }
 
+    public void resetVisualProperties() {
+        resetViewTransforms();
+        if (!getRecentsView().getQuickScrubController().isQuickSwitch()) {
+            // Reset full screen progress unless we are doing back to back quick switch.
+            setFullscreenProgress(0);
+        }
+    }
+
+    @Override
+    public void onRecycle() {
+        resetViewTransforms();
+        setFullscreenProgress(0);
+    }
+
     @Override
     public void onPageScroll(ScrollState scrollState) {
         float curveInterpolation =
@@ -439,7 +518,7 @@
             }
         }
 
-        if (hasRemainingTime()) {
+        if (mDigitalWellBeingToast.getVisibility() == VISIBLE) {
             info.addAction(
                     new AccessibilityNodeInfo.AccessibilityAction(
                             R.string.accessibility_app_usage_settings,
@@ -463,7 +542,7 @@
         }
 
         if (action == R.string.accessibility_app_usage_settings) {
-            openAppUsageSettings();
+            mDigitalWellBeingToast.openAppUsageSettings();
             return true;
         }
 
@@ -485,23 +564,7 @@
         return super.performAccessibilityAction(action, arguments);
     }
 
-    private void openAppUsageSettings() {
-        final Intent intent = new Intent(SEE_TIME_IN_APP_TEMPLATE)
-                .putExtra(Intent.EXTRA_PACKAGE_NAME,
-                        mTask.getTopComponent().getPackageName()).addFlags(
-                        Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
-        try {
-            final Launcher launcher = Launcher.getLauncher(getContext());
-            launcher.startActivity(intent);
-            launcher.getUserEventDispatcher().logActionOnControl(LauncherLogProto.Action.Touch.TAP,
-                    LauncherLogProto.ControlType.APP_USAGE_SETTINGS, this);
-        } catch (ActivityNotFoundException e) {
-            Log.e(TAG, "Failed to open app usage settings for task "
-                    + mTask.getTopComponent().getPackageName(), e);
-        }
-    }
-
-    private RecentsView getRecentsView() {
+    public RecentsView getRecentsView() {
         return (RecentsView) getParent();
     }
 
@@ -516,15 +579,37 @@
 
     /**
      * Hides the icon and shows insets when this TaskView is about to be shown fullscreen.
+     * @param progress: 0 = show icon and no insets; 1 = don't show icon and show full insets.
      */
-    public void setFullscreen(boolean isFullscreen) {
-        mIsFullscreen = isFullscreen;
-        mIconView.setVisibility(mIsFullscreen ? INVISIBLE : VISIBLE);
-        setClipChildren(!mIsFullscreen);
-        setClipToPadding(!mIsFullscreen);
+    public void setFullscreenProgress(float progress) {
+        if (progress == mFullscreenProgress) {
+            return;
+        }
+        mFullscreenProgress = progress;
+        boolean isFullscreen = mFullscreenProgress > 0;
+        setIconScaleAndDim(progress, true /* invert */);
+        mIconView.setVisibility(progress < 1 ? VISIBLE : INVISIBLE);
+        setClipChildren(!isFullscreen);
+        setClipToPadding(!isFullscreen);
+        getThumbnail().invalidate();
     }
 
-    public boolean isFullscreen() {
-        return mIsFullscreen;
+    public float getFullscreenProgress() {
+        return mFullscreenProgress;
+    }
+
+    public boolean isRunningTask() {
+        return this == getRecentsView().getRunningTaskView();
+    }
+
+    public void setShowScreenshot(boolean showScreenshot) {
+        mShowScreenshot = showScreenshot;
+    }
+
+    public boolean showScreenshot() {
+        if (!isRunningTask()) {
+            return true;
+        }
+        return mShowScreenshot;
     }
 }
diff --git a/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
new file mode 100644
index 0000000..52f3c53
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/StartLauncherViaGestureTests.java
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+import static com.android.launcher3.util.RaceConditionTracker.enterEvt;
+import static com.android.launcher3.util.RaceConditionTracker.exitEvt;
+
+import android.content.Intent;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.util.RaceConditionReproducer;
+import com.android.quickstep.QuickStepOnOffRule.Mode;
+import com.android.quickstep.QuickStepOnOffRule.QuickstepOnOff;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class StartLauncherViaGestureTests extends AbstractQuickStepTest {
+    @Override
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        // Start an activity where the gestures start.
+        startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+    }
+
+    private void runTest(String... eventSequence) {
+        final RaceConditionReproducer eventProcessor = new RaceConditionReproducer(eventSequence);
+
+        // Destroy Launcher activity.
+        closeLauncherActivity();
+
+        // The test action.
+        eventProcessor.startIteration();
+        mLauncher.pressHome();
+        eventProcessor.finishIteration();
+    }
+
+    @Test
+    @QuickstepOnOff(mode = Mode.ON)
+    public void testPressHome() {
+        runTest(enterEvt(Launcher.ON_CREATE_EVT),
+                exitEvt(Launcher.ON_CREATE_EVT),
+                enterEvt(OtherActivityTouchConsumer.DOWN_EVT),
+                exitEvt(OtherActivityTouchConsumer.DOWN_EVT));
+
+        runTest(enterEvt(OtherActivityTouchConsumer.DOWN_EVT),
+                exitEvt(OtherActivityTouchConsumer.DOWN_EVT),
+                enterEvt(Launcher.ON_CREATE_EVT),
+                exitEvt(Launcher.ON_CREATE_EVT));
+    }
+
+    @Test
+    @QuickstepOnOff(mode = Mode.ON)
+    public void testSwipeToOverview() {
+        closeLauncherActivity();
+        mLauncher.getBackground().switchToOverview();
+    }
+}
\ No newline at end of file
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTests.java b/quickstep/tests/src/com/android/quickstep/TaplTests.java
new file mode 100644
index 0000000..347b7ac
--- /dev/null
+++ b/quickstep/tests/src/com/android/quickstep/TaplTests.java
@@ -0,0 +1,462 @@
+/*
+ * 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;
+
+import static androidx.test.InstrumentationRegistry.getInstrumentation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import android.content.Intent;
+import android.os.RemoteException;
+import android.util.Log;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+import androidx.test.uiautomator.By;
+import androidx.test.uiautomator.Until;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.tapl.AllApps;
+import com.android.launcher3.tapl.AllAppsFromOverview;
+import com.android.launcher3.tapl.AppIcon;
+import com.android.launcher3.tapl.Background;
+import com.android.launcher3.tapl.Overview;
+import com.android.launcher3.tapl.OverviewTask;
+import com.android.launcher3.tapl.TestHelpers;
+import com.android.launcher3.tapl.Widgets;
+import com.android.launcher3.tapl.Workspace;
+import com.android.launcher3.views.OptionsPopupView;
+import com.android.launcher3.widget.WidgetsFullSheet;
+import com.android.launcher3.widget.WidgetsRecyclerView;
+import com.android.quickstep.QuickStepOnOffRule.QuickstepOnOff;
+import com.android.quickstep.views.RecentsView;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TestWatcher;
+import org.junit.runner.Description;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class TaplTests extends AbstractQuickStepTest {
+    private static final String TAG = "TaplTests";
+
+    private static int sScreenshotCount = 0;
+
+    @Rule
+    public TestWatcher mFailureWatcher = new TestWatcher() {
+        private void dumpViewHierarchy() {
+            final ByteArrayOutputStream stream = new ByteArrayOutputStream();
+            try {
+                mDevice.dumpWindowHierarchy(stream);
+                stream.flush();
+                stream.close();
+                for (String line : stream.toString().split("\\r?\\n")) {
+                    Log.e(TaplTests.TAG, line.trim());
+                }
+            } catch (IOException e) {
+                Log.e(TaplTests.TAG, "error dumping XML to logcat", e);
+            }
+        }
+
+        @Override
+        protected void failed(Throwable e, Description description) {
+            if (mDevice == null) return;
+            final String pathname = getInstrumentation().getTargetContext().
+                    getFilesDir().getPath() + "/TaplTestScreenshot" + sScreenshotCount++ + ".png";
+            Log.e(TaplTests.TAG, "Failed test " + description.getMethodName() +
+                    ", screenshot will be saved to " + pathname +
+                    ", track trace is below, UI object dump is further below:\n" +
+                    Log.getStackTraceString(e));
+            dumpViewHierarchy();
+            mDevice.takeScreenshot(new File(pathname));
+        }
+    };
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+
+        clearLauncherData();
+
+        mLauncher.pressHome();
+        waitForState("Launcher internal state didn't switch to Home", LauncherState.NORMAL);
+        waitForResumed("Launcher internal state is still Background");
+    }
+
+    private boolean isInState(LauncherState state) {
+        if (!TestHelpers.isInLauncherProcess()) return true;
+        return getFromLauncher(launcher -> launcher.getStateManager().getState() == state);
+    }
+
+    // Please don't add negative test cases for methods that fail only after a long wait.
+    private void expectFail(String message, Runnable action) {
+        boolean failed = false;
+        try {
+            action.run();
+        } catch (AssertionError e) {
+            failed = true;
+        }
+        assertTrue(message, failed);
+    }
+
+    private boolean isWorkspaceScrollable(Launcher launcher) {
+        return launcher.getWorkspace().getPageCount() > 1;
+    }
+
+    private boolean isInBackground(Launcher launcher) {
+        return !launcher.hasBeenResumed();
+    }
+
+    private void startTestApps() throws Exception {
+        startAppFast(resolveSystemApp(Intent.CATEGORY_APP_MESSAGING));
+        startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+        startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CONTACTS));
+
+        executeOnLauncher(launcher -> assertTrue(
+                "Launcher activity is the top activity; expecting another activity to be the top "
+                        + "one",
+                isInBackground(launcher)));
+    }
+
+    private int getCurrentWorkspacePage(Launcher launcher) {
+        return launcher.getWorkspace().getCurrentPage();
+    }
+
+    private WidgetsRecyclerView getWidgetsView(Launcher launcher) {
+        return WidgetsFullSheet.getWidgetsView(launcher);
+    }
+
+    @Test
+    public void testDevicePressMenu() throws Exception {
+        mDevice.pressMenu();
+        mDevice.waitForIdle();
+        executeOnLauncher(
+                launcher -> assertTrue("Launcher internal state didn't switch to Showing Menu",
+                        OptionsPopupView.getOptionsPopup(launcher) != null));
+    }
+
+    @Test
+    @PortraitLandscape
+    public void testPressRecentAppsLauncherAndGetOverview() throws RemoteException {
+        mDevice.pressRecentApps();
+        waitForState("Launcher internal state didn't switch to Overview", LauncherState.OVERVIEW);
+
+        assertNotNull("getOverview() returned null", mLauncher.getOverview());
+    }
+
+    private void runAllAppsTest(AllApps allApps) throws Exception {
+        assertNotNull("allApps parameter is null", allApps);
+
+        assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
+
+        // Test flinging forward and backward.
+        executeOnLauncher(launcher -> assertEquals("All Apps started in already scrolled state", 0,
+                getAllAppsScroll(launcher)));
+
+        allApps.flingForward();
+        assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
+        final Integer flingForwardY = getFromLauncher(launcher -> getAllAppsScroll(launcher));
+        executeOnLauncher(
+                launcher -> assertTrue("flingForward() didn't scroll App Apps", flingForwardY > 0));
+
+        allApps.flingBackward();
+        assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
+        final Integer flingBackwardY = getFromLauncher(launcher -> getAllAppsScroll(launcher));
+        executeOnLauncher(launcher -> assertTrue("flingBackward() didn't scroll App Apps",
+                flingBackwardY < flingForwardY));
+
+        // Test scrolling down to YouTube.
+        assertNotNull("All apps: can't fine YouTube", allApps.getAppIcon("YouTube"));
+        // Test scrolling up to Camera.
+        assertNotNull("All apps: can't fine Camera", allApps.getAppIcon("Camera"));
+        // Test failing to find a non-existing app.
+        final AllApps allAppsFinal = allApps;
+        expectFail("All apps: could find a non-existing app",
+                () -> allAppsFinal.getAppIcon("NO APP"));
+
+        assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
+    }
+
+    private int getAllAppsScroll(Launcher launcher) {
+        return launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY();
+    }
+
+    @Test
+    @PortraitLandscape
+    public void testAllAppsFromHome() throws Exception {
+        // Test opening all apps
+        assertNotNull("switchToAllApps() returned null",
+                mLauncher.getWorkspace().switchToAllApps());
+
+        runAllAppsTest(mLauncher.getAllApps());
+
+        // Testing pressHome.
+        assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
+        assertNotNull("pressHome returned null", mLauncher.pressHome());
+        assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
+        assertNotNull("getHome returned null", mLauncher.getWorkspace());
+    }
+
+    @Test
+    @QuickstepOnOff
+    @PortraitLandscape
+    public void testWorkspaceSwitchToAllApps() {
+        assertNotNull("switchToAllApps() returned null",
+                mLauncher.getWorkspace().switchToAllApps());
+        assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
+    }
+
+    @Test
+    public void testAllAppsFromOverview() throws Exception {
+        // Test opening all apps from Overview.
+        assertNotNull("switchToAllApps() returned null",
+                mLauncher.getWorkspace().switchToOverview().switchToAllApps());
+
+        runAllAppsTest(mLauncher.getAllAppsFromOverview());
+    }
+
+    @Test
+    public void testWorkspace() throws Exception {
+        final Workspace workspace = mLauncher.getWorkspace();
+
+        // Test that ensureWorkspaceIsScrollable adds a page by dragging an icon there.
+        executeOnLauncher(launcher -> assertFalse("Initial workspace state is scrollable",
+                isWorkspaceScrollable(launcher)));
+        assertNull("Messages app was found on empty workspace",
+                workspace.tryGetWorkspaceAppIcon("Messages"));
+
+        workspace.ensureWorkspaceIsScrollable();
+
+        executeOnLauncher(
+                launcher -> assertEquals("Ensuring workspace scrollable didn't switch to page #1",
+                        1, getCurrentWorkspacePage(launcher)));
+        executeOnLauncher(
+                launcher -> assertTrue("ensureScrollable didn't make workspace scrollable",
+                        isWorkspaceScrollable(launcher)));
+        assertNotNull("ensureScrollable didn't add Messages app",
+                workspace.tryGetWorkspaceAppIcon("Messages"));
+
+        // Test flinging workspace.
+        workspace.flingBackward();
+        assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
+        executeOnLauncher(
+                launcher -> assertEquals("Flinging back didn't switch workspace to page #0",
+                        0, getCurrentWorkspacePage(launcher)));
+
+        workspace.flingForward();
+        executeOnLauncher(
+                launcher -> assertEquals("Flinging forward didn't switch workspace to page #1",
+                        1, getCurrentWorkspacePage(launcher)));
+        assertTrue("Launcher internal state is not Home", isInState(LauncherState.NORMAL));
+
+        // Test starting a workspace app.
+        final AppIcon app = workspace.tryGetWorkspaceAppIcon("Messages");
+        assertNotNull("No Messages app in workspace", app);
+        assertNotNull("AppIcon.launch returned null",
+                app.launch(resolveSystemApp(Intent.CATEGORY_APP_MESSAGING)));
+        executeOnLauncher(launcher -> assertTrue(
+                "Launcher activity is the top activity; expecting another activity to be the top "
+                        + "one",
+                isInBackground(launcher)));
+    }
+
+    @Test
+    @PortraitLandscape
+    public void testOverview() throws Exception {
+        startTestApps();
+        Overview overview = mLauncher.pressHome().switchToOverview();
+        assertTrue("Launcher internal state didn't switch to Overview",
+                isInState(LauncherState.OVERVIEW));
+        executeOnLauncher(
+                launcher -> assertTrue("Don't have at least 3 tasks", getTaskCount(launcher) >= 3));
+
+        // Test flinging forward and backward.
+        executeOnLauncher(launcher -> assertEquals("Current task in Overview is not 0",
+                0, getCurrentOverviewPage(launcher)));
+
+        overview.flingForward();
+        assertTrue("Launcher internal state is not Overview", isInState(LauncherState.OVERVIEW));
+        final Integer currentTaskAfterFlingForward = getFromLauncher(
+                launcher -> getCurrentOverviewPage(launcher));
+        executeOnLauncher(launcher -> assertTrue("Current task in Overview is still 0",
+                currentTaskAfterFlingForward > 0));
+
+        overview.flingBackward();
+        assertTrue("Launcher internal state is not Overview", isInState(LauncherState.OVERVIEW));
+        executeOnLauncher(launcher -> assertTrue("Flinging back in Overview did nothing",
+                getCurrentOverviewPage(launcher) < currentTaskAfterFlingForward));
+
+        // Test opening a task.
+        OverviewTask task = mLauncher.pressHome().switchToOverview().getCurrentTask();
+        assertNotNull("overview.getCurrentTask() returned null (1)", task);
+        assertNotNull("OverviewTask.open returned null", task.open());
+        assertTrue("Contacts app didn't open from Overview", mDevice.wait(Until.hasObject(
+                By.pkg(resolveSystemApp(Intent.CATEGORY_APP_CONTACTS)).depth(0)),
+                LONG_WAIT_TIME_MS));
+        executeOnLauncher(launcher -> assertTrue(
+                "Launcher activity is the top activity; expecting another activity to be the top "
+                        + "one",
+                isInBackground(launcher)));
+
+        // Test dismissing a task.
+        overview = mLauncher.pressHome().switchToOverview();
+        assertTrue("Launcher internal state didn't switch to Overview",
+                isInState(LauncherState.OVERVIEW));
+        final Integer numTasks = getFromLauncher(launcher -> getTaskCount(launcher));
+        task = overview.getCurrentTask();
+        assertNotNull("overview.getCurrentTask() returned null (2)", task);
+        task.dismiss();
+        executeOnLauncher(
+                launcher -> assertEquals("Dismissing a task didn't remove 1 task from Overview",
+                        numTasks - 1, getTaskCount(launcher)));
+
+        if (!TestHelpers.isInLauncherProcess() ||
+                getFromLauncher(launcher -> !launcher.getDeviceProfile().isLandscape)) {
+            // Test switching to all apps and back.
+            final AllAppsFromOverview allApps = overview.switchToAllApps();
+            assertNotNull("overview.switchToAllApps() returned null (1)", allApps);
+            assertTrue("Launcher internal state is not All Apps (1)",
+                    isInState(LauncherState.ALL_APPS));
+
+            overview = allApps.switchBackToOverview();
+            assertNotNull("allApps.switchBackToOverview() returned null", overview);
+            assertTrue("Launcher internal state didn't switch to Overview",
+                    isInState(LauncherState.OVERVIEW));
+
+            // Test UIDevice.pressBack()
+            overview.switchToAllApps();
+            assertNotNull("overview.switchToAllApps() returned null (2)", allApps);
+            assertTrue("Launcher internal state is not All Apps (2)",
+                    isInState(LauncherState.ALL_APPS));
+            mDevice.pressBack();
+            mLauncher.getOverview();
+        }
+
+        // Test UIDevice.pressHome, once we are in AllApps.
+        mDevice.pressHome();
+        waitForState("Launcher internal state didn't switch to Home", LauncherState.NORMAL);
+    }
+
+    private int getCurrentOverviewPage(Launcher launcher) {
+        return launcher.<RecentsView>getOverviewPanel().getCurrentPage();
+    }
+
+    private int getTaskCount(Launcher launcher) {
+        return launcher.<RecentsView>getOverviewPanel().getTaskViewCount();
+    }
+
+    private void runIconLaunchFromAllAppsTest(AllApps allApps) throws Exception {
+        final AppIcon app = allApps.getAppIcon("Calculator");
+        assertNotNull("AppIcon.launch returned null", app.launch(
+                resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)));
+        executeOnLauncher(launcher -> assertTrue(
+                "Launcher activity is the top activity; expecting another activity to be the top "
+                        + "one",
+                isInBackground(launcher)));
+    }
+
+    @Test
+    @PortraitLandscape
+    public void testAppIconLaunchFromAllAppsFromHome() throws Exception {
+        final AllApps allApps = mLauncher.getWorkspace().switchToAllApps();
+        assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
+
+        runIconLaunchFromAllAppsTest(allApps);
+    }
+
+    @Test
+    public void testAppIconLaunchFromAllAppsFromOverview() throws Exception {
+        final AllApps allApps =
+                mLauncher.getWorkspace().switchToOverview().switchToAllApps();
+        assertTrue("Launcher internal state is not All Apps", isInState(LauncherState.ALL_APPS));
+
+        runIconLaunchFromAllAppsTest(allApps);
+    }
+
+    @Test
+    @PortraitLandscape
+    public void testWidgets() throws Exception {
+        // Test opening widgets.
+        executeOnLauncher(launcher ->
+                assertTrue("Widgets is initially opened", getWidgetsView(launcher) == null));
+        Widgets widgets = mLauncher.getWorkspace().openAllWidgets();
+        assertNotNull("openAllWidgets() returned null", widgets);
+        widgets = mLauncher.getAllWidgets();
+        assertNotNull("getAllWidgets() returned null", widgets);
+        executeOnLauncher(launcher ->
+                assertTrue("Widgets is not shown", getWidgetsView(launcher).isShown()));
+        executeOnLauncher(launcher -> assertEquals("Widgets is scrolled upon opening",
+                0, getWidgetsScroll(launcher)));
+
+        // Test flinging widgets.
+        widgets.flingForward();
+        Integer flingForwardY = getFromLauncher(launcher -> getWidgetsScroll(launcher));
+        executeOnLauncher(launcher -> assertTrue("Flinging forward didn't scroll widgets",
+                flingForwardY > 0));
+
+        widgets.flingBackward();
+        executeOnLauncher(launcher -> assertTrue("Flinging backward didn't scroll widgets",
+                getWidgetsScroll(launcher) < flingForwardY));
+
+        mLauncher.pressHome();
+        waitForLauncherCondition("Widgets were not closed",
+                launcher -> getWidgetsView(launcher) == null);
+    }
+
+    private int getWidgetsScroll(Launcher launcher) {
+        return getWidgetsView(launcher).getCurrentScrollY();
+    }
+
+    @Test
+    @QuickstepOnOff
+    @PortraitLandscape
+    public void testSwitchToOverview() throws Exception {
+        assertNotNull("Workspace.switchToOverview() returned null",
+                mLauncher.pressHome().switchToOverview());
+        assertTrue("Launcher internal state didn't switch to Overview",
+                isInState(LauncherState.OVERVIEW));
+    }
+
+    @Test
+    @QuickstepOnOff
+    @PortraitLandscape
+    public void testBackground() throws Exception {
+        startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR));
+        final Background background = mLauncher.getBackground();
+        assertNotNull("Launcher.getBackground() returned null", background);
+        executeOnLauncher(launcher -> assertTrue(
+                "Launcher activity is the top activity; expecting another activity to be the top "
+                        + "one",
+                isInBackground(launcher)));
+
+        assertNotNull("Background.switchToOverview() returned null", background.switchToOverview());
+        assertTrue("Launcher internal state didn't switch to Overview",
+                isInState(LauncherState.OVERVIEW));
+    }
+}
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index b1e6f2e..33ff46b 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -30,7 +30,50 @@
         layout="@layout/all_apps_rv_layout"
         android:visibility="gone" />
 
-    <include layout="@layout/all_apps_floating_header" />
+    <com.android.launcher3.allapps.FloatingHeaderView
+        android:id="@+id/all_apps_header"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_below="@id/search_container_all_apps"
+        android:clipToPadding="false"
+        android:paddingTop="@dimen/all_apps_header_top_padding"
+        android:orientation="vertical" >
+
+        <include layout="@layout/floating_header_content" />
+
+        <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
+            android:id="@+id/tabs"
+            android:layout_width="match_parent"
+            android:layout_height="@dimen/all_apps_header_tab_height"
+            android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
+            android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
+            android:orientation="horizontal">
+
+            <Button
+                android:id="@+id/tab_personal"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:background="?android:attr/selectableItemBackground"
+                android:fontFamily="sans-serif-medium"
+                android:text="@string/all_apps_personal_tab"
+                android:textAllCaps="true"
+                android:textColor="@color/all_apps_tab_text"
+                android:textSize="14sp" />
+
+            <Button
+                android:id="@+id/tab_work"
+                android:layout_width="0dp"
+                android:layout_height="match_parent"
+                android:layout_weight="1"
+                android:background="?android:attr/selectableItemBackground"
+                android:fontFamily="sans-serif-medium"
+                android:text="@string/all_apps_work_tab"
+                android:textAllCaps="true"
+                android:textColor="@color/all_apps_tab_text"
+                android:textSize="14sp" />
+        </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
+    </com.android.launcher3.allapps.FloatingHeaderView>
 
     <include
         android:id="@id/search_container_all_apps"
diff --git a/res/layout/all_apps_floating_header.xml b/res/layout/all_apps_floating_header.xml
deleted file mode 100644
index c4240f8..0000000
--- a/res/layout/all_apps_floating_header.xml
+++ /dev/null
@@ -1,58 +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.launcher3.allapps.FloatingHeaderView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/all_apps_header"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:layout_below="@id/search_container_all_apps"
-    android:clipToPadding="false"
-    android:paddingTop="@dimen/all_apps_header_top_padding"
-    android:orientation="vertical" >
-
-    <com.android.launcher3.allapps.PersonalWorkSlidingTabStrip
-        android:id="@+id/tabs"
-        android:layout_width="match_parent"
-        android:layout_height="@dimen/all_apps_header_tab_height"
-        android:layout_marginLeft="@dimen/all_apps_tabs_side_padding"
-        android:layout_marginRight="@dimen/all_apps_tabs_side_padding"
-        android:orientation="horizontal">
-
-        <Button
-            android:id="@+id/tab_personal"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:background="?android:attr/selectableItemBackground"
-            android:fontFamily="sans-serif-medium"
-            android:text="@string/all_apps_personal_tab"
-            android:textAllCaps="true"
-            android:textColor="@color/all_apps_tab_text"
-            android:textSize="14sp" />
-
-        <Button
-            android:id="@+id/tab_work"
-            android:layout_width="0dp"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:background="?android:attr/selectableItemBackground"
-            android:fontFamily="sans-serif-medium"
-            android:text="@string/all_apps_work_tab"
-            android:textAllCaps="true"
-            android:textColor="@color/all_apps_tab_text"
-            android:textSize="14sp" />
-    </com.android.launcher3.allapps.PersonalWorkSlidingTabStrip>
-</com.android.launcher3.allapps.FloatingHeaderView>
diff --git a/res/layout/floating_header_content.xml b/res/layout/floating_header_content.xml
new file mode 100644
index 0000000..e4061c2
--- /dev/null
+++ b/res/layout/floating_header_content.xml
@@ -0,0 +1,16 @@
+<?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.
+-->
+<merge />
\ No newline at end of file
diff --git a/res/layout/launcher_preview_layout.xml b/res/layout/launcher_preview_layout.xml
new file mode 100644
index 0000000..3fd02e3
--- /dev/null
+++ b/res/layout/launcher_preview_layout.xml
@@ -0,0 +1,50 @@
+<?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.launcher3.InsettableFrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <com.android.launcher3.CellLayout
+        android:id="@+id/workspace"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_gravity="top|left"
+        android:theme="@style/HomeScreenElementTheme"
+        launcher:containerType="workspace"
+        launcher:pageIndicator="@+id/page_indicator"/>
+
+    <com.android.launcher3.Hotseat
+        android:id="@+id/hotseat"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:importantForAccessibility="no"
+        android:theme="@style/HomeScreenElementTheme"
+        launcher:containerType="hotseat" />
+
+    <com.android.launcher3.InsettableFrameLayout
+        android:id="@+id/apps_view"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent" >
+
+        <include
+            android:id="@id/search_container_all_apps"
+            layout="@layout/search_container_all_apps"/>
+
+    </com.android.launcher3.InsettableFrameLayout>
+
+</com.android.launcher3.InsettableFrameLayout>
\ No newline at end of file
diff --git a/res/layout/system_shortcut_icons.xml b/res/layout/system_shortcut_icons.xml
index 4daf469..a340f4f 100644
--- a/res/layout/system_shortcut_icons.xml
+++ b/res/layout/system_shortcut_icons.xml
@@ -22,4 +22,10 @@
     android:orientation="horizontal"
     android:gravity="end|center_vertical"
     android:background="?attr/popupColorSecondary"
-    android:clipToPadding="true" />
+    android:clipToPadding="true">
+
+    <Space android:layout_width="0dp"
+           android:layout_height="match_parent"
+           android:layout_weight="1"
+           android:id="@+id/separator"/>
+</LinearLayout>
diff --git a/res/raw/downgrade_schema.json b/res/raw/downgrade_schema.json
index 3c1b64f..8f1780e 100644
--- a/res/raw/downgrade_schema.json
+++ b/res/raw/downgrade_schema.json
@@ -2,8 +2,12 @@
   // Note: Comments are not supported in JSON schema, but android parser is lenient.
 
   // Maximum DB version supported by this schema
-  "version" : 27,
+  "version" : 28,
 
+  "downgrade_to_27" : [
+    "CREATE TABLE workspaceScreens (_id INTEGER PRIMARY KEY,screenRank INTEGER,modified INTEGER NOT NULL DEFAULT 0)",
+    "insert into workspaceScreens (_id, screenRank) select screen as _id, screen as screenRank from favorites where container = -100 group by screen order by screen"
+  ],
   // Downgrade from 27 to 26. Empty array indicates, the DB is compatible
   "downgrade_to_26" : [],
   "downgrade_to_25" : [],
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 56d198c..0f08c0a 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Laai tans programme …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Kon geen programme kry wat by \"<xliff:g id="QUERY">%1$s</xliff:g>\" pas nie"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Soek meer programme"</string>
+    <string name="label_application" msgid="8531721983832654978">"Program"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Kennisgewings"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Raak en hou om \'n kortpad op te tel."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dubbeltik en hou om \'n kortpad op te tel of gebruik gepasmaakte handelinge."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dit is \'n stelselprogram en kan nie gedeïnstalleer word nie."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Naamlose vouer"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Het <xliff:g id="APP_NAME">%1$s</xliff:g> gedeaktiveer"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> het <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> kennisgewings</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> het <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> kennisgewing</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, het <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> kennisgewings</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, het <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> kennisgewing</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Bladsy %1$d van %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Tuisskerm %1$d van %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gedeaktiveer deur jou administrateur"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Laat toe dat tuisskerm gedraai word"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Wanneer foon gedraai word"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Kennisgewingkolle"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aan"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Af"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Kennisgewingkolle"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Aan"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Af"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Kennisgewingtoegang word benodig"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Skakel programkennisgewings vir <xliff:g id="NAME">%1$s</xliff:g> aan om kennisgewingkolle te sien"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Verander instellings"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Wys kennisgewingkolle"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Wys kennisgewingkolle"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Voeg ikoon by tuisskerm"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Vir nuwe programme"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Verander ikoon se vorm"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"op tuisskerm"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Gebruik stelselverstek"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Vierkant"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Sirkelvierkant"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Sirkel"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Traandruppel"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Pas ikoonvormveranderings toe"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Verwyder"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Soek"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 6c4a51c..5df7ced 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"መተግበሪያዎችን በመጫን ላይ…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"ከ«<xliff:g id="QUERY">%1$s</xliff:g>» ጋር የሚዛመዱ ምንም መተግበሪያዎች አልተገኙም"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ተጨማሪ መተግበሪያዎች ይፈልጉ"</string>
+    <string name="label_application" msgid="8531721983832654978">"መተግበሪያ"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ይህ የስርዓት መተግበሪያ ነው እና ማራገፍ አይቻልም።"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"ስም-አልባ አቃፊ"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ተሰናክሏል"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>፣ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ማሳወቂያዎች አለው</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>፣ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ማሳወቂያዎች አለው</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>፣ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ማሳወቂያ አለው</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>፣ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ማሳወቂያ አለው</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"ገጽ %1$d ከ%2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"መነሻ ማያ ገጽ %1$d ከ%2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"በእርስዎ አስተዳዳሪ የተሰናከለ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"የመነሻ ማያ ገጽ ማሽከርከርን ይፍቀዱ"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ስልኩ ሲዞር"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"የማሳወቂያ ነጥቦች"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"በርቷል"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ጠፍቷል"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"የማሳወቂያ ነጥቦች"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"አብራ"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ጠፍቷል"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"የማሳወቂያ መዳረሻ ያስፈልጋል"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"የማሳወቂያ ነጥቦችን ለማሳየት የመተግብሪያ ማሳወቂያዎችን ለ<xliff:g id="NAME">%1$s</xliff:g> ያብሩ"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ቅንብሮችን ቀይር"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"የማሳወቂያ ነጥቦችን አሳይ"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"የማሳወቂያ ነጥቦችን አሳይ"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"አዶ ወደ የመነሻ ማያ ገጽ አክል"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ለአዲስ መተግበሪያዎች"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"የአዶ ቅርፅ ለውጥ"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"በመነሻ ማያ ገጽ ላይ"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"የሥርዓቱን ነባሪ ተጠቀም"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"ካሬ"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"ክብ"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"የእንባ ጠብታ"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"የአዶ ቅርች ለውጦች"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"የማይታወቅ"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"አስወግድ"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ፈልግ"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"ማሳወቂያዎች እና መተግበሪያዎች ጠፍተዋል"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ዝጋ"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ዝግ"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"አልተሳካም፦ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index bebc7b3..5b5cfa4 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"جارٍ تحميل التطبيقات…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"لم يتم العثور على أي تطبيقات تتطابق مع \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"البحث عن مزيد من التطبيقات"</string>
+    <string name="label_application" msgid="8531721983832654978">"تطبيق"</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>
@@ -64,13 +65,13 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"هذا تطبيق نظام وتتعذر إزالته."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"مجلد بدون اسم"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"تم إيقاف <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="zero"><xliff:g id="APP_NAME_2">%1$s</xliff:g>، به <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعار</item>
-      <item quantity="two"><xliff:g id="APP_NAME_2">%1$s</xliff:g>، به إشعاران (<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>)</item>
-      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>، به <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعارات</item>
-      <item quantity="many"><xliff:g id="APP_NAME_2">%1$s</xliff:g>، به <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعارًا</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>، به <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعار</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>، به <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> إشعار</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="zero">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعار.​</item>
+      <item quantity="two">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> إشعارين (<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>).</item>
+      <item quantity="few">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعارات.​</item>
+      <item quantity="many">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعارًا.</item>
+      <item quantity="other">يتضمن تطبيق <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> إشعار.</item>
+      <item quantity="one">يتضمن تطبيق <xliff:g id="APP_NAME_0">%1$s</xliff:g> إشعارًا واحدًا (<xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g>).</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"‏الصفحة %1$d من %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"‏الشاشة الرئيسية %1$d من %2$d"</string>
@@ -87,23 +88,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"أوقف المشرف هذه الميزة"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"السماح بتدوير الشاشة الرئيسية"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"عند تدوير الهاتف"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"نقاط الإشعارات"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"قيد التشغيل"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"غير مفعّل"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"نقاط الإشعارات"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"مفعّل"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"غير مفعّل"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"يلزم تفعيل الوصول إلى الإشعارات"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"لعرض نقاط الإشعارات، يجب تشغيل إشعارات التطبيق في <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"تغيير الإعدادات"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"عرض نقاط الإشعارات"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"عرض نقاط الإشعارات"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"إضافة رمز إلى الشاشة الرئيسية"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"للتطبيقات الجديدة"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"تغيير شكل الرمز"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"على الشاشة الرئيسية"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"استخدام الإعداد التلقائي للنظام"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"مربّع"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"رمز دائري مربّع"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"دائرة"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"رمز على شكل دمعة"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"جارٍ تطبيق تغييرات شكل الرمز"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"غير معروفة"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"إزالة"</string>
     <string name="abandoned_search" msgid="891119232568284442">"بحث"</string>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index 2bb2f67..75616f3 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -24,8 +24,8 @@
     <string name="work_folder_name" msgid="3753320833950115786">"কৰ্মস্থান"</string>
     <string name="activity_not_found" msgid="8071924732094499514">"এপটো ইনষ্টল কৰা নহ\'ল।"</string>
     <string name="activity_not_available" msgid="7456344436509528827">"এপটো নাই"</string>
-    <string name="safemode_shortcut_error" msgid="9160126848219158407">"ডাউনল\'ড কৰা এপটোক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ\'ল"</string>
-    <string name="safemode_widget_error" msgid="4863470563535682004">"ৱিজেটবোৰক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ\'ল"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"ডাউনল’ড কৰা এপটোক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ’ল"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"ৱিজেটবোৰক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ’ল"</string>
     <string name="shortcut_not_available" msgid="2536503539825726397">"শ্বৰ্টকাট নাই"</string>
     <string name="home_screen" msgid="806512411299847073">"গৃহ স্ক্ৰীণ"</string>
     <string name="custom_actions" msgid="3747508247759093328">"উপযোগিতা অনুসৰি কৰা কাৰ্যবিলাক"</string>
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"এপসমূহ ল’ড কৰি থকা হৈছে…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"ৰ সৈতে মিলা কোনো এপ্ বিচাৰি পোৱা নগ\'ল"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"আৰু অধিক এপবোৰ সন্ধান কৰক"</string>
+    <string name="label_application" msgid="8531721983832654978">"এপ্"</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>
@@ -63,18 +64,18 @@
     <string name="gadget_setup_text" msgid="8274003207686040488">"ছেটআপ কৰক"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"এইটো এটা ছিষ্টেম এপ আৰু ইয়াক আনইনষ্টল কৰিব নোৱৰি"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"নামবিহীন ফ\'ল্ডাৰ"</string>
-    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> অক্ষম কৰা হ\'ল"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> অক্ষম কৰা হ’ল"</string>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>ৰ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টা জাননী আছে</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>ৰ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টা জাননী আছে</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%2$dৰ %1$d পৃষ্ঠা"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"গৃহ স্ক্ৰীণ %2$dৰ %1$d"</string>
     <string name="workspace_new_page" msgid="257366611030256142">"গৃহ স্ক্ৰীণৰ নতুন পৃষ্ঠা"</string>
-    <string name="folder_opened" msgid="94695026776264709">"ফ’ল্ডাৰ খোলা হ\'ল, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+    <string name="folder_opened" msgid="94695026776264709">"ফ’ল্ডাৰ খোলা হ’ল, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
     <string name="folder_tap_to_close" msgid="4625795376335528256">"ফ\'ল্ডাৰ বন্ধ কৰিবলৈ টিপক"</string>
     <string name="folder_tap_to_rename" msgid="4017685068016979677">"সলনি কৰা নাম ছেভ কৰিবলৈ টিপক"</string>
-    <string name="folder_closed" msgid="4100806530910930934">"ফ\'ল্ডাৰ বন্ধ কৰা হ\'ল"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"ফ\'ল্ডাৰ বন্ধ কৰা হ’ল"</string>
     <string name="folder_renamed" msgid="1794088362165669656">"ফ\'ল্ডাৰৰ নাম সলনি কৰি <xliff:g id="NAME">%1$s</xliff:g> কৰা হৈছে"</string>
     <string name="folder_name_format" msgid="6629239338071103179">"ফ’ল্ডাৰ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ৱিজেটসমূহ"</string>
@@ -83,55 +84,47 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপোনাৰ প্ৰশাসকে অক্ষম কৰি ৰাখিছে"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"গৃহ স্ক্ৰীণ ঘূৰোৱাৰ অনুমতি দিয়ক"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ফ\'নটো যেতিয়া ঘূৰোৱা হয়"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"জাননী সম্পৰ্কীয় বিন্দুবোৰ"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"অন অৱস্থাত আছে"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"অফ অৱস্থাত আছে"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"জাননী বিন্দু"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"অন আছে"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"অফ আছে"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"জাননী চাবলৈ অনুমতিৰ প্ৰয়োজন"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"জাননী সম্পৰ্কীয় বিন্দুবোৰ দেখুৱাবলৈ <xliff:g id="NAME">%1$s</xliff:g>ৰ বাবে এপৰ জাননীসমূহ অন কৰক"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ছেটিংসমূহ সলনি কৰক"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"জাননী বিন্দুসমূহ দেখুৱাওক"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"জাননী বিন্দু দেখুৱাওক"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"গৃহ স্ক্ৰীণত আইকনটো যোগ কৰক"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন এপসমূহৰ বাবে"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"আইকনৰ আকৃতি সলনি কৰক"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"গৃহ স্ক্ৰীণত"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"ছিষ্টেম ডিফ\'ল্ট ব্য়ৱহাৰ কৰক"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"বৰ্গাকাৰ"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"বৰ্গবৃত্তাকাৰ"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"পৰিচিত মানুহৰ গোট"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"চকুপানীৰ টোপাল"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"আইকনৰ আকৃতিত কৰা পৰিবৰ্তনবোৰ প্ৰয়োগ কৰি থকা হৈছে"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"অজ্ঞাত"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"আঁতৰাওক"</string>
     <string name="abandoned_search" msgid="891119232568284442">"সন্ধান কৰক"</string>
     <string name="abandoned_promises_title" msgid="7096178467971716750">"এই এপটো ইনষ্টল কৰা হোৱা নাই"</string>
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"এই আইকনৰ এপটো ইনষ্টল কৰা হোৱা নাই। আপুনি এইটো আঁতৰাব পাৰে অথবা এপটো বিচাৰি মেনুৱেলভাৱে ইনষ্টল কৰিব পাৰে।"</string>
-    <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ডাউনল\'ড কৰি থকা হৈছে, <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পূৰ্ণ হ\'ল"</string>
+    <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ডাউনল’ড কৰি থকা হৈছে, <xliff:g id="PROGRESS">%2$s</xliff:g> সম্পূৰ্ণ হ’ল"</string>
     <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ইনষ্টল হোৱালৈ অপেক্ষা কৰি থকা হৈছে"</string>
     <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ৱিজেট"</string>
     <string name="widgets_list" msgid="796804551140113767">"ৱিজেটৰ তালিকা"</string>
-    <string name="widgets_list_closed" msgid="6141506579418771922">"ৱিজেটৰ তালিকা বন্ধ কৰা হ\'ল"</string>
+    <string name="widgets_list_closed" msgid="6141506579418771922">"ৱিজেটৰ তালিকা বন্ধ কৰা হ’ল"</string>
     <string name="action_add_to_workspace" msgid="8902165848117513641">"গৃহ স্ক্ৰীণত যোগ কৰক"</string>
     <string name="action_move_here" msgid="2170188780612570250">"বস্তুটো ইয়ালৈ স্থানান্তৰ কৰক"</string>
-    <string name="item_added_to_workspace" msgid="4211073925752213539">"বস্তুটো গৃহ স্ক্ৰীণত যোগ কৰা হ\'ল"</string>
-    <string name="item_removed" msgid="851119963877842327">"বস্তুটো আঁতৰোৱা হ\'ল"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"বস্তুটো গৃহ স্ক্ৰীণত যোগ কৰা হ’ল"</string>
+    <string name="item_removed" msgid="851119963877842327">"বস্তুটো আঁতৰোৱা হ’ল"</string>
     <string name="undo" msgid="4151576204245173321">"আনডু কৰক"</string>
     <string name="action_move" msgid="4339390619886385032">"বস্তু স্থানান্তৰ কৰক"</string>
     <string name="move_to_empty_cell" msgid="2833711483015685619">"শাৰী <xliff:g id="NUMBER_0">%1$s</xliff:g> স্তম্ভ <xliff:g id="NUMBER_1">%2$s</xliff:g>লৈ স্থানান্তৰিত কৰক"</string>
     <string name="move_to_position" msgid="6750008980455459790">"পছন্দৰ অৱস্থান <xliff:g id="NUMBER">%1$s</xliff:g>লৈ স্থানান্তৰিত কৰক"</string>
     <string name="move_to_hotseat_position" msgid="6295412897075147808">"পছন্দৰ অৱস্থান <xliff:g id="NUMBER">%1$s</xliff:g>লৈ স্থানান্তৰিত কৰক"</string>
-    <string name="item_moved" msgid="4606538322571412879">"বস্তুটো স্থানান্তৰ কৰা হ\'ল"</string>
+    <string name="item_moved" msgid="4606538322571412879">"বস্তুটো স্থানান্তৰ কৰা হ’ল"</string>
     <string name="add_to_folder" msgid="9040534766770853243">"ফ\'ল্ডাৰত যোগ কৰক: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g>সহ ফ\'ল্ডাৰত যোগ কৰক"</string>
-    <string name="added_to_folder" msgid="4793259502305558003">"বস্তুটো ফ\'ল্ডাৰত যোগ কৰা হ\'ল"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"বস্তুটো ফ\'ল্ডাৰত যোগ কৰা হ’ল"</string>
     <string name="create_folder_with" msgid="4050141361160214248">"<xliff:g id="NAME">%1$s</xliff:g>: ৰ জৰিয়তে ফ\'ল্ডাৰ সৃষ্টি কৰক"</string>
-    <string name="folder_created" msgid="6409794597405184510">"ফ\'ল্ডাৰ সৃষ্টি কৰা হ\'ল"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ফ\'ল্ডাৰ সৃষ্টি কৰা হ’ল"</string>
     <string name="action_move_to_workspace" msgid="1603837886334246317">"হ\'ম স্ক্ৰীণলৈ স্থানান্তৰ কৰক"</string>
     <string name="action_resize" msgid="1802976324781771067">"আকাৰ সলনি কৰক"</string>
     <string name="action_increase_width" msgid="8773715375078513326">"প্ৰস্থ বৃদ্ধি কৰক"</string>
     <string name="action_increase_height" msgid="459390020612501122">"উচ্চতা বৃদ্ধি কৰক"</string>
     <string name="action_decrease_width" msgid="1374549771083094654">"প্ৰস্থ হ্ৰাস কৰক"</string>
     <string name="action_decrease_height" msgid="282377193880900022">"উচ্চতা হ্ৰাস কৰক"</string>
-    <string name="widget_resized" msgid="9130327887929620">"ৱিজেটৰ আকাৰ সলনি কৰি প্ৰস্থ <xliff:g id="NUMBER_0">%1$s</xliff:g> আৰু উচ্চতা <xliff:g id="NUMBER_1">%2$s</xliff:g> কৰা হ\'ল"</string>
+    <string name="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_with_notifications_description" msgid="2676582286544232849">"শ্বৰ্টকাট আৰু জাননীসমূহ"</string>
     <string name="action_dismiss_notification" msgid="5909461085055959187">"অগ্ৰাহ্য কৰক"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"জাননী আৰু এপসমূহ অফ হৈ আছে"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"বন্ধ কৰক"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"বন্ধ"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"বিফল: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index f8aba17..9fc8626 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Tətbiqlər yüklənir…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> sorğusuna uyğun tətbiq tapılmadı"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Daha çox tətbiq üçün axtarış edin"</string>
+    <string name="label_application" msgid="8531721983832654978">"Tətbiq"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Bildirişlər"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Qısayolu seçmək üçün basıb saxlayın."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu sistem tətbiqi olduğu üçün sistemdən silinə bilməz."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Adsız Qovluq"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> deaktiv edildi"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> tətbiqində <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> bildiriş var</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> tətbiqində <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> bildiriş var</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Admininiz tərəfindən deaktiv edilib"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Əsas ekranın firlanmağına icazə verin"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon çevrilən zaman"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Bildiriş nişanı"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktiv"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Deaktiv"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Bildiriş nöqtələri"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktiv"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Deaktiv"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Bildiriş girişi tələb edilir"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Bildiriş Nöqtələrini göstərmək üçün <xliff:g id="NAME">%1$s</xliff:g> bildirişlərini aktiv edin"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Ayarları dəyişin"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Bildiriş nöqtələrini göstərin"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Bildiriş nöqtələrini göstərin"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Əsas ekrana ikona əlavə edin"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yeni tətbiqlər üçün"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"İkona formasını dəyişin"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"Əsas səhifə ekranında"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Sistem defoltu istifadə edin"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Kənarları dairəvi kvadrat"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Çevrə"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Gözyaşı damlası"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"İkona formasına etdiyiniz dəyişikliklər tətbiq edilir"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Naməlum"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Yığışdır"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Axtarış"</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index e716204..269ba78 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži još aplikacija"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obaveštenja"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Dodirnite i zadržite da biste izabrali prečicu."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dvaput dodirnite i zadržite da biste izabrali prečicu ili koristite prilagođene radnje."</string>
@@ -64,10 +65,10 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ovo je sistemska aplikacija i ne može da se deinstalira."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Neimenovani direktorijum"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućena"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obaveštenje</item>
-      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obaveštenja</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obaveštenja</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obaveštenje</item>
+      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obaveštenja</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obaveštenja</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%1$d. stranica od %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d. početni ekran od %2$d"</string>
@@ -84,23 +85,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator je onemogućio"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotaciju početnog ekrana"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon rotira"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Tačke za obaveštenja"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Uključeno"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Isključeno"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Tačke za obaveštenja"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Uključeno"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Isključeno"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Potreban je pristup za obaveštenja"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Da biste prikazali tačke za obaveštenja, uključite obaveštenja za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Promenite podešavanja"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Prikazuj tačke za obaveštenja"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Prikazuj tačke za obaveštenja"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonu na početni ekran"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Promenite oblik ikona"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"na početnom ekranu"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Koristi podrazumevano sistemsko podešavanje"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaobljeni kvadrat"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Krug"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Suza"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Primenjuju se promene oblika ikona"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Ukloni"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Pretraži"</string>
@@ -146,4 +139,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Obaveštenja i aplikacije su isključeni"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zatvori"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zatvoreno"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Nije uspelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index e5a6587..1a1cfce 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Праграмы загружаюцца…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Праграм, якія адпавядаюць запыту \"<xliff:g id="QUERY">%1$s</xliff:g>\", не знойдзена"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукаць іншыя праграмы"</string>
+    <string name="label_application" msgid="8531721983832654978">"Праграма"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Апавяшчэнні"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Дакраніцеся і ўтрымлiвайце ярлык, каб дадаць яго."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Дакраніцеся двойчы і ўтрымлівайце, каб выбраць ярлык або выкарыстоўваць спецыяльныя дзеянні."</string>
@@ -49,7 +50,7 @@
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"Спіс працоўных праграм"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"Галоўная"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"Выдаліць"</string>
-    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Выдаліць"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Дэінсталяваць"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"Звесткі пра праграмы"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"Усталяваць"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"усталёўваць ярлыкі"</string>
@@ -64,11 +65,11 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Гэта сістэмная праграма, яе нельга выдаліць."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Папка без назвы"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> адключана"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>: ёсць <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэнне</item>
-      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>: ёсць <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэнні</item>
-      <item quantity="many"><xliff:g id="APP_NAME_2">%1$s</xliff:g>: ёсць <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэнняў</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>: ёсць <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэння</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, мае <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэнне</item>
+      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, мае <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэнні</item>
+      <item quantity="many"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, мае <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэнняў</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, мае <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> апавяшчэння</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Старонка %1$d з %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Галоўны экран %1$d з %2$d"</string>
@@ -85,23 +86,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Адключаная адміністратарам"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Дазволіць паварот галоўнага экрана"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Пры павароце тэлефона"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Значкі апавяшчэнняў"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Уключана"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Выключана"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Значкі апавяшчэнняў"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Укл."</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Выкл."</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Патрабуецца доступ да апавяшчэнняў"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Каб паказваліся значкі апавяшчэнняў, уключыце апавяшчэнні праграм для <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Змяніць налады"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Паказаць значкі апавяшчэнняў"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Паказваць значкі апавяшчэнняў"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Дадаць значок на Галоўны экран"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Для новых праграм"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Змяніць форму значка"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"на галоўным экране"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Выкарыстоўваць стандартныя формы"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Прамавугольнік са скругленымі вугламі"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Сляза"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Змены формы значка прымяняюцца"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Невядома"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Выдаліць"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Шукаць"</string>
@@ -147,4 +140,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Апавяшчэнні і праграмы выключаны"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Закрыць"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Закрытыя"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Не ўдалося: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 74c361b..436e890 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Приложенията се зареждат…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Няма намерени приложения, съответстващи на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Търсене на още приложения"</string>
+    <string name="label_application" msgid="8531721983832654978">"Приложение"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Това е системно приложение и не може да се деинсталира."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Папка без име"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Деактивирахте <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> – има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> известия</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> – има <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> известие</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Деактивирано от администратора ви"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Разрешаване на завъртането на началния екран"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"При завъртане на телефона"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Точки за известия"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Включено"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Изключено"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Точки за известия"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Вкл."</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Изкл."</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Необходим е достъп до известията"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"За да се показват точки за известия, включете известията за приложението <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Промяна на настройките"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Показване на точките за известия"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Показване на точките за известия"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Добавяне на икона към началния екран"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови приложения"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Промяна на формата на иконите"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"на началния екран"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Използване на стандартната системна настройка"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Комбинация от кръг и квадрат"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Кръг"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Сълза"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Промените във формата на иконите се прилагат"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Няма информация"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Премахване"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Търсене"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Известията и приложенията са изключени"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Затваряне"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Затворено"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Неуспешно: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 859bddf..7efacf3 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"অ্যাপ লোড হচ্ছে…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" এর সাথে মেলে এমন কোনো অ্যাপ পাওয়া যায়নি"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"আরও অ্যাপ্লিকেশানের জন্য খুঁজুন"</string>
+    <string name="label_application" msgid="8531721983832654978">"অ্যাপ"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"এটি একটি সিস্টেম অ্যাপ্লিকেশান এবং আনইনস্টল করা যাবে না৷"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"নামবিহীন ফোল্ডার"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> অক্ষম করা হয়েছে"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> এ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টি বিজ্ঞপ্তি আছে</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> এ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টি বিজ্ঞপ্তি আছে</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টি বিজ্ঞপ্তি আছে</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>টি বিজ্ঞপ্তি আছে</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%2$dটির মধ্যে %1$dটি পৃষ্ঠা"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dটির %1$d নম্বর হোম স্ক্রিন"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"হোমস্ক্রীন ঘোরানোর অনুমতি দিন"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"যখন ফোনটি ঘোরানো হয়"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"বিজ্ঞপ্তি ডট"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"চালু হয়েছে"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"বন্ধ আছে"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"বিজ্ঞপ্তি ডট"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"চালু"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"বন্ধ"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"বিজ্ঞপ্তিতে অ্যাক্সেস প্রয়োজন"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"বিজ্ঞপ্তির ডটগুলি দেখানোর জন্য, <xliff:g id="NAME">%1$s</xliff:g> এর অ্যাপ বিজ্ঞপ্তি চালু করুন"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"সেটিংস পরিবর্তন করুন"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"বিজ্ঞপ্তির ডট দেখুন"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"বিজ্ঞপ্তির ডট দেখুন"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"হোম স্ক্রিনে আইকন যোগ করুন"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন অ্যাপ্লিকেশানগুলির জন্যে"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"আইকনের আকৃতি পরিবর্তন করুন"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"হোম স্ক্রিনে"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"সিস্টেমের ডিফল্ট মান ব্যবহার করুন"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"চৌকো"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"চৌকো-গোলাকার"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"গোলাকার"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"চোখের জল"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"আইকনের আকৃতি পরিবর্তন করা হচ্ছে"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"অজানা"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"সরান"</string>
     <string name="abandoned_search" msgid="891119232568284442">"সার্চ"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"বিজ্ঞপ্তি এবং অ্যাপ বন্ধ আছে"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"বন্ধ করুন"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"বন্ধ"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"কাজটি করা যায়নি: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 1e2b267..6703d22 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za upit \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži više aplikacija"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obavještenja"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Dodirnite i držite da uzmete prečicu."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dodirnite dvaput i držite da uzmete prečicu ili koristite prilagođene akcije."</string>
@@ -64,10 +65,10 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ovo je sistemska aplikacija i ne može se deinstalirati."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Neimenovani folder"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućena"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavještenje</item>
-      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavještenja</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavještenja</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavještenje​</item>
+      <item quantity="few">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavještenja​</item>
+      <item quantity="other">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavještenja​</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Strana %1$d od %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Početni ekran %1$d od %2$d"</string>
@@ -84,23 +85,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio vaš administrator"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotiranje početnog ekrana"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon zarotira"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Tačke za obavještenja"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Uključeno"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Isključeno"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Tačke za obavještenja"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Uključeno"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Isključeno"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Potreban je pristup obavještenjima"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Za prikaz tačaka obavještenja, uključite obavještenja za aplikacije za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Promijeni postavke"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Prikaži tačke za obavještenja"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Prikaži tačke za obavještenja"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonu na početni ekran"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Promjena oblika ikona"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"na Početnom ekranu"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Koristite sistemski zadano"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaobljeni kvadrat"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Krug"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Suza"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Primjenjivanje promjena oblika ikona"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Ukloni"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Pretraži"</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index df4f3f2..a4f701f 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"S\'estan carregant les aplicacions…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No s\'ha trobat cap aplicació que coincideixi amb \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca més aplicacions"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplicació"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificacions"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Mantén premuda una drecera per seleccionar-la."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Fes doble toc i mantén premut per seleccionar una drecera o per utilitzar accions personalitzades."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Aquesta aplicació és una aplicació del sistema i no es pot desinstal·lar."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Carpeta sense nom"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"S\'ha desactivat <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> té <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificacions</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> té <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificació</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>​ té <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificacions</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> té <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificació</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Pàgina %1$d de %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla d\'inici %1$d de %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desactivada per l\'administrador"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permet la rotació de la pantalla d\'inici"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"En girar el telèfon"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Punts de notificació"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activat"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivat"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Punts de notificació"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activats"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivats"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Cal que tingui accés a les notificacions"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Per veure els punts de notificació, activa les notificacions de l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Canvia la configuració"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Mostra els punts de notificació"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostra els punts de notificació"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Afegeix la icona a la pantalla d\'inici"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per a les aplicacions noves"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Canvia la forma de les icones"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"a la pantalla d\'inici"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Utilitza l\'opció predeterminada del sistema"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Quadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Quadrat arrodonit"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Cercle"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Llàgrima"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"S\'estan aplicant els canvis de forma de les icones"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconegut"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Suprimeix"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Cerca"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Les notificacions i les aplicacions estan desactivades"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Tanca"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"S\'ha tancat"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index f26226c..a9e705a 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Načítání aplikací…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Dotazu „<xliff:g id="QUERY">%1$s</xliff:g>“ neodpovídají žádné aplikace"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Vyhledat další aplikace"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikace"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Oznámení"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Zkratku vyberete podržením."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dvojitým klepnutím a podržením vyberte zkratku, případně použijte vlastní akce."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikace a nelze ji odinstalovat."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Složka bez názvu"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> je zakázána"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="few">Aplikace <xliff:g id="APP_NAME_2">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> oznámení</item>
       <item quantity="many">Aplikace <xliff:g id="APP_NAME_2">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> oznámení</item>
       <item quantity="other">Aplikace <xliff:g id="APP_NAME_2">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> oznámení</item>
@@ -85,23 +86,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázáno administrátorem"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Povolit otáčení plochy"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Při otočení telefonu"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Puntíky s oznámením"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Zapnuto"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Vypnuto"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Puntíky s oznámením"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Zapnuto"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Vypnuto"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Je třeba udělit přístup k oznámením"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Chcete-li zobrazovat puntíky s oznámením, zapněte oznámení z aplikace <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Změnit nastavení"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Zobrazovat puntíky s oznámením"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Zobrazovat puntíky s oznámením"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Přidat ikonu na plochu"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pro nové aplikace"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Změnit tvar ikony"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"na ploše"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Použít výchozí nastavení systému"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Čtverec"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Kruh/čtverec"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Kruh"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Slza"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Tvar ikony se mění"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Neznámé"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Odstranit"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Hledat"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 6b78770..573da2d 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -33,17 +33,18 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tryk to gange, og hold fingeren nede for at vælge en widget eller bruge tilpassede handlinger."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i bredden og %2$d i højden"</string>
-    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tryk, og hold fingeren nede for at placere manuelt"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tryk og hold fingeren nede for at placere manuelt"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Tilføj automatisk"</string>
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søg efter apps"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Indlæser apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Der blev ikke fundet nogen apps, som matcher \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søg efter flere apps"</string>
-    <string name="notifications_header" msgid="1404149926117359025">"Underretninger"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Notifikationer"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Hold en genvej nede for at samle den op."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Tryk to gange, og hold en genvej nede for at samle den op eller bruge tilpassede handlinger."</string>
     <string name="out_of_space" msgid="4691004494942118364">"Der er ikke mere plads på denne startskærm."</string>
-    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Der er ikke mere plads i bakken Foretrukne"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Der er ikke mere plads i bakken Favoritter"</string>
     <string name="all_apps_button_label" msgid="8130441508702294465">"Liste med apps"</string>
     <string name="all_apps_button_personal_label" msgid="1315764287305224468">"Liste over personlige apps"</string>
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"Liste over apps til arbejdet"</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dette er en systemapp, som ikke kan afinstalleres."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Unavngiven mappe"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> er deaktiveret"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> underretning</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> underretninger</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifikation</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifikationer</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Side %1$d ud af %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Startskærm %1$d ud af %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Deaktiveret af din administrator"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Tillad rotation af startskærmen"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Underretningscirkler"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Til"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Fra"</string>
-    <string name="title_missing_notification_access" msgid="7503287056163941064">"Kræver adgang til underretninger"</string>
-    <string name="msg_missing_notification_access" msgid="281113995110910548">"Hvis du vil se underretningscirkler, skal du aktivere appunderretninger for <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Notifikationscirkler"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Til"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Fra"</string>
+    <string name="title_missing_notification_access" msgid="7503287056163941064">"Kræver adgang til notifikationer"</string>
+    <string name="msg_missing_notification_access" msgid="281113995110910548">"Hvis du vil se notifikationscirkler, skal du aktivere appnotifikationer for <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Skift indstillinger"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Vis underretningscirkler"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Vis notifikationscirkler"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Føj ikon til startskærmen"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For nye apps"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Skift ikonform"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"på startskærmen"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Brug systemstandarden"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Kvadrat med runde hjørner"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Cirkel"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Dråbeform"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Anvender ændringer af ikonform"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Ukendt"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Fjern"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Søg"</string>
@@ -133,18 +126,17 @@
     <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_with_notifications_description" msgid="2676582286544232849">"Genveje og underretninger"</string>
+    <string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"Genveje og notifikationer"</string>
     <string name="action_dismiss_notification" msgid="5909461085055959187">"Afvis"</string>
-    <string name="notification_dismissed" msgid="6002233469409822874">"Underretningen blev afvist"</string>
+    <string name="notification_dismissed" msgid="6002233469409822874">"Notifikationen blev afvist"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personlige"</string>
     <string name="all_apps_work_tab" msgid="4884822796154055118">"Arbejde"</string>
     <string name="work_profile_toggle_label" msgid="3081029915775481146">"Arbejdsprofil"</string>
     <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"Find arbejdsapps her"</string>
     <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"Alle arbejdsapps har et badge og beskyttes af din organisation. Flyt apps til din startskærm, så du nemmere kan få adgang til dem."</string>
     <string name="work_mode_on_label" msgid="4781128097185272916">"Administreret af din organisation"</string>
-    <string name="work_mode_off_label" msgid="3194894777601421047">"Underretninger og apps er slået fra"</string>
+    <string name="work_mode_off_label" msgid="3194894777601421047">"Notifikationer og apps er slået fra"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Luk"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Lukket"</string>
-    <!-- no translation found for remote_action_failed (1383965239183576790) -->
-    <skip />
+    <string name="remote_action_failed" msgid="1383965239183576790">"Mislykket: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 20f2a9c..d26661d 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Apps werden geladen…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Keine Apps für \"<xliff:g id="QUERY">%1$s</xliff:g>\" gefunden"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Weitere Apps suchen"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Benachrichtigungen"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tippen und halten, um eine Verknüpfung auszuwählen."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Doppeltippen und halten, um eine Verknüpfung auszuwählen oder benutzerdefinierte Aktionen zu nutzen."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dies ist eine Systemanwendung, die nicht deinstalliert werden kann."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Unbenannter Ordner"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> deaktiviert"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, hat <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> Benachrichtigungen</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, hat <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> Benachrichtigung</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Von deinem Administrator deaktiviert"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Drehung des Startbildschirms zulassen"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Bei Drehung des Smartphones"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"App-Benachrichtigungspunkte"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktiviert"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Deaktiviert"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"App-Benachrichtigungspunkte"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"An"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Aus"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Benachrichtigungszugriff erforderlich"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Um dir Benachrichtigungspunkte anzeigen zu lassen, aktiviere die Benachrichtigungen für die App \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Einstellungen ändern"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"App-Benachrichtigungspunkte anzeigen"</string>
-    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Symbol zu Startbildschirm hinzufügen"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"App-Benachrichtigungspunkte anzeigen"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Symbol zum Startbildschirm hinzufügen"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Für neue Apps"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Form des Symbols ändern"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"auf dem Startbildschirm"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Systemstandardeinstellung verwenden"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Quadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Superkreis"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Kreis"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Träne"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Änderungen an der Form des Symbols werden übernommen"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Unbekannt"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Entfernen"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Suchen"</string>
@@ -145,6 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Benachrichtigungen und Apps sind deaktiviert"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Schließen"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Geschlossen"</string>
-    <!-- no translation found for remote_action_failed (1383965239183576790) -->
-    <skip />
+    <string name="remote_action_failed" msgid="1383965239183576790">"Fehler: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index eef66ff..9745089 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Φόρτωση εφαρμογών…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Δεν βρέθηκαν εφαρμογές αντιστοίχισης για \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Αναζήτηση περισσότερων εφαρμογών"</string>
+    <string name="label_application" msgid="8531721983832654978">"Εφαρμογή"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Αυτή είναι μια εφαρμογή συστήματος και δεν είναι δυνατή η κατάργηση της εγκατάστασής της."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Φάκελος χωρίς όνομα"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> είναι απενεργοποιημένη"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other">Η εφαρμογή <xliff:g id="APP_NAME_2">%1$s</xliff:g> έχει <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ειδοποιήσεις</item>
-      <item quantity="one">Η εφαρμογή <xliff:g id="APP_NAME_0">%1$s</xliff:g> έχει <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ειδοποίηση</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other">Η εφαρμογή <xliff:g id="APP_NAME_2">%1$s</xliff:g>, έχει <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ειδοποιήσεις</item>
+      <item quantity="one">Η εφαρμογή <xliff:g id="APP_NAME_0">%1$s</xliff:g>, έχει <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ειδοποίηση</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Σελίδα %1$d από %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Αρχική οθόνη %1$d από %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Απενεργοποιήθηκε από τον διαχειριστή σας"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Όταν το τηλέφωνο περιστρέφεται"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Κουκκίδες ειδοποίησης"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Ενεργή"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Ανενεργή"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Κουκκίδες ειδοποίησης"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Ενεργοποίηση"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Απενεργοποίηση"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Απαιτείται πρόσβαση στις ειδοποιήσεις"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Για να εμφανιστούν οι Κουκκίδες ειδοποίησης, ενεργοποιήστε τις κουκκίδες εφαρμογής για την εφαρμογή <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Αλλαγή ρυθμίσεων"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Εμφάνιση κουκκίδων ειδοποίησης"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Εμφάνιση κουκκίδων ειδοποιήσεων"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Προσθήκη εικονιδίου στην Αρχική οθόνη"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Για νέες εφαρμογές"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Αλλαγή σχήματος εικονιδίου"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"στην Αρχική οθόνη"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Χρήση προεπιλογής συστήματος"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Τετράγωνο"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Στρογγυλεμένο τετράγωνο"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Κύκλος"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Δάκρυ"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Εφαρμογή αλλαγών σχήματος εικονιδίων"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Άγνωστο"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Κατάργηση"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Αναζήτηση"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 0494eb4..04c341c 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Touch &amp; hold to pick up a shortcut."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Unnamed Folder"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Disabled <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notification</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Notification dots"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"On"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Off"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Notification dots"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Notification access needed"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Show notification dots"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Show notification dots"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Change icon shape"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"on Home screen"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Use system default"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Square"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Circle"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Teardrop"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Applying icon shape changes"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Search"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 0494eb4..04c341c 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Touch &amp; hold to pick up a shortcut."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Unnamed Folder"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Disabled <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notification</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Notification dots"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"On"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Off"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Notification dots"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Notification access needed"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Show notification dots"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Show notification dots"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Change icon shape"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"on Home screen"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Use system default"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Square"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Circle"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Teardrop"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Applying icon shape changes"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Search"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 0494eb4..04c341c 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Touch &amp; hold to pick up a shortcut."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"This is a system app and can\'t be uninstalled."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Unnamed Folder"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Disabled <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notification</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"When phone is rotated"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Notification dots"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"On"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Off"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Notification dots"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Notification access needed"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"To show Notification Dots, turn on app notifications for <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Change settings"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Show notification dots"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Show notification dots"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Add icon to Home screen"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For new apps"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Change icon shape"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"on Home screen"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Use system default"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Square"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Circle"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Teardrop"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Applying icon shape changes"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Remove"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Search"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 208e822..4f5a13a 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No hay apps que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más apps"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Mantén presionado para elegir un acceso directo."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Presiona dos veces y mantén presionado para elegir un acceso directo o usar acciones personalizadas."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta es una aplicación del sistema y no se puede desinstalar."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Carpeta sin nombre"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Se inhabilitó <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificaciones</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificación</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificaciones</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificación</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla principal %1$d de %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"El administrador inhabilitó esta función"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir la rotación de la pantalla principal"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Al girar el teléfono"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Puntos de notificación"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activada"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivada"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Puntos de notificación"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activado"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"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 los puntos de notificación, activa las notificaciones de la app para <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Cambiar la configuración"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Mostrar puntos de notificación"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar puntos de notificación"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Agregar ícono a la pantalla principal"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para nuevas apps"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Cambiar forma de los íconos"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"en la pantalla principal"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Usar valores predeterminados del sistema"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Cuadrado"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Cuadrado con esquinas redondeadas"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Gota"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Aplicando cambio en la forma de los íconos"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Eliminar"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Buscar"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Las notificaciones y las apps están desactivadas"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Cerrar"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Cerrado"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 9672e1b..899b2f1 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicaciones…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más aplicaciones"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplicación"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Mantén pulsado para elegir un acceso directo."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Toca dos veces y mantén pulsado para elegir un acceso directo o utilizar acciones personalizadas."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta aplicación es del sistema y no se puede desinstalar."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Carpeta sin nombre"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Se ha inhabilitado <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificaciones</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> tiene <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificación</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inhabilitado por el administrador"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotación de la pantalla de inicio"</string>
     <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">"Desactivado"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Burbujas de notificación"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activadas"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Desactivadas"</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>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Mostrar burbujas de notificación"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar burbujas de notificación"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Añadir icono a la pantalla de inicio"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para aplicaciones nuevas"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Cambiar forma de los iconos"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"en la pantalla de inicio"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Usar opción predeterminada del sistema"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Cuadrado"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Cuadrado con esquinas redondeadas"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lágrima"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Aplicando cambios en la forma de los iconos"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Quitar"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Buscar"</string>
@@ -134,7 +127,7 @@
     <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_with_notifications_description" msgid="2676582286544232849">"Accesos directos y notificaciones"</string>
-    <string name="action_dismiss_notification" msgid="5909461085055959187">"Ignorar"</string>
+    <string name="action_dismiss_notification" msgid="5909461085055959187">"Cerrar"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"Notificación ignorada"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"Personal"</string>
     <string name="all_apps_work_tab" msgid="4884822796154055118">"Trabajo"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Las notificaciones y las aplicaciones están desactivadas"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Cerrar"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Cerrada"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Se ha producido un error: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index c8b5d4b..269bb20 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Rakenduste laadimine …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Päringule „<xliff:g id="QUERY">%1$s</xliff:g>” ei vastanud ükski rakendus"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Otsi rohkem rakendusi"</string>
+    <string name="label_application" msgid="8531721983832654978">"Rakendus"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Märguanded"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Otsetee valimiseks puudutage seda pikalt."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Topeltpuudutage ja hoidke otsetee valimiseks või kohandatud toimingute kasutamiseks."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"See on süsteemirakendus ja seda ei saa desinstallida."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Nimetu kaust"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Rakendus <xliff:g id="APP_NAME">%1$s</xliff:g> on keelatud"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> märguannet</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> – <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> märguanne</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> märguanne</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Leht %1$d/%2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Avaekraan %1$d/%2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Keelas administraator"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Luba avaekraani pööramine"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Kui telefoni pööratakse"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Märguandetäpid"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Sees"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Väljas"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Märguandetäpid"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Sees"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Väljas"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Vaja on juurdepääsu märguannetele"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Märguandetäppide kuvamiseks lülitage sisse rakenduse <xliff:g id="NAME">%1$s</xliff:g> märguanded"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Seadete muutmine"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Kuva märguandetäpid"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Kuva märguandetäpid"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisa ikoon avaekraanile"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uute rakenduste puhul"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Ikooni kuju muutmine"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"avaekraanil"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Kasuta süsteemi vaikeseadet"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Ruut"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Ümarate nurkadega ruut"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Ring"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Tilk"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Ikooni kuju muudatuste rakendamine"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Teadmata"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Eemalda"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Otsing"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Märguanded ja rakendused on välja lülitatud"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Sule"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Suletud"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Nurjus: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 29d96f8..9a07a20 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikazioak kargatzen…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketaren emaitzarik"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Bilatu aplikazio gehiago"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikazioa"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Jakinarazpenak"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Eduki sakatuta lasterbide bat aukeratzeko."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Sakatu birritan eta eduki sakatuta lasterbide bat aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Sistema-aplikazioa da hau eta ezin da desinstalatu."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Izenik gabeko karpeta"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desgaituta dago"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> jakinarazpen dauzka <xliff:g id="APP_NAME_2">%1$s</xliff:g> aplikazioak</item>
-      <item quantity="one"><xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> jakinarazpen dauka <xliff:g id="APP_NAME_0">%1$s</xliff:g> aplikazioak</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> aplikazioak <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> jakinarazpen ditu</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> aplikazioak <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> jakinarazpen du</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%1$d/%2$d orria"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d/%2$d hasierako pantaila"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Baimendu hasierako pantaila biratzea"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Telefonoa biratzen denean"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Jakinarazpen-biribiltxoak"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktibatuta"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desaktibatuta"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Jakinarazpen-biribiltxoak"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktibatuta"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Desaktibatuta"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Jakinarazpenetarako sarbidea behar da"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Jakinarazpen-biribiltxoak ikusteko, aktibatu <xliff:g id="NAME">%1$s</xliff:g> aplikazioaren jakinarazpenak"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Aldatu ezarpenak"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Erakutsi jakinarazpen-biribiltxoak"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Erakutsi jakinarazpen-biribiltxoak"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Gehitu ikonoa hasierako pantailan"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Aplikazio berrietan"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Aldatu ikonoaren forma"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"Hasierako pantailan"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Erabili sistemaren balio lehenetsiak"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Karratua"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Ertz biribilduko karratua"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Zirkulua"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Malkoa"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Ikonoaren forman egindako aldaketak aplikatzen"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Ezezaguna"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Kendu"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Bilatu"</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index e78af15..f2c0998 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"درحال بارگیری برنامه‌‌ها…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"هیچ برنامه‌ای در مطابقت با «<xliff:g id="QUERY">%1$s</xliff:g>» پیدا نشد"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"جستجوی برنامه‌های بیشتر"</string>
+    <string name="label_application" msgid="8531721983832654978">"برنامه"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"این برنامه سیستمی است و حذف نصب نمی‌شود."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"پوشه بی‌نام"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> غیرفعال شد"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> اعلان دارد</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> اعلان دارد</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>، <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> اعلان دارد</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>، <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> اعلان دارد</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"‏صفحه %1$d از %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"‏صفحه اصلی %1$d از %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"توسط سرپرست سیستم غیرفعال شده است"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"امکان دادن به چرخش صفحه اصلی"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"وقتی تلفن چرخانده می‌شود"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"نقطه‌های اعلان"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"روشن"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"خاموش"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"نقطه‌های اعلان"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"روشن"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"خاموش"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"دسترسی به اعلان نیاز است"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"برای نمایش «نقطه‌های اعلان»، اعلان‌های برنامه را برای <xliff:g id="NAME">%1$s</xliff:g> روشن کنید"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"تغییر تنظیمات"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"نمایش نقطه‌های اعلان"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"نمایش نقطه‌های اعلان"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"افزودن نماد به صفحه اصلی"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"برای برنامه‌های جدید"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"تغییر شکل نماد"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"در صفحه اصلی"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"استفاده از پیش‌فرض سیستم"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"مربع"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"مربع با گوشه‌های گرد"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"دایره"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"قطره اشک"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"درحال اعمال کردن تغییرات شکل نماد"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"نامشخص"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"حذف"</string>
     <string name="abandoned_search" msgid="891119232568284442">"جستجو"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index ed620e5..ba4e68f 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Ladataan sovelluksia…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> ei palauttanut sovelluksia."</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hae lisää sovelluksia"</string>
+    <string name="label_application" msgid="8531721983832654978">"Sovellus"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Ilmoitukset"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Valitse pikakuvake painamalla sitä pitkään."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Valitse pikakuvake tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla pitkään."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Tämä on järjestelmäsovellus, eikä sitä voi poistaa."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Nimetön kansio"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> poistettiin käytöstä"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>: <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ilmoitusta</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>: <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ilmoitus</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Järjestelmänvalvoja on poistanut toiminnon käytöstä."</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Salli aloitusnäytön kiertäminen"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Kun puhelinta kierretään"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Pistemerkit"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Käytössä"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Pois käytöstä"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Pistemerkit"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Käytössä"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Ei käytössä"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Ilmoituksien käyttöoikeus tarvitaan"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"<xliff:g id="NAME">%1$s</xliff:g> tarvitsee ilmoitusten käyttöoikeuden, jotta pistemerkkejä voidaan näyttää."</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Muuta asetuksia"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Näytä ilmoituksista kertovat pistemerkit"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Näytä ilmoituksista kertovat pistemerkit"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lisää kuvake aloitusruutuun"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Uusille sovelluksille"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Muuta kuvakkeen muotoa"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"aloitusnäytöllä"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Käytä järjestelmän oletusarvoa"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Neliö"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Ympyräneliö"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Ympyrä"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Pisara"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Sovelletaan kuvakkeiden muotojen muutoksia"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Tuntematon"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Poista"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Haku"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Ilmoitukset ja sovellukset ovat poissa käytöstä"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Sulje"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Suljettu"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Epäonnistui: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index dc32a3b..4ea32c0 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications en cours…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application trouvée correspondant à « <xliff:g id="QUERY">%1$s</xliff:g> »"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
+    <string name="label_application" msgid="8531721983832654978">"Application"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Maintenez un doigt sur le raccourci pour l\'ajouter"</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Touchez 2x un raccourci et maintenez doigt dessus pour l’aj. ou utiliser des actions personnalisées."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Impossible de désinstaller cette application, car il s\'agit d\'une application système."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Dossier sans nom"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"L\'application <xliff:g id="APP_NAME">%1$s</xliff:g> est désactivée"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> a <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notification</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> a <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> a <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificatio​ns</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Page %1$d sur %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Écran d\'accueil %1$d sur %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Cette fonction est désactivée par votre administrateur"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Points de notification"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activé"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Désactivé"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Points de notification"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activé"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Désactivé"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"L\'accès aux notifications est requis"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Pour afficher les points de notification, activez les notifications d\'application pour <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Modifier les paramètres"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Afficher les points de notification"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Afficher les points de notification"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ajouter l\'icône à l\'écran d\'accueil"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pour les nouvelles applications"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Modifier la forme de l\'icône"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"sur l\'écran d\'accueil"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Utiliser les valeurs système par défaut"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Carré"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Carré aux coins ronds"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Cercle"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Goutte"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Application des changements à la forme de l\'icône en cours…"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Supprimer"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Rechercher"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Les notifications et les applications sont désactivées"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Fermer"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Fermé"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index e2d5e79..696dec9 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -33,12 +33,13 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Appuyez 2 fois et maintenez la pression pour sélectionner widget ou utilisez actions personnalisées."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur et %2$d de hauteur"</string>
-    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Appuyez de manière prolongée pour placer l\'élément manuellement"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Appuyez de manière prolongée pour placer l\'élément manuellement."</string>
     <string name="place_automatically" msgid="8064208734425456485">"Ajouter automatiquement"</string>
     <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application ne correspond à la requête \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
+    <string name="label_application" msgid="8531721983832654978">"Application"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Appui prolongé pour sélectionner un raccourci."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Appuyez 2X et maintenez la pression pour choisir un raccourci ou utilisez les actions personnalisées"</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Impossible de désinstaller cette application, car il s\'agit d\'une application système."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Dossier sans nom"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> est désactivé."</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> comporte <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notification</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> comporte <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Désactivé par votre administrateur"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Lorsque vous faites pivoter le téléphone"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Pastilles de notification"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activé"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Désactivé"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Pastilles de notification"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activées"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Désactivées"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Accès aux notifications requis"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Pour afficher les pastilles de notification, activez les notifications de l\'application <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Modifier les paramètres"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Afficher les pastilles de notification"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Afficher les pastilles de notification"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ajouter l\'icône à l\'écran d\'accueil"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pour les nouvelles applications"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Modifier la forme des icônes"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"sur l\'écran d\'accueil"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Utiliser la valeur système par défaut"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Carré"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Cercle"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Goutte"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Application des modifications de forme des icônes…"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Supprimer"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Rechercher"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Les notifications et les applications sont désactivées"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Fermer"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Fermé"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Échec : <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 1e6184e..00528b4 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicacións…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Non se atoparon aplicacións que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar máis aplicacións"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplicación"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificacións"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Mantén premido un atallo para seleccionalo."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Toca dúas veces e mantén premido para seleccionar un atallo ou utiliza accións personalizadas."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta aplicación é do sistema e non se pode desinstalar."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Cartafol sen nome"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Desactivouse <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ten <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificacións</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ten <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificación</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other">A aplicación <xliff:g id="APP_NAME_2">%1$s</xliff:g> ten <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificacións</item>
+      <item quantity="one">A aplicación <xliff:g id="APP_NAME_0">%1$s</xliff:g> ten <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificación</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Páxina %1$d de %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Pantalla de inicio %1$d de %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Función desactivada polo administrador"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir xirar a pantalla de inicio"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Ao xirar o teléfono"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Puntos de notificacións"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activado"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desactivado"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Puntos de notificacións"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Opción activada"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Opción desactivada"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Necesítase acceso ás notificacións"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Para que se mostren os puntos de notificacións, activa as notificacións da aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Cambiar configuración"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Mostrar puntos de notificación"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar puntos de notificacións"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Engadir icona á pantalla de inicio"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas aplicacións"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Cambiar forma das iconas"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"na pantalla de inicio"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Usar valores predeterminados do sistema"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Cadrado"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Cadrado de bordos redondeados"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Bágoa"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Aplicando cambios na forma das iconas"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Descoñecido"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Eliminar"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Buscar"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"As notificacións e as aplicacións están desactivadas"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Pechar"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Pechada"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Erro: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index bc0608e..181422a 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"વધુ ઍપ્લિકેશનો શોધો"</string>
+    <string name="label_application" msgid="8531721983832654978">"ઍપ"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"આ એક સિસ્ટમ ઍપ્લિકેશન છે અને અનઇન્સ્ટોલ કરી શકાતી નથી."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"અનામી ફોલ્ડર"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> અક્ષમ કરી"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>ના <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> નોટિફિકેશન છે</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>ના <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> નોટિફિકેશન છે</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"જ્યારે ફોન ફેરવવામાં આવે ત્યારે"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"સૂચના બિંદુઓ"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ચાલુ"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"બંધ"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"નોટિફિકેશન માટેના ચિહ્નો"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ચાલુ છે"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"બંધ છે"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"નોટિફિકેશનનો ઍક્સેસની જરૂરી છે"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"નોટિફિકેશન માટેનું ચિહ્ન બતાવવા હેતુ, <xliff:g id="NAME">%1$s</xliff:g> માટેની ઍપ્લિકેશન નોટિફિકેશન ચાલુ કરો"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"સેટિંગ્સ બદલો"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"નોટિફિકેશન માટેનું ચિહ્ન બતાવો"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"નોટિફિકેશન માટેના ચિહ્ન બતાવો"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"હોમ સ્ક્રીન પર આઇકન ઉમેરો"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"નવી ઍપ્લિકેશનો માટે"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"આઇકનનો આકાર બદલો"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"હોમ સ્ક્રીન પર"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"સિસ્ટમ ડિફૉલ્ટનો ઉપયોગ કરો"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"ચોરસ"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"ચોરસ જેવું ગોળ"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"વર્તુળ"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"ટિઅરડ્રોપ"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"આઇકનના આકારમાં કરેલ ફેરફારો લાગુ કરી રહ્યા છીએ"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"અજાણ્યો"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"દૂર કરો"</string>
     <string name="abandoned_search" msgid="891119232568284442">"શોધો"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"નોટિફિકેશન અને ઍપ બંધ છે"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"બંધ કરો"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"બંધ"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"નિષ્ફળ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index ecb5fcb..ca35c2f 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ऐप्लिकेशन लोड हो रहे हैं…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" से मिलता-जुलता कोई ऐप्लिकेशन नहीं मिला"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"और ऐप सर्च करें"</string>
+    <string name="label_application" msgid="8531721983832654978">"ऐप्लिकेशन"</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>
@@ -50,7 +51,7 @@
     <string name="all_apps_home_button_label" msgid="252062713717058851">"होम पेज"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"निकालें"</string>
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"अनइंस्टॉल करें"</string>
-    <string name="app_info_drop_target_label" msgid="692894985365717661">"ऐप की जानकारी"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"ऐप्लिकेशन की जानकारी"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"इंस्‍टॉल करें"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट इंस्‍टॉल करें"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"ऐप को उपयोगकर्ता के हस्‍तक्षेप के बिना शॉर्टकट जोड़ने देती है."</string>
@@ -64,8 +65,8 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"यह एक सिस्टम ऐप्लिकेशन है और इसे अनइंस्टॉल नहीं किया जा सकता."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"अनामित फ़ोल्डर"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> अक्षम है"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> की <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचनाएं हैं</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> की <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचना है</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> की <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचनाएं हैं</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"पेज %2$d में से %1$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपके एडमिन ने बंद किया हुआ है"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"होमस्क्रीन घुमाने की अनुमति दें"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"फ़ोन घुुमाए जाने पर"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"सूचना बिंदु"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"चालू"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"बंद"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"नई सूचनाएं बताने वाला गोल निशान"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"चालू"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"चालू"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"सूचना के एक्सेस की ज़रूरत है"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"सूचना बिंदु दिखाने के लिए, <xliff:g id="NAME">%1$s</xliff:g> के ऐप्लिकेशन सूचना चालू करें"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"सेटिंग बदलें"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"नई सूचनाएं बताने वाला गोल निशान दिखाएं"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"नई सूचनाएं बताने वाला गोल निशान दिखाएं"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"होम स्क्रीन में आइकॉन जोड़ें"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नए ऐप्लिकेशन के लिए"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"आइकॉन का आकार बदलें"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"होम स्‍क्रीन पर"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"सिस्टम डिफ़ॉल्ट का उपयोग करें"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"वर्ग"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"गोल कोनों वाला वर्ग"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"मंडली"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"आंसू की बूंद"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"आइकॉन के आकार में बदलाव किए जा रहे हैं"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"निकालें"</string>
     <string name="abandoned_search" msgid="891119232568284442">"सर्च करें"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"सूचनाएं और ऐप्लिकेशन बंद हैं"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"बंद करें"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"बंद कर दिया गया"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"पूरा नहीं हुआ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index a4b4028..a15fcb2 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Učitavanje aplikacija…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nema aplikacija podudarnih s upitom \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Traži više aplikacija"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obavijesti"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Dodirnite i zadržite kako biste podigli prečac."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dvaput dodirnite i zadržite pritisak kako biste podigli prečac ili pokušajte prilagođenim radnjama."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ovo je aplikacija sustava i ne može se ukloniti."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Neimenovana mapa"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> onemogućena"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavijest</item>
       <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavijesti</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obavijesti</item>
@@ -84,23 +85,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio administrator"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Dopusti zakretanje početnog zaslona"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Kada se telefon zakrene"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Točke obavijesti"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Uključeno"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Isključeno"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Točke obavijesti"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Uključeno"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Isključeno"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Potreban je pristup obavijestima"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Za prikaz točaka obavijesti uključite obavijesti aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Promjena postavki"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Prikaži točke obavijesti"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Prikaži točke obavijesti"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonu na početni zaslon"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Promijeni oblik ikona"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"na početnom zaslonu"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Upotrijebi zadane postavke sustava"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaobljeni kvadrat"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Krug"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Suza"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Primjena promjena oblika ikona"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Ukloni"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Traži"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index df2106d..fb3a149 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Alkalmazások betöltése…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nem található alkalmazás a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"További alkalmazások keresése"</string>
+    <string name="label_application" msgid="8531721983832654978">"Alkalmazás"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Értesítések"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Felvételhez tartsa nyomva a parancsikont."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Parancsikon felvételéhez koppintson rá duplán és tartsa nyomva, vagy használjon egyéni műveleteket."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ez egy rendszeralkalmazás, és nem lehet eltávolítani."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Névtelen mappa"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> letiltva"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other">A(z) <xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> értesítéssel rendelkezik</item>
       <item quantity="one">A(z) <xliff:g id="APP_NAME_0">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> értesítéssel rendelkezik</item>
     </plurals>
@@ -83,25 +84,17 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"A rendszergazda letiltotta"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"A kezdőképernyő elforgatásának engedélyezése"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"A telefon elforgatásakor"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Értesítési pöttyök"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Bekapcsolva"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Kikapcsolva"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Értesítési pöttyök"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Be"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Ki"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Értesítésekhez való hozzáférésre van szükség"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Az értesítési pöttyök megjelenítéséhez kapcsolja be a(z) <xliff:g id="NAME">%1$s</xliff:g> alkalmazás értesítéseit"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Beállítások módosítása"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Értesítési pöttyök megjelenítése"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Értesítési pöttyök megjelenítése"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ikon hozzáadása a kezdőképernyőhöz"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Új alkalmazásoknál"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Ikon formájának módosítása"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"a kezdőképernyőn"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Alapértelmezett érték használata"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Négyzet"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Kör"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Könnycsepp"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Ikonforma módosításainak alkalmazása…"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Ismeretlen"</string>
-    <string name="abandoned_clean_this" msgid="7610119707847920412">"Eltávolítás"</string>
+    <string name="abandoned_clean_this" msgid="7610119707847920412">"Törlés"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Keresés"</string>
     <string name="abandoned_promises_title" msgid="7096178467971716750">"Az alkalmazás nincs telepítve"</string>
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Az ikonhoz tartozó alkalmazás nincs telepítve. Törölheti az ikont, vagy az alkalmazás megkeresése után manuálisan telepítheti azt."</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Az értesítések és az alkalmazások ki vannak kapcsolva"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Bezárás"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Bezárva"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Sikertelen: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 18a644c..b0082c0 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Հավելվածների բեռնում…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"«<xliff:g id="QUERY">%1$s</xliff:g>» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Որոնել այլ հավելվածներ"</string>
+    <string name="label_application" msgid="8531721983832654978">"Հավելված"</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>
@@ -48,7 +49,7 @@
     <string name="all_apps_button_personal_label" msgid="1315764287305224468">"Անձնական հավելվածների ցանկ"</string>
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"Աշխատանքային հավելվածների ցանկ"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"Հիմնական"</string>
-    <string name="remove_drop_target_label" msgid="7812859488053230776">"Հեռացնել"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Ապատեղադրել"</string>
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Հեռացնել"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"Հավելվածի տվյալներ"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"Տեղադրել"</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Սա համակարգային ծրագիր է և չի կարող ապատեղադրվել:"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Անանուն պանակ"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածն անջատված է"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ունի <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ծանուցում</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ունի <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ծանուցում</item>
     </plurals>
@@ -83,25 +84,17 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Անջատվել է ձեր ադմինիստրատորի կողմից"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Թույլ տալ հիմնական էկրանի պտտումը"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Հեռախոսը պտտելու դեպքում"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Ծանուցումների կետիկներ"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Միացված է"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Անջատված է"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Ծանուցումների կետիկներ"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Միացված է"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Անջատած է"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Անհրաժեշտ է ծանուցման թույլտվություն"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Ծանուցումների կետիկները ցուցադրելու համար միացրեք ծանուցումները <xliff:g id="NAME">%1$s</xliff:g>-ի համար"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Փոխել կարգավորումները"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Ցուցադրել ծանուցումների կետիկները"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Ցուցադրել ծանուցումների կետիկները"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ավելացնել պատկերակը Հիմնական էկրանին"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Նոր հավելվածների համար"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Փոխել պատկերակների տեսքը"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"հիմնական էկրանին"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Օգտագործել համակարգի կանխադրված կարգավորումը"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Քառակուսի"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Քառանկյուն"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Օղակ"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Արցունքաձև"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Պատկերակների տեսքի փոփոխությունները կիրառվում են"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Անհայտ է"</string>
-    <string name="abandoned_clean_this" msgid="7610119707847920412">"Հեռացնել"</string>
+    <string name="abandoned_clean_this" msgid="7610119707847920412">"Ապատեղադրել"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Գտնել"</string>
     <string name="abandoned_promises_title" msgid="7096178467971716750">"Այս ծրագիրը տեղադրված չէ:"</string>
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Այս պատկերակի ծրագիրը տեղադրված չէ: Դուք կարող եք հեռացնել այն կամ գտնել ծրագիրը և տեղադրել այն ձեռքով:"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Ծանուցումներն ու հավելվածներն անջատված են"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Փակել"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Փակվեց"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Չհաջողվեց կատարել գործողությունը (<xliff:g id="WHAT">%1$s</xliff:g>)"</string>
 </resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index a4c6a54..448473e 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Memuat aplikasi…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Tidak ditemukan aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Telusuri aplikasi lainnya"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikasi"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifikasi"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tap lama untuk memilih pintasan."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Tap dua kali &amp; tahan untuk memilih pintasan atau menggunakan tindakan khusus."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini adalah aplikasi sistem dan tidak dapat dicopot pemasangannya."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Folder Tanpa Nama"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> dinonaktifkan"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, memiliki <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifikasi</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, memiliki <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notifikasi</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dinonaktifkan oleh admin"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Izinkan layar Utama diputar"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Saat ponsel diputar"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Titik notifikasi"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktif"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Nonaktif"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Titik notifikasi"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktif"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Nonaktif"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Perlu akses notifikasi"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Guna menampilkan Titik Notifikasi, aktifkan notifikasi aplikasi untuk <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Ubah setelan"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Tampilkan titik notifikasi"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Tampilkan titik notifikasi"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Tambahkan ikon ke Layar utama"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Untuk aplikasi baru"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Ubah bentuk ikon"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"di layar Utama"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Gunakan default sistem"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Persegi"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Persegi bundar"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Lingkaran"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Butiran Air"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Menerapkan perubahan bentuk ikon"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Tidak dikenal"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Buang"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Telusuri"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 0040463..174beaa 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Hleður forrit…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ekki fundust forrit sem samsvara „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Leita að fleiri forritum"</string>
+    <string name="label_application" msgid="8531721983832654978">"Forrit"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Tilkynningar"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Haltu fingri á flýtileið til að grípa hana."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Ýttu tvisvar og haltu fingri á flýtileið til að grípa hana eða notaðu sérsniðnar aðgerðir."</string>
@@ -48,7 +49,7 @@
     <string name="all_apps_button_personal_label" msgid="1315764287305224468">"Listi yfir eigin forrit"</string>
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"Listi yfir vinnuforrit"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"Heim"</string>
-    <string name="remove_drop_target_label" msgid="7812859488053230776">"Fjarlægja"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Taka niður"</string>
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Fjarlægja"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"Forritsupplýsingar"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"Setja upp"</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Þetta er kerfisforrit sem ekki er hægt að fjarlægja."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Ónefnd mappa"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Óvirkt <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, er með <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> tilkynningu</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, er með <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> tilkynningar</item>
     </plurals>
@@ -83,25 +84,17 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gert óvirkt af kerfisstjóra"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Leyfa snúning fyrir heimaskjá"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Þegar símanum er snúið"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Tilkynningapunktar"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Kveikt"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Slökkt"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Tilkynningapunktar"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Kveikt"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Slökkt"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Aðgangs að tilkynningum er krafist"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Til að sýna tilkynningarpunkta skaltu kveikja á forritstilkynningum fyrir <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Breyta stillingum"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Sýna tilkynningapunkta"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Sýna tilkynningapunkta"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Bæta tákni á heimaskjáinn"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Fyrir ný forrit"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Breyta formi tákns"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"á heimaskjá"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Nota sjálfgildi kerfis"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Ferningur"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Ferhringur"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Hringur"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Dropi"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Breytir formi tákns"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Óþekkt"</string>
-    <string name="abandoned_clean_this" msgid="7610119707847920412">"Fjarlægja"</string>
+    <string name="abandoned_clean_this" msgid="7610119707847920412">"Taka niður"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Leita"</string>
     <string name="abandoned_promises_title" msgid="7096178467971716750">"Þetta forrit er ekki uppsett"</string>
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Forritið fyrir þetta tákn er ekki uppsett. Þú getur fjarlægt það eða leitað að forritinu og sett það upp handvirkt."</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Slökkt er á tilkynningum og forritum"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Loka"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Lokað"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Mistókst: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 1c53c75..52c851f 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Caricamento delle app…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca altre app"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifiche"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tocca e tieni premuto per scegliere la scorciatoia"</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Tocca due volte e tieni premuto per scegliere una scorciatoia o per usare azioni personalizzate."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Questa è un\'app di sistema e non può essere disinstallata."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Cartella senza nome"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"App <xliff:g id="APP_NAME">%1$s</xliff:g> disattivata"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ha <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifiche</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> ha <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notifica</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ha <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifiche</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ha <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notifica</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Pagina %1$d di %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Schermata Home %1$d di %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disattivata dall\'amministratore"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Consenti rotazione della schermata Home"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Con il telefono ruotato"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Indicatori notifica"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Attiva"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Non attiva"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Indicatori di notifica"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"On"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Off"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Accesso alle notifiche necessario"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Per mostrare gli indicatori di notifica, attiva le notifiche per l\'app <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Modifica impostazioni"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Mostra indicatori di notifica"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostra indicatori di notifica"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Aggiungi icone alla schermata Home"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Per le nuove app"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Cambia la forma delle icone"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"nella schermata Home"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Usa impostazione predefinita di sistema"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Quadrato"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Supercerchio"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Cerchio"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Goccia"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Applicazione delle modifiche alla forma delle icone"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Sconosciuto"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Rimuovi"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Cerca"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index a62cd90..4c9a1cd 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"טוען אפליקציות…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"לא נמצאו אפליקציות התואמות ל-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"חפש אפליקציות נוספות"</string>
+    <string name="label_application" msgid="8531721983832654978">"אפליקציה"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"זוהי אפליקציית מערכת ולא ניתן להסיר את התקנתה."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"תיקיה ללא שם"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> מושבתת"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="two">לאפליקציה <xliff:g id="APP_NAME_2">%1$s</xliff:g> יש <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> התראות</item>
       <item quantity="many">לאפליקציה <xliff:g id="APP_NAME_2">%1$s</xliff:g> יש <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> התראות</item>
       <item quantity="other">לאפליקציה <xliff:g id="APP_NAME_2">%1$s</xliff:g> יש <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> התראות</item>
@@ -85,23 +86,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"הושבת על ידי מנהל המערכת שלך"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"אפשרות סיבוב של מסך דף הבית"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"כאשר הטלפון מסובב"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"סימני ההתראות"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"מופעלת"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"כבויה"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"סימני ההתראות"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"מופעל"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"כבוי"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"נדרשת גישה להתראות"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"כדי להציג את סימני ההתראות,יש להפעיל התראות מהאפליקציה <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"שנה את ההגדרות"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"הצגה של סימן ההתראות"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"הצגת סימני ההתראות"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"הוספת סמל במסך דף הבית"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"לאפליקציות חדשות"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"שינוי הצורה של הסמלים"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"במסך דף הבית"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"השתמש בברירת המחדל של המערכת"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"ריבוע"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"ריבוע בעל פינות מעוגלות"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"מעגל"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"טיפה"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"משנה את הצורה של הסמלים"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"לא ידוע"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"הסר"</string>
     <string name="abandoned_search" msgid="891119232568284442">"חיפוש"</string>
@@ -135,7 +128,7 @@
     <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_with_notifications_description" msgid="2676582286544232849">"קיצורי דרך והודעות"</string>
+    <string name="shortcuts_menu_with_notifications_description" msgid="2676582286544232849">"קיצורי דרך והתראות"</string>
     <string name="action_dismiss_notification" msgid="5909461085055959187">"סגור"</string>
     <string name="notification_dismissed" msgid="6002233469409822874">"ההתראה נסגרה"</string>
     <string name="all_apps_personal_tab" msgid="4190252696685155002">"אישיות"</string>
@@ -144,9 +137,8 @@
     <string name="bottom_work_tab_user_education_title" msgid="5785851780786322825">"ניתן למצוא כאן את אפליקציות העבודה"</string>
     <string name="bottom_work_tab_user_education_body" msgid="2818107472360579152">"לכל אפליקציית עבודה יש תג ואבטחתה מטופלת בידי הארגון. אפשר להעביר אפליקציות אל מסך דף הבית כדי להקל את הגישה אליהן."</string>
     <string name="work_mode_on_label" msgid="4781128097185272916">"מנוהל בידי הארגון"</string>
-    <string name="work_mode_off_label" msgid="3194894777601421047">"הודעות ואפליקציות כבויות"</string>
+    <string name="work_mode_off_label" msgid="3194894777601421047">"התראות ואפליקציות כבויות"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"סגירה"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"סגור"</string>
-    <!-- no translation found for remote_action_failed (1383965239183576790) -->
-    <skip />
+    <string name="remote_action_failed" msgid="1383965239183576790">"הפעולה נכשלה: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 3de53f6..08abb4b 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"アプリを読み込んでいます…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"「<xliff:g id="QUERY">%1$s</xliff:g>」に一致するアプリは見つかりませんでした"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"他のアプリを検索"</string>
+    <string name="label_application" msgid="8531721983832654978">"アプリ"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"このシステムアプリはアンインストールできません。"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"名前のないフォルダ"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」は無効です"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>: <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> 件の通知</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>: <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> 件の通知</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> の通知が <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> 件あります</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> の通知が <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> 件あります</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%1$d/%2$dページ"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"ホーム画面: %1$d/%2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"管理者により無効にされています"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ホーム画面の回転を許可"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"スマートフォンが回転したとき"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"通知ドット"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ON"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"OFF"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"通知ドット"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ON"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"OFF"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"通知へのアクセス権限が必要"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"通知ドットを表示するには、「<xliff:g id="NAME">%1$s</xliff:g>」のアプリ通知を ON にしてください"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"設定を変更"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"通知ドットの表示"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"通知ドットの表示"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ホーム画面にアイコンを追加"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"新しいアプリをダウンロードしたとき"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"アイコンの形の変更"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"ホーム画面上"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"システムのデフォルトを使用"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"スクエア"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"スクワークル"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"サークル"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"ティアドロップ"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"アイコンの形の変更を適用しています"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"削除"</string>
     <string name="abandoned_search" msgid="891119232568284442">"検索"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"通知とアプリは OFF です"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"閉じる"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"終了"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"失敗: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 8b4503e..846060c 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"აპები იტვირთება…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"„<xliff:g id="QUERY">%1$s</xliff:g>“-ის თანხვედრი აპები არ მოიძებნა"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"მეტი აპის პოვნა"</string>
+    <string name="label_application" msgid="8531721983832654978">"აპი"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ეს სისტემური აპია და მისი წაშლა შეუძლებელია."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"უსახელო საქაღალდე"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> გაითიშა"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>-ში <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> შეტყობინებაა</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>-ში <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> შეტყობინებაა</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>-ში არის <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> შეტყობინება</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>-ში არის <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> შეტყობინება</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"გვერდი %1$d %2$d-დან"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"მთავარი ეკრანი %1$d, %2$d-დან"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"გათიშულია თქვენი ადმინისტრატორის მიერ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"მთავარი ეკრანის შეტრიალების დაშვება"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ტელეფონის შეტრიალებისას"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"შეტყობინების ნიშნულები"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ჩართული"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"გამორთული"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"შეტყობინების ნიშნულები"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ჩართულია"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"გამორთულია"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"საჭიროა შეტყობინებებზე წვდომა"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"შეტყობინებათა ნიშნულების საჩვენებლად, ჩართეთ აპის შეტყობინებები <xliff:g id="NAME">%1$s</xliff:g>-ისთვის"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"პარამეტრების შეცვლა"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"შეტყობინების ნიშნულების ჩვენება"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"შეტყობინების ნიშნულების ჩვენება"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ხატულას მთავარ ეკრანზე დამატება"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ახალი აპებისთვის"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"ხატულას ფორმის შეცვლა"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"მთავარ ეკრანზე"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"ნაგულისხმევი სისტემური პარამეტრების გამოყენება"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"კვადრატი"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"წრეკუთხედი"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"წრე"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"წვეთი"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"მიმდინარეობს ხატულას ფორმის ცვლილებების მიყენება"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"უცნობი"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"ამოშლა"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ძიება"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 0d4d3be..c6a2ce4 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Қолданбалар жүктелуде…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сұрауына сәйкес келетін қолданбалар жоқ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Қосымша қолданбалар іздеу"</string>
+    <string name="label_application" msgid="8531721983832654978">"Қолданба"</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>
@@ -48,7 +49,7 @@
     <string name="all_apps_button_personal_label" msgid="1315764287305224468">"Жеке қолданбалар тізімі"</string>
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"Жұмыс қолданбаларының тізімі"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"Негізгі"</string>
-    <string name="remove_drop_target_label" msgid="7812859488053230776">"Жою"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Алып тастау"</string>
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Жою"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"Қолданба ақпараты"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"Орнату"</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Бұл жүйе қолданбасы, сондықтан оны алу мүмкін емес."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Атауы жоқ қалта"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> өшірілді"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> қолданбасында <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> хабарландыру бар</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> қолданбасында <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> хабарландыру бар</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Әкімші өшірді"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Негізгі экранның бұрылуына рұқсат ету"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон бұрылғанда"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Хабарландыру белгілері"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Қосулы"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Өшірулі"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Хабарландыру белгілері"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Қосулы"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Өшірулі"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Хабарландыруға кіру рұқсаты қажет"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Хабарландыру белгілерін көрсету үшін <xliff:g id="NAME">%1$s</xliff:g> қолданбасының қолданба хабарландыруларын қосыңыз"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Параметрлерді өзгерту"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Хабарландыру белгілерін көрсету"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Хабарландыру белгілерін көрсету"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Негізгі экранға белгіше енгізу"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңа қолданбаларға арналған"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Белгіше пішінін өзгерту"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"Негізгі экранда"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Жүйенің әдепкі параметрін пайдалану"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Шаршы"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Жұмыр төртбұрыш"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Шеңбер"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Тамшы"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Белгіше пішіні өзгерістері күшіне енуде"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Белгісіз"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Алып тастау"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Іздеу"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Хабарландырулар мен қолданбалар өшірулі"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Жабу"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Жабық"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Қате шықты: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index a4f33aa..4f3e82c 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"កំពុងផ្ទុកកម្មវិធី…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"រកមិនឃើញកម្មវិធី​ដែលត្រូវគ្នាជាមួយ \"<xliff:g id="QUERY">%1$s</xliff:g>\" ទេ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ស្វែងរកកម្មវិធីច្រើនទៀត"</string>
+    <string name="label_application" msgid="8531721983832654978">"កម្មវិធី"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"នេះ​​​ជា​កម្មវិធី​ប្រព័ន្ធ មិន​អាច​លុប​បាន​ទេ។"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"ថត​គ្មាន​ឈ្មោះ"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"បានបិទដំណើរការ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> មាន​ការ​ជូន​ដំណឹង <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> មាន​ការ​ជូន​ដំណឹង <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g></item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, មាន​ការជូនដំណឹង <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, មាន​ការជូនដំណឺង <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g></item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"ទំព័រ %1$d នៃ %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"អេក្រង់​ដើម %1$d នៃ %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"នៅពេលដែលបង្វិលទូរស័ព្ទរបស់អ្នក"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"ស្លាកជូនដំណឹង"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"បើក"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"បិទ"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"ស្លាកជូនដំណឹង"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"បើក"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"បិទ"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"តម្រូវ​ឲ្យមាន​សិទ្ធិចូល​ប្រើប្រាស់​ការជូនដំណឹង"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"ដើម្បីបង្ហាញស្លាកជូនដំណឹង សូមបើកការជូនដំណឹងកម្មវិធីសម្រាប់ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ប្ដូរ​ការកំណត់"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"បង្ហាញ​ស្លាក​ជូនដំណឹង"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"បង្ហាញ​ស្លាក​ជូនដំណឹង"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"បញ្ចូល​រូបតំណាង​ទៅ​អេក្រង់​ដើម"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"សម្រាប់កម្មវិធីថ្មី"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"ប្តូររូបរាងរូបតំណាង"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"នៅ​លើ​អេក្រង់​ដើម"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"ប្រើលំនាំដើមរបស់ប្រព័ន្ធ"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"ការ៉េ"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"ការ៉េជ្រុងកោង"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"រង្វង់"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"តំណក់​ទឹកភ្នែក"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"កំពុងអនុវត្ត​ការប្តូររូបរាងរូបតំណាង"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"មិន​ស្គាល់"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"លុបចេញ"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ស្វែងរក"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"ការជូនដំណឹង​ និងកម្មវិធី​ត្រូវបានបិទ"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"បិទ"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"បានបិទ"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"បានបរាជ័យ៖ <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 91b08dc9..3479eb5 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
+    <string name="label_application" msgid="8531721983832654978">"ಆ್ಯಪ್"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ಇದೊಂದು ಅಪ್ಲಿಕೇಶನ್ ಆಗಿದೆ ಮತ್ತು ಅಸ್ಥಾಪಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"ಹೆಸರಿಲ್ಲದ ಫೋಲ್ಡರ್"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ಅಧಿಸೂಚನೆಗಳನ್ನು ಹೊಂದಿದೆ</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ಫೋನ್‌ ತಿರುಗಿಸಿದಾಗ"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"ಅಧಿಸೂಚನೆ ಡಾಟ್‌ಗಳು"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ಆನ್"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ಆಫ್"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"ಅಧಿಸೂಚನೆ ಡಾಟ್‌ಗಳು"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ಆನ್ ಆಗಿದೆ"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ಆಫ್ ಆಗಿದೆ"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"ಅಧಿಸೂಚನೆ ಪ್ರವೇಶ ಅಗತ್ಯವಿದೆ"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"ಅಧಿಸೂಚನೆ ಚುಕ್ಕೆಗಳನ್ನು ತೋರಿಸಲು, <xliff:g id="NAME">%1$s</xliff:g> ಗೆ ಅಪ್ಲಿಕೇಶನ್‌ ಅಧಿಸೂಚನೆಗಳನ್ನು ಆನ್‌ ಮಾಡಿ"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ಸೆಟ್ಟಿಂಗ್‌‌ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"ಅಧಿಸೂಚನೆ ಡಾಟ್‌ಗಳನ್ನು ತೋರಿಸಿ"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"ಅಧಿಸೂಚನೆ ಡಾಟ್‌ಗಳನ್ನು ತೋರಿಸಿ"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ಮುಖಪುಟದ ಪರದೆಗೆ ಐಕಾನ್ ಸೇರಿಸಿ"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"ಐಕಾನ್ ಆಕಾರವನ್ನು ಬದಲಿಸಿ"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"ಮುಖಪುಟ ಪರದೆಯಲ್ಲಿ"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"ಸಿಸ್ಟಂ ಡಿಫಾಲ್ಟ್ ಬಳಸಿ"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"ಚೌಕ"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"ಚೌಕವೃತ್ತ"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"ವೃತ್ತ"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"ಕಂಬನಿ"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"ಐಕಾನ್ ಆಕಾರ ಬದಲಾವಣೆಯನ್ನು ಅನ್ವಯಿಸಲಾಗುತ್ತಿದೆ"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"ಅಪರಿಚಿತ"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"ತೆಗೆದುಹಾಕಿ"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ಹುಡುಕಿ"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 6711e02..b4ac8e6 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"앱 로드 중…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\'<xliff:g id="QUERY">%1$s</xliff:g>\'과(와) 일치하는 앱이 없습니다."</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"더 많은 앱 검색"</string>
+    <string name="label_application" msgid="8531721983832654978">"앱"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"시스템 앱은 제거할 수 없습니다."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"이름이 없는 폴더"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> 사용 안함"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>개의 <xliff:g id="APP_NAME_2">%1$s</xliff:g> 알림 있음</item>
-      <item quantity="one"><xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g>개의 <xliff:g id="APP_NAME_0">%1$s</xliff:g> 알림 있음</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>에 <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>개의 알림이 있음</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>에 <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g>개의 알림이 있음</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"페이지 %1$d/%2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"홈 화면 %1$d/%2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"관리자가 사용 중지함"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"홈 화면 회전 허용"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"휴대전화 회전 시"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"알림 표시 점"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"사용"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"사용 안함"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"알림 표시 점"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"사용"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"사용 안함"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"알림 액세스 권한 필요"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"알림 표시점을 표시하려면 <xliff:g id="NAME">%1$s</xliff:g>의 앱 알림을 사용 설정하세요."</string>
     <string name="title_change_settings" msgid="1376365968844349552">"설정 변경"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"알림 표시 점 보기"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"알림 표시 점 보기"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"홈 화면에 아이콘 추가"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"새로 설치한 앱에 적용"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"아이콘 모양 변경"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"홈 화면에 표시"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"시스템 기본값 사용"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"정사각형"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"모서리가 둥근 정사각형"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"원"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"눈물방울"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"아이콘 모양 변경사항을 적용하는 중입니다."</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"알 수 없음"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"삭제"</string>
     <string name="abandoned_search" msgid="891119232568284442">"검색"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"알림 및 앱 사용 중지됨"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"닫기"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"종료됨"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"실패: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 753691d..544d7fe 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Колдонмолор жүктөлүүдө…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сурамына дал келген колдонмолор табылган жок"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Көбүрөөк колдонмолорду издөө"</string>
+    <string name="label_application" msgid="8531721983832654978">"Колдонмо"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Бул системдик колдонмо жана аны чечкенге болбойт."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Аты жок фолдер"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> өчүрүлгөн"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> эскертме бар</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> эскертме бар</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> билдирмеси бар</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> билдирмеси бар</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%2$d ичинен %1$d барак"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Үй экраны %2$d ичинен %1$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Башкы экранды айлантууга уруксат берүү"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон айланганда"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Билдирмелер белгилери"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Күйүк"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Өчүк"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Билдирмелер белгилери"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Күйүк"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Өчүк"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Эскертмелерге уруксат берилиши керек"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Эскертме белгилерин көрсөтүү максатында, <xliff:g id="NAME">%1$s</xliff:g> үчүн колдонмонун эскертмелерин күйгүзүү керек"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Жөндөөлөрдү өзгөртүү"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Эскертме белгилерин көрсөтүү"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Билдирмелер белгилерин көрсөтүү"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Башкы экранга сүрөтчө кошуу"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңы колдонмолор үчүн"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Сүрөтчөнүн формасын өзгөртүү"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"Башкы экранда"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Демейки тутум жөндөөлөрү колдонулат"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Чарчы"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Бурчтары жумуру төрт бурчтук"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Тегерек"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Тамчы"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Өзгөртүлгөн сүрөтчөнүн формасы колдонулууда"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Белгисиз"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Алып салуу"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Издөө"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Билдирүүлөр жана колдонмолор өчүрүлгөн"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Жабуу"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Жабык"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Аткарылган жок: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-land/dimens.xml b/res/values-land/dimens.xml
index f002195..b2f3575 100644
--- a/res/values-land/dimens.xml
+++ b/res/values-land/dimens.xml
@@ -31,7 +31,5 @@
     <dimen name="dynamic_grid_cell_layout_bottom_padding">5.5dp</dimen>
 
     <!-- Hotseat -->
-    <!-- Will be set to equal the hotseat icon size. -->
-    <dimen name="dynamic_grid_hotseat_size">0dp</dimen>
     <dimen name="dynamic_grid_hotseat_side_padding">16dp</dimen>
 </resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 0bdc4bb..be59112 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ກໍາລັງໂຫຼດແອັບ…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"ບໍ່ພົບແອັບທີ່ກົງກັບ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ຊອກຫາແອັບເພີ່ມເຕີມ"</string>
+    <string name="label_application" msgid="8531721983832654978">"ແອັບ"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ນີ້ແມ່ນແອັບຯຂອງລະບົບ ແລະບໍ່ສາມາດຖອນການຕິດຕັ້ງອອກໄດ້."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"ໂຟນເດີຍັງບໍ່ຖືກຕັ້ງຊື່"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"ປິດການນຳໃຊ້ <xliff:g id="APP_NAME">%1$s</xliff:g> ແລ້ວ"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ມີ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ການແຈ້ງເຕືອນ</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ມີ <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ການແຈ້ງເຕືອນ</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍທຳອິດໄດ້"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ເມື່ອໝຸນໂທລະສັບ"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"ຈຸດການແຈ້ງເຕືອນ"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ເປີດ"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ປິດ"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"ຈຸດການແຈ້ງເຕືອນ"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ເປີດ"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ປິດ"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"ຕ້ອງໃຊ້ການເຂົ້າເຖິງການແຈ້ງເຕືອນ"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"ເພື່ອສະແດງຈຸດການແຈ້ງເຕືອນ, ໃຫ້ເປີດການແຈ້ງເຕືອນສຳລັບ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ບັນທຶກການຕັ້ງຄ່າ"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"ສະແດງຈຸດການແຈ້ງເຕືອນ"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"ສະແດງຈຸດການແຈ້ງເຕືອນ"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ເພີ່ມໄອຄອນໃສ່ໜ້າຈໍຫຼັກ"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ສຳລັບແອັບໃໝ່"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"ປ່ຽນຮູບຮ່າງໄອຄອນ"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"ຢູ່ໜ້າຈໍຫຼັກ"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"ໃຊ້ຄ່າເລີ່ມຕົ້ນລະບົບ"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"ສີ່ຫຼ່ຽມຈັດຕຸລັດ"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"ສີ່ຫຼ່ຽມຂອບມົນ"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"ວົງມົນ"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"ນ້ຳຢອດ"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"ນຳໃຊ້ການປ່ຽນແປງຮູບຮ່າງໄອຄອນ"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"​ບໍ່​ຮູ້​ຈັກ"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ​"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ຊອກຫາ"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"ການແຈ້ງເຕືອນ ແລະ ແອັບຖືກປິດໄວ້"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ປິດ"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ປິດແລ້ວ"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"ບໍ່ສຳເລັດ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index cf0beef..2556a96 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Įkeliamos programos…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nerasta jokių užklausą „<xliff:g id="QUERY">%1$s</xliff:g>“ atitinkančių programų"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Ieškoti daugiau programų"</string>
+    <string name="label_application" msgid="8531721983832654978">"Programa"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Pranešimai"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Paliesk. ir palaikyk., kad pasirinkt. spart. klav."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dukart palieskite ir palaikykite, kad pasirinkt. spartųjį klavišą ar naudotumėte tinkintus veiksmus."</string>
@@ -64,11 +65,11 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Tai sistemos programa ir jos negalima pašalinti."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Aplankas be pavadinimo"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ išjungta"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one">„<xliff:g id="APP_NAME_2">%1$s</xliff:g>“, yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimas</item>
-      <item quantity="few">„<xliff:g id="APP_NAME_2">%1$s</xliff:g>“, yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimai</item>
-      <item quantity="many">„<xliff:g id="APP_NAME_2">%1$s</xliff:g>“, yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimo</item>
-      <item quantity="other">„<xliff:g id="APP_NAME_2">%1$s</xliff:g>“, yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimų</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one">Programoje „<xliff:g id="APP_NAME_2">%1$s</xliff:g>“ yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimas</item>
+      <item quantity="few">Programoje „<xliff:g id="APP_NAME_2">%1$s</xliff:g>“ yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimai</item>
+      <item quantity="many">Programoje „<xliff:g id="APP_NAME_2">%1$s</xliff:g>“ yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimo</item>
+      <item quantity="other">Programoje „<xliff:g id="APP_NAME_2">%1$s</xliff:g>“ yra <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pranešimų</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%1$d psl. iš %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d pagrindinis ekranas iš %2$d"</string>
@@ -85,25 +86,17 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Išjungė administratorius"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Leisti pasukti pagrindinį ekraną"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Kai telefonas pasukamas"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Pranešimų taškai"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Įjungta"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Išjungta"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Pranešimų taškai"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Įjungta"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Išjungta"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Reikalinga prieiga prie pranešimų"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Kad būtų rodomi pranešimų taškai, įjunkite programos „<xliff:g id="NAME">%1$s</xliff:g>“ pranešimus."</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Keisti nustatymus"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Rodyti pranešimų taškus"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Rodyti pranešimų taškus"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pridėti piktogr. prie pagrindinio ekrano"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Skirta naujoms programoms"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Pakeisti piktogramos formą"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"pagrindiniame ekrane"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Naudoti numatytuosius sistemos nustatymus"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadratas"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Kvadratais suapvalintais kampais"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Apskritimas"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Ašara"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Taikomi piktogramos formos pakeitimai"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Nežinoma"</string>
-    <string name="abandoned_clean_this" msgid="7610119707847920412">"Pašalinti"</string>
+    <string name="abandoned_clean_this" msgid="7610119707847920412">"Panaikinti"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Ieškoti"</string>
     <string name="abandoned_promises_title" msgid="7096178467971716750">"Ši programa neįdiegta"</string>
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Šios piktogramos programa neįdiegta. Galite ją pašalinti arba bandyti ieškoti programos ir ją įdiegti patys."</string>
@@ -147,4 +140,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Programos ir pranešimai išjungti"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Uždaryti"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Uždaryta"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Nepavyko: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index d53de8f..c33490d 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Notiek lietotņu ielāde…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Vaicājumam “<xliff:g id="QUERY">%1$s</xliff:g>” neatbilda neviena lietotne"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Meklēt citas lietotnes"</string>
+    <string name="label_application" msgid="8531721983832654978">"Lietotne"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Paziņojumi"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Lai atlasītu saīsni, pieskarieties un turiet to."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Lai atlasītu saīsni, veiciet dubultskārienu uz tās un turiet to. Varat arī veikt pielāgotas darbības."</string>
@@ -64,10 +65,10 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Šī ir sistēmas lietotne, un to nevar atinstalēt."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Mape bez nosaukuma"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Lietotne <xliff:g id="APP_NAME">%1$s</xliff:g> ir atspējota"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="zero"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ir <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> paziņojumi</item>
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ir <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> paziņojums</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ir <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> paziņojumi</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="zero">Lietotnē <xliff:g id="APP_NAME_2">%1$s</xliff:g> ir <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> paziņojumi</item>
+      <item quantity="one">Lietotnē <xliff:g id="APP_NAME_2">%1$s</xliff:g> ir <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> paziņojums</item>
+      <item quantity="other">Lietotnē <xliff:g id="APP_NAME_2">%1$s</xliff:g> ir <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> paziņojumi</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%1$d. lapa no %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Sākuma ekrāns: %1$d no %2$d"</string>
@@ -84,23 +85,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Atspējojis administrators"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Atļaut sākuma ekrāna pagriešanu"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Pagriežot tālruni"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Paziņojumu punkti"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Ieslēgts"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Izslēgts"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Paziņojumu punkti"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Ieslēgts"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Izslēgts"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Nepieciešama piekļuve paziņojumiem"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Lai tiktu rādīti paziņojumu punkti, ieslēdziet paziņojumus lietotnei <xliff:g id="NAME">%1$s</xliff:g>."</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Mainīt iestatījumus"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Rādīt paziņojumu punktus"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Rādīt paziņojumu punktus"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pievienot ikonu sākuma ekrānā"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Jaunām lietotnēm"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Mainīt ikonu formu"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"sākuma ekrānā"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Izmantot sistēmas noklusējumu"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrāts"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Kvadrāts ar noapaļotiem stūriem"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Aplis"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lāse"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Tiek piemērotas ikonu formas izmaiņas"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Nezināma"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Noņemt"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Meklēt"</string>
@@ -146,4 +139,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Paziņojumi un lietotnes ir izslēgtas"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Aizvērt"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Aizvērta"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Neizdevās: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index af6ece0..563e2fe 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Се вчитуваат апликации…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Не се најдени апликации што одговараат на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Пребарај други апликации"</string>
+    <string name="label_application" msgid="8531721983832654978">"Апликација"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ова е системска апликација и не може да се деинсталира."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Неименувана папка"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> е оневозможена"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> известување</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> известувања</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Оневозможено од администраторот"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Дозволете ротација на Почетниот екран"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Кога телефонот се ротира"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Точки за известување"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Вклучено"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Исклучено"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Точки за известување"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Вклучено"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Исклучено"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Потребен е пристап до известувањата"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"За да се прикажуваат „Точки за известување“, вклучете ги известувањата за апликацијата <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Промени ги поставките"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Прикажи точки за известување"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Прикажувај точки за известување"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додај икона на почетниот екран"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови апликации"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Променете ја формата на иконата"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"на „Почетен екран“"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Користи ја стандардната поставка на системот"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Заоблен квадрат"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Солза"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Се применуваат промените на формата на иконата"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Отстрани"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Барај"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Известувањата и апликациите се исклучени"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Затвори"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Затворено"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Не успеа: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index d9f0312..5390f0d 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ആപ്പുകൾ ലോഡുചെയ്യുന്നു..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"കൂടുതൽ ആപ്പുകൾക്ക് തിരയുക"</string>
+    <string name="label_application" msgid="8531721983832654978">"ആപ്പ്"</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">"കുറുക്കുവഴി തിരഞ്ഞെടുക്കാനോ ഇഷ്‌ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ 2 തവണ ടാപ്പ് ചെയ്‌ത് പിടിക്കുക."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ഇതൊരു സിസ്‌റ്റം അപ്ലിക്കേഷനായതിനാൽ അൺഇൻസ്‌റ്റാളുചെയ്യാനാവില്ല."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"പേരുനൽകാത്ത ഫോൾഡർ"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> പ്രവർത്തനരഹിതമാക്കി"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>-ന്, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> അറിയിപ്പുകൾ ഉണ്ട്</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>-ന്, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> അറിയിപ്പ് ഉണ്ട്</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> എന്ന ആപ്പിന്, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> അറിയിപ്പുകൾ ഉണ്ട്</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> എന്ന ആപ്പിന്, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> അറിയിപ്പുണ്ട്</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"പേജ് %1$d / %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"ഹോം സ്‌ക്രീൻ %1$d / %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ഫോൺ തിരിച്ച നിലയിലായിരിക്കുമ്പോൾ"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"അറിയിപ്പ് ഡോട്ടുകൾ"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ഓൺ"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ഓഫ്"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"അറിയിപ്പ് ഡോട്ടുകൾ"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ഓണാണ്"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ഓഫാണ്"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"അറിയിപ്പിനായുള്ള ആക്‌സസ് ആവശ്യമാണ്"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"അറിയിപ്പ് ഡോട്ടുകൾ കാണിക്കുന്നതിന്, <xliff:g id="NAME">%1$s</xliff:g> എന്നയാളിനായുള്ള ആപ്പ് അറിയിപ്പുകൾ ഓണാക്കുക"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ക്രമീകരണം മാറ്റുക"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"അറിയിപ്പ് ഡോട്ടുകൾ കാണിക്കുക"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"അറിയിപ്പ് ഡോട്ടുകൾ കാണിക്കുക"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ഹോം സ്ക്രീനിലേക്ക് ഐക്കൺ ചേർക്കുക"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"പുതിയ ആപ്പുകൾക്ക്"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"ഐക്കണിന്റെ ആകാരം മാറ്റുക"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"ഹോം സ്‌ക്രീനിൽ"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"സിസ്‌റ്റം ഡിഫോൾട്ട് ഉപയോഗിക്കുക"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"ചതുരം"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"ചതുരവൃത്തം"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"വൃത്തം"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"കണ്ണുനീര്‍ തുള്ളി"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"ഐക്കൺ ആകാര മാറ്റങ്ങൾ പ്രയോഗിക്കുന്നു"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"അജ്ഞാതം"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"നീക്കംചെയ്യുക"</string>
     <string name="abandoned_search" msgid="891119232568284442">"തിരയുക"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"അറിയിപ്പുകളും ആപ്പുകളും ഓഫാണ്"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"അടയ്ക്കുക"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"അടച്ചു"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"പരാജയപ്പെട്ടു: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 39e7021..0b6dcd4 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Аппыг ачааллаж байна..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"-д тохирох апп олдсонгүй"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Бусад апп-г хайх"</string>
+    <string name="label_application" msgid="8531721983832654978">"Апп"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Энэ апп нь системийн апп ба устгах боломжгүй."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Нэргүй фолдер"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г идэвхгүй болгосон"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> мэдэгдэл байна</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> мэдэгдэл байна</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> мэдэгдэлтэй байна</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> мэдэгдэлтэй байна</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%2$d-н %1$d хуудас"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d-н Нүүр дэлгэц %1$d"</string>
@@ -83,25 +84,17 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Таны админ идэвхгүй болгосон"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Нүүр дэлгэцийг эргүүлэхийг зөвшөөрөх"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Утсыг эргүүлсэн үед"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Мэдэгдлийн цэг"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Асаалттай"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Унтраалттай"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Мэдэгдлийн цэг"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Асаалттай"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Унтраалттай"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Мэдэгдлийн хандалт шаардлагатай"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Мэдэгдлийн цэгийг харуулахын тулд <xliff:g id="NAME">%1$s</xliff:g>-д аппын мэдэгдлийг асаана уу"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Тохиргоог өөрчлөх"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Мэдэгдлийн цэгийг харуулах"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Мэдэгдлийн цэгийг харуулах"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Нүүр хуудаст дүрс тэмдэг нэмэх"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Шинэ аппад зориулсан"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Дүрс тэмдгийн хэлбэрийг өөрчлөх"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"Үндсэн нүүр хэсэгт"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Системийн өгөгдмөл тохиргоог ашиглах"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Дөрвөлжин"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Мохоо өнцөгтэй дөрвөлжин"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Дугуй"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Дусал"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Дүрс тэмдгийн хэлбэрийг өөрчилж байна"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Тодорхойгүй"</string>
-    <string name="abandoned_clean_this" msgid="7610119707847920412">"Устгах"</string>
+    <string name="abandoned_clean_this" msgid="7610119707847920412">"Хасах"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Хайх"</string>
     <string name="abandoned_promises_title" msgid="7096178467971716750">"Энэ апп-г суулгаагүй байна"</string>
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Энэ дүрсний апп-г суулгаагүй байна. Та үүнийг устгах буюу апп-г хайж суулгах боломжтой."</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Мэдэгдэл, апп унтраалттай байна"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Хаах"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Хаасан"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Амжилтгүй болсон: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index df863c1..253c4a2 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -22,8 +22,8 @@
     <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"कार्य"</string>
-    <string name="activity_not_found" msgid="8071924732094499514">"अॅप इंस्टॉल केलेला नाही."</string>
-    <string name="activity_not_available" msgid="7456344436509528827">"अॅप उपलब्ध नाही"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"अ‍ॅप इंस्टॉल केलेला नाही."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"अ‍ॅप उपलब्ध नाही"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"डाउनलोड केलेला अ‍ॅप सुरक्षित मोड मध्‍ये अक्षम केला"</string>
     <string name="safemode_widget_error" msgid="4863470563535682004">"विजेट सुरक्षित मोडमध्ये अक्षम झाले"</string>
     <string name="shortcut_not_available" msgid="2536503539825726397">"शॉर्टकट उपलब्ध नाही"</string>
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"अॅप्स लोड करत आहे…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक अॅप्स शोधा"</string>
+    <string name="label_application" msgid="8531721983832654978">"ॲप"</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>
@@ -50,23 +51,23 @@
     <string name="all_apps_home_button_label" msgid="252062713717058851">"होम"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"काढा"</string>
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"अनइंस्टॉल करा"</string>
-    <string name="app_info_drop_target_label" msgid="692894985365717661">"अॅप माहिती"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"अ‍ॅप माहिती"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"इंस्टॉल करा"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट स्‍थापित करा"</string>
-    <string name="permdesc_install_shortcut" msgid="923466509822011139">"वापरकर्ता हस्तक्षेपाशिवाय शॉर्टकट जोडण्यास अॅप ला अनुमती देते."</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"वापरकर्ता हस्तक्षेपाशिवाय शॉर्टकट जोडण्यास अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_read_settings" msgid="1941457408239617576">"होम सेटिंग्ज आणि शॉर्टकट वाचा"</string>
-    <string name="permdesc_read_settings" msgid="5833423719057558387">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट वाचण्यास अॅप ला अनुमती देते."</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट वाचण्यास अ‍ॅप ला अनुमती देते."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"होम सेटिंग्ज आणि शॉर्टकट लिहा"</string>
-    <string name="permdesc_write_settings" msgid="5440712911516509985">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अॅप ला अनुमती देते."</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अ‍ॅप ला अनुमती देते."</string>
     <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ला फोन कॉल करण्याची अनुमती नाही"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"विजेट लोड करण्यात समस्या"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"सेटअप"</string>
-    <string name="uninstall_system_app_text" msgid="4172046090762920660">"हा सिस्टम अॅप आहे आणि अनइंस्टॉल केला जाऊ शकत नाही."</string>
+    <string name="uninstall_system_app_text" msgid="4172046090762920660">"हा सिस्टम अ‍ॅप आहे आणि अनइंस्टॉल केला जाऊ शकत नाही."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"अनामित फोल्डर"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> अक्षम केला आहे"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, कडे <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचना आहे</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, कडे <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचना आहेत</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>साठी<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>सूचना आहेत</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>साठी <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचना आहेत</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%2$d पैकी %1$d पृष्ठ"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$d पैकी %1$d मुख्य स्क्रीन"</string>
@@ -83,28 +84,20 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपल्या प्रशासकाने अक्षम केले"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"मुख्यस्क्रीन फिरविण्‍यास अनुमती द्या"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"फोन फिरविला जातो तेव्हा"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"सूचना बिंदू"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"चालू"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"बंद"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"सूचना बिंदू"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"सुरू"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"बंद"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"सूचनांच्या अ‍ॅक्सेसची आवश्यकता आहे"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"सूचना बिंदू दाखवण्यासाठी, <xliff:g id="NAME">%1$s</xliff:g> साठी अ‍ॅप सूचना चालू करा"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"सेटिंग्ज बदला"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"सूचना बिंदू दाखवा"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"सूचना बिंदू दाखवा"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"होम स्क्रीनवर आयकन जोडा"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नवीन अॅप्ससाठी"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"चिन्हाचा आकार बदला"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"होम स्क्रीनवर"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"सिस्‍टमचे डीफॉल्‍ट वापरा"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"चौरस"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"गोलाकार चौरस"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"वर्तुळ"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"अश्रू"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"चिन्हाचा आकार बदल लागू करत आहे"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"काढा"</string>
     <string name="abandoned_search" msgid="891119232568284442">"शोधा"</string>
-    <string name="abandoned_promises_title" msgid="7096178467971716750">"हा अॅप इंस्टॉल केलेला नाही"</string>
-    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"या चिन्हासाठी अॅप इंस्टॉल केलेला नाही. तुम्ही ते काढू शकता किंवा अॅपचा शोध घेऊ शकता आणि त्यास व्यक्तिचलितपणे इंस्टॉल करू शकता."</string>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"हा अ‍ॅप इंस्टॉल केलेला नाही"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"या चिन्हासाठी अ‍ॅप इंस्टॉल केलेला नाही. तुम्ही ते काढू शकता किंवा अ‍ॅपचा शोध घेऊ शकता आणि त्यास व्यक्तिचलितपणे इंस्टॉल करू शकता."</string>
     <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड होत आहे , <xliff:g id="PROGRESS">%2$s</xliff:g> पूर्ण झाले"</string>
     <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> इंस्टॉल करण्याची प्रतिक्षा करत आहे"</string>
     <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> विजेट"</string>
@@ -145,6 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"सूचना आणि अॅप्स बंद आहेत"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"बंद करा"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"बंद केले"</string>
-    <!-- no translation found for remote_action_failed (1383965239183576790) -->
-    <skip />
+    <string name="remote_action_failed" msgid="1383965239183576790">"हे करता आले नाही: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 98f63c5..358dbc3 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Memuatkan apl…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Tiada apl yang ditemui sepadan dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cari lagi apl"</string>
+    <string name="label_application" msgid="8531721983832654978">"Apl"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Pemberitahuan"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Sentuh &amp; tahan untuk mengambil pintasan."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Ketik dua kali &amp; tahan untuk mengambil pintasan atau menggunakan tindakan tersuai."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ini ialah apl sistem dan tidak boleh dinyahpasang."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Folder Tanpa Nama"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> dilumpuhkan"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, mempunyai <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> pemberitahuan</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, mempunyai <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> pemberitahuan</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dilumpuhkan oleh pentadbir anda"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Benarkan putaran Skrin Utama"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Apabila telefon diputar"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Titik pemberitahuan"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Hidup"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Mati"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Titik pemberitahuan"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Hidup"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Mati"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Akses pemberitahuan diperlukan"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Untuk menunjukkan Titik Pemberitahuan, hidupkan pemberitahuan apl untuk <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Tukar tetapan"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Tunjukkan titik pemberitahuan"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Tunjukkan titik pemberitahuan"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Tambahkan ikon pada Skrin Utama"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Untuk apl baharu"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Tukar bentuk ikon"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"pada Skrin Utama"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Gunakan lalai sistem"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Segi empat sama"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Segi empat berbucu bulat"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Bulatan"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Titisan air mata"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Menggunakan perubahan bentuk ikon"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Tidak diketahui"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Alih keluar"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Carian"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Pemberitahuan dan apl dimatikan"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Tutup"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Ditutup"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Gagal: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 0b07e30..b9884c0 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"အက်ပ်များကို ဖွင့်နေသည်…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" နှင့်ကိုက်ညီသည့် အပ်ပ်များကို မတွေ့ပါ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"နောက်ထပ် အက်ပ်များကို ရှာပါ"</string>
+    <string name="label_application" msgid="8531721983832654978">"အက်ပ်"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ဤအပ်ပလီကေးရှင်းမှာ စစ်စတန်ပိုင်းဆိုင်ရာ အပ်ပလီကေးရှင်းဖြစ်ပါသည်။ ထုတ်ပစ်၍ မရပါ"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"အမည်မရှိအကန့်"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ပိတ်ထားသည်"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> တွင် အကြောင်းကြားချက် <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ခု ရှိသည်</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> တွင် အကြောင်းကြားချက် <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ခု ရှိသည်</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> တွင် သတိပေးချက် <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ခု ရှိသည်</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> တွင် သတိပေးချက် <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ခု ရှိသည်</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"စာမျက်နှာ %1$d မှ %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"ပင်မစာမျက်နှာ %1$d မှ %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုပါ"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ဖုန်းကိုလှည့်ထားစဉ်"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"အကြောင်းကြားချက်အမှတ်အသားများ"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ဖွင့်ထားသည်"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ပိတ်ထားသည်"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"သတိပေးချက် အစက်များ"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ဖွင့်ထားသည်"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ပိတ်ထားသည်"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"အကြောင်းကြားချက် အသုံးပြုခွင့် လိုအပ်သည်"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"အကြောင်းကြားချက် အစက်များကို ပြသရန် <xliff:g id="NAME">%1$s</xliff:g> အတွက် အက်ပ်အကြောင်းကြားချက်များကို ဖွင့်ပါ"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ဆက်တင်များ ပြောင်းရန်"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"အကြောင်းကြားချက် အမှတ်အသားများကို ပြရန်"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"သတိပေးချက် အစက်များ ပြရန်"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ပင်မစာမျက်နှာသို့ သင်္ကေတပုံ ထည့်ရန်"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"အက်ပ်အသစ်များအတွက်"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"သင်္ကေတပုံစံကို ပြောင်းရန်"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"\'ပင်မမျက်နှာပြင်\' ပေါ်တွင်"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"စနစ်၏ မူရင်းပုံကို အသုံးပြုရန်"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"လေးထောင့်"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"စတုရန်းမကျ စက်ဝိုင်းမကျပုံ"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"စက်ဝိုင်း"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"မျက်ရည်စက်ပုံ"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"သင်္ကေတပုံစံကို ပြောင်းလဲနေသည်"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"မသိရ"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"ဖယ်ရှားရန်"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ရှာဖွေရန်"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index cfa77bf..fa404f7 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Laster inn appene …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Fant ingen apper som samsvarer med «<xliff:g id="QUERY">%1$s</xliff:g>»"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søk etter flere apper"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Varsler"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Trykk og hold for å velge en snarvei."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dobbelttrykk og hold for å velge en snarvei eller bruke tilpassede handlinger."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dette er en systemapp som ikke kan avinstalleres."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Mappe uten navn"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Slo av <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> varsler</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> varsel</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratoren har slått av funksjonen"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Tillat rotasjon av startskjermen"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Når telefonen roteres"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Varselsprikker"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"På"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Av"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Varselsprikker"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"På"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Av"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Tilgang til varsler er nødvendig"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Slå på appvarsler for <xliff:g id="NAME">%1$s</xliff:g> for å vise varselsprikker"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Endre innstillingene"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Vis varselsprikker"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Vis varselsprikker"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Legg til ikon på startsiden"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"For nye apper"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Endre formen på ikonet"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"på startskjermen"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Bruk systemstandard"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Superellipse"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Sirkel"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Dråpe"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Aktiverer endringer av formen på ikonet"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Ukjent"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Fjern"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Søk"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Varsler og apper er slått av"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Lukk"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Lukket"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Mislyktes: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index a5d3a4e..a99c4ad 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"अनुप्रयोगहरू लोड गर्दै…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै अनुप्रयोग भेटिएन"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"थप अनुप्रयोगहरू खोज्नुहोस्"</string>
+    <string name="label_application" msgid="8531721983832654978">"अनुप्रयोग"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"यो प्रणाली अनुप्रयोग हो र यसलाई स्थापना रद्द गर्न सकिँदैन।"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"बेनाम फोल्डर"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"असक्षम पारिएको <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, यसमा <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचनाहरू छन्‌</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, यसमा <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> सूचना छ</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, का <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> सूचनाहरू छन्</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, को <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> सूचना छ</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"पृष्ठ %2$d को %1$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"गृह स्क्रिन %1$d को %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"तपाईँको प्रशासकद्वारा असक्षम गरिएको"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"गृह स्क्रिनलाई घुम्ने अनुमति दिनुहोस्"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"फोनलाई घुमाइँदा"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"सूचनाको प्रतीक जनाउने थोप्लोहरू"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"सक्रिय छ"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"निष्क्रिय छ"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"सूचनाको प्रतीक जनाउने थोप्लाहरू"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"सक्रिय"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"निष्क्रिय"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"सूचनासम्बन्धी पहुँच आवश्यक हुन्छ"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउन <xliff:g id="NAME">%1$s</xliff:g> को अनुप्रयोगसम्बन्धी सूचनाहरूलाई सक्रिय गर्नुहोस्"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"सेटिङहरू बदल्नुहोस्"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउनुहोस्"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"सूचनाको प्रतीक जनाउने थोप्लाहरू देखाउनुहोस्"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"गृह स्क्रिनमा आइकन थप्नुहोस्"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नयाँ अनुप्रयोगका लागि"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"आइकनको आकार परिवर्तन गर्नुहोस्"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"गृह स्क्रिनमा"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"प्रणालीको पूर्वनिर्धारित सेटिङ प्रयोग गर्नुहोस्"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"वर्ग"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"वर्गाकार वृत्त"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"वृत्त"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"आँसुको थोपा"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"आइकनको आकारमा गरिएका परिवर्तनहरू लागू गरिँदैछन्"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"हटाउनुहोस्"</string>
     <string name="abandoned_search" msgid="891119232568284442">"खोजी गर्नुहोस्"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"सूचना र अनुप्रयोगहरू निष्क्रिय छन्‌"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"बन्द गर्नुहोस्"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"बन्द गरियो"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"कार्य पूरा गर्न सकिएन: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 1b11161..964f10c 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Apps laden…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Er zijn geen apps gevonden die overeenkomen met \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Zoeken naar meer apps"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Meldingen"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tik en houd vast om snelkoppeling toe te voegen."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dubbeltik en houd vast om een snelkoppeling toe te voegen of aangepaste acties te gebruiken."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Dit is een systeemapp die niet kan worden verwijderd."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Naamloze map"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> is uitgeschakeld"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> heeft <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> meldingen</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> heeft <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> melding</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, heeft <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> meldingen</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, heeft <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> melding</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Pagina %1$d van %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Startscherm %1$d van %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Uitgeschakeld door je beheerder"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Draaien van startscherm toestaan"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Wanneer de telefoon gedraaid is"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Meldingsstipjes"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aan"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Uit"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Meldingsstipjes"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Aan"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Uit"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Toegang tot meldingen vereist"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Als je meldingsstipjes wilt weergeven, schakel je app-meldingen in voor <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Instellingen wijzigen"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Meldingsstipjes weergeven"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Meldingsstipjes weergeven"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pictogram toevoegen aan startscherm"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Voor nieuwe apps"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Vorm van pictogram wijzigen"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"op het startscherm"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Systeemstandaard gebruiken"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Vierkant"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Cirkel"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Traan"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Wijzigingen in vorm van pictogram toepassen"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Verwijderen"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Zoeken"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Meldingen en apps zijn uitgeschakeld"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Sluiten"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Gesloten"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Mislukt: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index f61fd6a..0e1efd3 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ଆପ୍‌ ଲୋଡ୍‌ ହେଉଛି..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ସହିତ ମେଳ ହେଉଥିବା କୌଣସି ଆପ୍‌ ମିଳିଲା ନାହିଁ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ଅଧିକ ଆପ୍‌ ଖୋଜନ୍ତୁ"</string>
+    <string name="label_application" msgid="8531721983832654978">"ଆପ୍"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ଏହା ଏକ ସିଷ୍ଟମ୍‌ ଆପ୍‌ ଅଟେ ଏବଂ ଏହା ଅନଇନଷ୍ଟଲ୍‌ କରାଯାଇ ପାରିବ ନାହିଁ।"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"ବେନାମୀ ଫୋଲ୍ଡର୍‌"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଅକ୍ଷମ କରାଗଲା"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ରେ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ଅଛି</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ରେ <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ବିଜ୍ଞପ୍ତି ଅଛି</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>ଟି ବିଜ୍ଞପ୍ତି ରହିଛି</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g>ଟି ବିଜ୍ଞପ୍ତି ରହିଛି</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"ମୋଟ %2$dରୁ %1$d ନମ୍ବର ପୃଷ୍ଠା"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dରୁ %1$d ହୋମ୍‌ ସ୍କ୍ରୀନ୍"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଅକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ହୋମ୍‌ ସ୍କ୍ରୀନ୍ ବୁଲାଇବା ଅନୁମତି ଦିଅନ୍ତୁ"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ଯେତେବେଳେ ଫୋନକୁ ବୁଲାଯାଇଥାଏ"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"ବିଜ୍ଞପ୍ତି ବିନ୍ଦୁଗୁଡ଼ିକ"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ଅନ୍"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ଅଫ୍‌"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"ବିଜ୍ଞପ୍ତି ବିନ୍ଦୁଗୁଡ଼ିକ"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ଚାଲୁ କରନ୍ତୁ"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"ବିଜ୍ଞପ୍ତି ଆକ୍ସେସ୍‌ ଆବଶ୍ୟକ ଅଟେ"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"ବିଜ୍ଞପ୍ତି ବିନ୍ଦୁ ଦେଖାଇବାକୁ, <xliff:g id="NAME">%1$s</xliff:g> ପାଇଁ ଆପ୍‌ ବିଜ୍ଞପ୍ତି ଅନ୍‌ କରନ୍ତୁ"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ସେଟିଙ୍ଗ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"ବିଜ୍ଞପ୍ତି ଡଟ୍‌ଗୁଡ଼ିକୁ ଦେଖାନ୍ତୁ"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"ବିଜ୍ଞପ୍ତି ଡଟ୍‌ଗୁଡ଼ିକୁ ଦେଖାନ୍ତୁ"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ହୋମ୍‌ ସ୍କ୍ରୀନରେ ଆଇକନ୍‌କୁ ଯୋଡ଼ନ୍ତୁ"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ନୂଆ ଆପ୍‌ ପାଇଁ"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"ଆଇକନ୍‌ର ଆକାର ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"ହୋମ୍ ସ୍କ୍ରୀନ୍ ଉପରେ"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"ସିଷ୍ଟମ ଡିଫଲ୍ଟ ବ୍ୟବହାର କରନ୍ତୁ"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"ବର୍ଗାକାର"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"ବର୍ଗାକାରର ବୃତ୍ତ"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"ବୃତ୍ତ"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"ଟିଅରଡ୍ରପ୍‌"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"ଆଇକନ୍‌ ଆକାର ପରିବର୍ତ୍ତନ ଲାଗୁ କରୁଛି"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"ଅଜଣା"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"ବାହାର କରନ୍ତୁ"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ସର୍ଚ୍ଚ କରନ୍ତୁ"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"ବିଜ୍ଞପ୍ତି ଓ ଆପ୍‌ଗୁଡ଼ିକ ବନ୍ଦ ଅଛି"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ବନ୍ଦ କରନ୍ତୁ"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ବନ୍ଦ ହୋଇଯାଇଛି"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"ବିଫଳ ହୋଇଛି: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 326c813..e00ba10 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ਨਾਲ ਮੇਲ ਖਾਂਦੀਆਂ ਕੋਈ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ਹੋਰ ਐਪਾਂ ਖੋਜੋ"</string>
+    <string name="label_application" msgid="8531721983832654978">"ਐਪ"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ਇਹ ਇੱਕ ਸਿਸਟਮ ਐਪ ਹੈ ਅਤੇ ਇਸਨੂੰ ਅਣਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਦਾ।"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"ਬਿਨਾਂ ਨਾਮ ਦਿੱਤਾ ਫੋਲਡਰ"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ਦੀ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ਸੂਚਨਾ</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ਦੀਆਂ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ਸੂਚਨਾਵਾਂ</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ਦੀ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ਸੂਚਨਾ</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ਦੀਆਂ <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ਸੂਚਨਾਵਾਂ</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"ਸਫ਼ਾ %2$d ਦਾ %1$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"ਹੋਮ ਸਕ੍ਰੀਨ %2$d ਦੀ %1$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ਹੋਮ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁੰਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ਜਦੋਂ ਫ਼ੋਨ ਘੁੰਮਾਇਆ ਜਾਂਦਾ ਹੈ"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"ਸੂਚਨਾ ਬਿੰਦੂ"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ਚਾਲੂ"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ਬੰਦ"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"ਸੂਚਨਾ ਬਿੰਦੂ"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ਚਾਲੂ"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ਬੰਦ"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"ਸੂਚਨਾ ਪਹੁੰਚ ਲੋੜੀਂਦੀ ਹੈ"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"ਸੂਚਨਾ ਬਿੰਦੂਆਂ ਦਿਖਾਉਣ ਲਈ, <xliff:g id="NAME">%1$s</xliff:g> ਲਈ ਐਪ ਸੂਚਨਾਵਾਂ ਚਾਲੂ ਕਰੋ"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ਸੈਟਿੰਗਾਂ ਬਦਲੋ"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"ਸੂਚਨਾ ਬਿੰਦੂ ਦਿਖਾਓ"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"ਸੂਚਨਾ ਬਿੰਦੂ ਦਿਖਾਓ"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਪ੍ਰਤੀਕ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ਨਵੀਆਂ ਐਪਾਂ ਲਈ"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"ਪ੍ਰਤੀਕ ਦੀ ਆਕ੍ਰਿਤੀ ਬਦਲੋ"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"ਸਿਸਟਮ ਦੀ ਪੂਰਵ-ਨਿਰਧਾਰਤ ਸੈਟਿੰਗ ਵਰਤੋ"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"ਵਰਗ"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"ਵਰਗਾਕਾਰ-ਚੱਕਰ"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"ਚੱਕਰ"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"ਹੰਝੂ ਦੀ ਬੂੰਦ"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"ਪ੍ਰਤੀਕ ਦੀ ਆਕ੍ਰਿਤੀ ਵਿੱਚ ਤਬਦੀਲੀਆਂ ਨੂੰ ਲਾਗੂ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"ਅਗਿਆਤ"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"ਹਟਾਓ"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ਖੋਜੋ"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"ਸੂਚਨਾਵਾਂ ਅਤੇ ਐਪਾਂ ਬੰਦ ਹਨ"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ਬੰਦ ਕਰੋ"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"ਇਹ ਕਾਰਵਾਈ ਅਸਫਲ ਹੋਈ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 98d2c66..6bcbfd5 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Ładuję aplikacje…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nie znaleziono aplikacji pasujących do zapytania „<xliff:g id="QUERY">%1$s</xliff:g>”"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Wyszukaj więcej aplikacji"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikacja"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Powiadomienia"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Kliknij i przytrzymaj, by wybrać skrót."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Kliknij dwukrotnie i przytrzymaj, by wybrać skrót lub użyć działań niestandardowych."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"To aplikacja systemowa i nie można jej odinstalować."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Folder bez nazwy"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> jest wyłączona"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g> – <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> powiadomienia</item>
       <item quantity="many"><xliff:g id="APP_NAME_2">%1$s</xliff:g> – <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> powiadomień</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> – <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> powiadomienia</item>
@@ -85,23 +86,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Funkcja wyłączona przez administratora"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Zezwalaj na obrót ekranu głównego"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Po obróceniu telefonu"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Plakietki z powiadomieniami"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Włączono"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Wyłączono"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Plakietki z powiadomieniami"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Włączono"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Wyłączono"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Wymagany jest dostęp do powiadomień"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Aby pokazać plakietki z powiadomieniami, włącz powiadomienia aplikacji <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Zmień ustawienia"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Pokaż plakietki z powiadomieniami"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Pokaż plakietki z powiadomieniami"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikonę do ekranu głównego"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"W przypadku nowych aplikacji"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Zmień kształt ikon"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"na ekranie głównym"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Użyj ustawienia domyślnego"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kwadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaokrąglony kwadrat"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Okrąg"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Łza"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Zmieniam kształt ikon"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Brak informacji"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Usuń"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Szukaj"</string>
@@ -147,4 +140,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Powiadomienia i aplikacje są wyłączone"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zamknij"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zamknięto"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Niepowodzenie: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 6a98848..2527cd5 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"A carregar aplicações…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhuma aplicação correspondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais aplicações"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplicação"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Toque sem soltar para escolher um atalho."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Toque duas vezes sem soltar para escolher um atalho ou utilize ações personalizadas."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"É uma aplicação de sistema e não pode ser desinstalada."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Pasta sem nome"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desativado"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, tem <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificações.</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, tem <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificação.</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other">A aplicação <xliff:g id="APP_NAME_2">%1$s</xliff:g> tem <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificações.</item>
+      <item quantity="one">A aplicação <xliff:g id="APP_NAME_0">%1$s</xliff:g> tem <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificação</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Ecrã principal %1$d de %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativada pelo gestor"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação do ecrã principal"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o telemóvel é rodado"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Pontos de notificação"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Ativada"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desativada"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Pontos de notificação"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Ativados"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Desativados"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Acesso a notificações necessário"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Para mostrar os Pontos de notificação, ative as notificações de aplicações para o <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Alterar definições"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Mostrar pontos de notificação"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar pontos de notificação"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adicionar ícone ao ecrã principal"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novas aplicações"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Alterar forma do ícone"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"no ecrã principal"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Utilizar a predefinição do sistema"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Quadrado"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Quadrado e círculo"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lágrima"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"A aplicar alterações à forma do ícone..."</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Remover"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Pesquisar"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"As notificações e as aplicações estão desativadas."</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Fechar"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Fechado"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Falhou: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index d3b3ab3..93bcca7 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Carregando apps…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais apps"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Toque e segure para selecionar um atalho."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Toque duas vezes na tela e segure para selecionar um atalho ou usar ações personalizadas."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Este é um app do sistema e não pode ser desinstalado."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Pasta sem nome"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desativado"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one">O app <xliff:g id="APP_NAME_2">%1$s</xliff:g> tem <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificação</item>
-      <item quantity="other">O app <xliff:g id="APP_NAME_2">%1$s</xliff:g> tem <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificações</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one">O app <xliff:g id="APP_NAME_2">%1$s</xliff:g>tem <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificação</item>
+      <item quantity="other">O app <xliff:g id="APP_NAME_2">%1$s</xliff:g>tem <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificações</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Tela inicial %1$d de %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativado pelo administrador"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação da tela inicial"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Quando o smartphone for girado"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Pontos de notificação"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Ativado"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Desativado"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Pontos de notificação"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Ativado"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Desativado"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Acesso a notificações necessário"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Para mostrar pontos de notificação, ative as notificações de app para <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Alterar configurações"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Mostrar pontos de notificação"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Mostrar pontos de notificação"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adicionar ícone à tela inicial"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para novos apps"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Alterar forma de ícones"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"na tela inicial"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Usar padrão do sistema"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Quadrado"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Quadrado arredondado"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Círculo"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lágrima"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Aplicando alterações na forma dos ícones"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Remover"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Pesquisar"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"As notificações e os apps estão desativados"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Fechar"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Fechado"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Falha: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 26f3f23..d1e5b3d 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Se încarcă aplicații…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nu s-a găsit nicio aplicație pentru „<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Căutați mai multe aplicații"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplicație"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificări"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Atingeți lung pentru a selecta o comandă rapidă."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Atingeți lung pentru a selecta o comandă rapidă sau folosiți acțiuni personalizate."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Aceasta este o aplicație de sistem și nu poate fi dezinstalată."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Dosar fără nume"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"S-a dezactivat <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g> are <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notificări</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> are <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> de notificări</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>​ are <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> de notificări</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> are <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> notificare</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Pagina %1$d din %2$d"</string>
@@ -84,23 +85,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dezactivată de administrator"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permiteți rotirea ecranului de pornire"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Când telefonul este rotit"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Puncte de notificare"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Activat"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Dezactivat"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Puncte de notificare"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Activate"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Dezactivate"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Este necesar accesul la notificări"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Pentru a afișa punctele de notificare, activați notificările din aplicație pentru <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Modificați setările"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Afișați punctele de notificare"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Afișați punctele de notificare"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Adaugă pictograme în ecranul de pornire"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pentru aplicații noi"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Schimbați forma pictogramei"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"pe ecranul de pornire"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Folosiți setarea prestabilită a sistemului"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Pătrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Pătrat cu colțuri rotunjite"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Cerc"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Lacrimă"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Se aplică modificările aduse formei pictogramei"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Necunoscut"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Eliminați"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Căutați"</string>
@@ -146,4 +139,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Notificările și aplicațiile sunt dezactivate"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Închideți"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Închis"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Eșuare: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 0f70ecd..f633ed6 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Загрузка приложений…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"По запросу \"<xliff:g id="QUERY">%1$s</xliff:g>\" ничего не найдено"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Искать другие приложения"</string>
+    <string name="label_application" msgid="8531721983832654978">"Приложение"</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>
@@ -64,11 +65,11 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Это системное приложение, его нельзя удалить."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Папка без названия"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Приложение <xliff:g id="APP_NAME">%1$s</xliff:g> отключено"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомление</item>
-      <item quantity="few">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомления</item>
-      <item quantity="many">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомлений</item>
-      <item quantity="other">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомления</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомление</item>
+      <item quantity="few">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомления</item>
+      <item quantity="many">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомлений</item>
+      <item quantity="other">В приложении \"<xliff:g id="APP_NAME_2">%1$s</xliff:g>\" <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> уведомления</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Стр. %1$d из %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Главный экран %1$d из %2$d"</string>
@@ -85,25 +86,17 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Функция отключена администратором"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Разрешить поворачивать главный экран"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Когда телефон повернут"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Значки уведомлений"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Вкл."</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Выкл."</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Значки уведомлений"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Включены"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Отключены"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Нет доступа к уведомлениям"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Чтобы показывать значки уведомлений, включите уведомления в приложении \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Изменить настройки"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Показывать значки уведомлений"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Показывать значки уведомлений"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Добавлять значки"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Добавлять значки установленных приложений на главный экран"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Изменить форму значков"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"на главном экране"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Использовать системные настройки по умолчанию"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Квадрат с закругленными краями"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Капля"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Применение изменений…"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Неизвестно"</string>
-    <string name="abandoned_clean_this" msgid="7610119707847920412">"Удалить"</string>
+    <string name="abandoned_clean_this" msgid="7610119707847920412">"Убрать"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Найти"</string>
     <string name="abandoned_promises_title" msgid="7096178467971716750">"Приложение не установлено"</string>
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Приложение не установлено. Вы можете удалить значок или найти приложение и установить его вручную."</string>
@@ -147,4 +140,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Уведомления и приложения отключены."</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Закрыть"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Закрыта"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Не удалось выполнить действие (<xliff:g id="WHAT">%1$s</xliff:g>)."</string>
 </resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index aea06aa..ae0fb50 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"යෙදුම් පූරණය වෙමින්…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"තව යෙදුම් සඳහා සොයන්න"</string>
+    <string name="label_application" msgid="8531721983832654978">"යෙදුම"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"මෙය පද්ධති යෙදුමක් වන අතර අස්ථාපනය කළ නොහැක."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"නම් නොකළ ෆෝල්ඩරය"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> අබල කෙරිණි"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, දැනුම්දීම් <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>ක් ඇත</item>
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, දැනුම්දීම් <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g>ක් ඇත</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ඔබගේ පරිපාලක විසින් අබල කරන ලදී"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"දුරකථනය කරකවන විට"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"දැනුම්දීම් තිත්"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ක්‍රියාත්මකයි"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ක්‍රියාවිරහිතයි"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"දැනුම්දීම් තිත්"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ක්‍රියාත්මකයි"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ක්‍රියාවිරහිතයි"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"දැනුම්දීම් ප්‍රවේශය අවශ්‍යයි"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"දැනුම්දීම් තිත් පෙන්වීමට, <xliff:g id="NAME">%1$s</xliff:g> සඳහා යෙදුම් දැනුම්දීම් සබල කරන්න"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"සැකසීම් වෙනස් කරන්න"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"දැනුම් දීමේ තිත් පෙන්වන්න"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"දැනුම්දීම් තිත් පෙන්වන්න"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"මුල් පිටු තිරය වෙත අයිකනය එක් කරන්න"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"නව යෙදුම් සඳහා"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"නිරූපක හැඩය වෙනස් කරන්න"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"මුල් පිටු තිරය මත"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"පද්ධති පෙරනිමි භාවිත කරන්න"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"සමචතුරස්‍රය"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"හතරැස් කවය"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"කවය"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"කඳුළු බිංදුව"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"නිරූපක හැඩය වෙනස් කිරීම් යොදමින්"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"නොදනී"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"ඉවත් කරන්න"</string>
     <string name="abandoned_search" msgid="891119232568284442">"සොයන්න"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"දැනුම්දීම් සහ යෙදුම් ක්‍රියාවිරහිතයි"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"වසන්න"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"වසා ඇත"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"අසාර්ථකයි: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index c983fe1..9f7e503 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Načítavajú sa aplikácie…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenašli sa žiadne aplikácie zodpovedajúce dopytu <xliff:g id="QUERY">%1$s</xliff:g>"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hľadať ďalšie aplikácie"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikácia"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Upozornenia"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Skratku pridáte pridržaním."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Skratku pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií."</string>
@@ -64,11 +65,11 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikácia a nedá sa odinštalovať."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Nepomenovaný priečinok"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je deaktivovaná"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="few">Aplikácia <xliff:g id="APP_NAME_2">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> upozornenia</item>
-      <item quantity="many">Aplikácia <xliff:g id="APP_NAME_2">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> upozornenia</item>
-      <item quantity="other">Aplikácia <xliff:g id="APP_NAME_2">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> upozornení</item>
-      <item quantity="one">Aplikácia <xliff:g id="APP_NAME_0">%1$s</xliff:g> má <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> upozornenie</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> upozornenia</item>
+      <item quantity="many"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, has <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notifications</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, má <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> upozornení</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, má <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> upozornenie</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Stránka %1$d z %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Plocha %1$d z %2$d"</string>
@@ -85,23 +86,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázané vaším správcom"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Povoliť otáčanie plochy"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Pri otočení telefónu"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Bodky upozornení"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Zapnuté"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Vypnuté"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Bodky upozornení"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Zapnuté"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Vypnuté"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Vyžaduje sa prístup k upozorneniam"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Ak chcete, aby sa zobrazovali bodky upozornení, zapnite upozornenia aplikácie <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Zmeniť nastavenia"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Zobrazovať bodky upozornení"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Zobrazovať bodky upozornení"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Pridať ikonu na plochu"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pri inštalácii novej aplikácie"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Zmeniť tvar ikony"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"na ploche"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Použiť predvolené nastavenie systému"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Štvorec"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Okrúhly štvorec"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Kruh"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Slza"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Tvar ikony sa mení"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Neznáme"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Odstrániť"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Vyhľadať"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 903edd2..0d9f504 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Nalaganje aplikacij …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ni aplikacij, ki bi ustrezale poizvedbi »<xliff:g id="QUERY">%1$s</xliff:g>«"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Iskanje več aplikacij"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikacija"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obvestila"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Pridržite bližnjico, da jo izberete."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Dvakrat se dotaknite bližnjice in jo pridržite, da jo izberete, ali pa uporabite dejanja po meri."</string>
@@ -49,7 +50,7 @@
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"Seznam delovnih aplikacij"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"Začetni zaslon"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"Odstrani"</string>
-    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Odstrani"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Odmesti"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"Podatki o aplikaciji"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"Namesti"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"namestitev bližnjic"</string>
@@ -64,11 +65,11 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"To je sistemska aplikacija in je ni mogoče odstraniti."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Neimenovana mapa"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogočena"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestilo</item>
-      <item quantity="two">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestili</item>
-      <item quantity="few">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestila</item>
-      <item quantity="other">Aplikacija <xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestil</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestilo</item>
+      <item quantity="two"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestili</item>
+      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestila</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ima <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> obvestil</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Stran %1$d od %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Začetni zaslon %1$d od %2$d"</string>
@@ -85,23 +86,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogočil skrbnik."</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Omogočanje sukanja začetnega zaslona"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Ko se telefon zasuka"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Obvestilne pike"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Vklopljeno"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Izklopljeno"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Obvestilne pike"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Vklopljeno"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Izklopljeno"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Potreben je dostop do obvestil"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Za prikaz obvestilnih pik vklopite obvestila aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Spremeni nastavitve"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Pokaži obvestilne pike"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Pokaži obvestilne pike"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodaj ikono na začetni zaslon"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Spremeni obliko ikon"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"na začetnem zaslonu"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Uporabi privzeto nastavitev sistema"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Zaobljen kvadrat"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Krog"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Solza"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Uveljavljanje spremenjene oblike ikon"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Neznano"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Odstrani"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Iskanje"</string>
@@ -147,4 +140,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Obvestila in aplikacije – izklopljeno"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Zapri"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Zaprto"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Ni uspelo: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index c26b7a5..8dfb229 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Po ngarkon aplikacionet..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nuk u gjet asnjë aplikacion që përputhet me \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Kërko për më shumë aplikacione"</string>
+    <string name="label_application" msgid="8531721983832654978">"Aplikacioni"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Njoftimet"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Prek dhe mbaj prekur për të zgjedhur një shkurtore."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Prek dy herë dhe mbaj prekur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ky është aplikacion sistemi dhe nuk mund të çinstalohet."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Dosje e paemërtuar"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> u çaktivizua"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ka <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> njoftime</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ka <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> njoftime</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ka <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> njoftim</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Faqja: %1$d nga gjithsej %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Ekrani bazë: %1$d nga gjithsej %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Çaktivizuar nga administratori"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Lejo rrotullimin e ekranit kryesor"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Kur telefoni rrotullohet"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Pikat e njoftimeve"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Aktiv"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Joaktiv"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Pikat e njoftimeve"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Aktiv"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Joaktiv"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Nevojitet qasja në njoftime"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Për të shfaqur \"Pikat e njoftimeve\", aktivizo njoftimet e aplikacionit për <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Ndrysho cilësimet"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Shfaq pikat e njoftimeve"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Shfaq pikat e njoftimeve"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Shto ikonë në ekranin bazë"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Për aplikacionet e reja"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Ndrysho formën e ikonës"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"në ekranin bazë"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Përdor parazgjedhjen e sistemit"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Katror"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Katror me kënde të rrumbullakëta"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Rreth"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Pikë loti"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Po zbatohen ndryshimet e formës së ikonës"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"I panjohur"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Hiq"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Kërko"</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 0a6e30a..067cf9f 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Апликације се учитавају…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Није пронађена ниједна апликација за „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Претражи још апликација"</string>
+    <string name="label_application" msgid="8531721983832654978">"Апликација"</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>
@@ -64,10 +65,10 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Ово је системска апликација и не може да се деинсталира."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Неименовани директоријум"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је онемогућена"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g> има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> обавештење</item>
-      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g> има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> обавештења</item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> обавештења</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> обавештење</item>
+      <item quantity="few"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> обавештења</item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, има <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> обавештења</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%1$d. страница од %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d. почетни екран од %2$d"</string>
@@ -84,23 +85,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администратор је онемогућио"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Дозволи ротацију почетног екрана"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Када се телефон ротира"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Тачке за обавештења"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Укључено"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Искључено"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Тачке за обавештења"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Укључено"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Искључено"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Потребан је приступ за обавештења"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Да бисте приказали тачке за обавештења, укључите обавештења за апликацију <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Промените подешавања"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Приказуј тачке за обавештења"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Приказуј тачке за обавештења"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додај икону на почетни екран"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нове апликације"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Промените облик икона"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"на почетном екрану"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Користи подразумевано системско подешавање"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Заобљени квадрат"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Суза"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Примењују се промене облика икона"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Уклони"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Претражи"</string>
@@ -146,4 +139,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Обавештења и апликације су искључени"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Затвори"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Затворено"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Није успело: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 01e8841..791fcc1 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Läser in appar …"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Inga appar som matchar <xliff:g id="QUERY">%1$s</xliff:g> hittades"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sök efter fler appar"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Aviseringar"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Tryck länge om du vill ta upp en genväg."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Tryck snabbt två gånger och håll kvar om du vill ta upp en genväg eller använda anpassade åtgärder."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Det här är en systemapp som inte kan avinstalleras."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Namnlös mapp"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inaktiverats"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> aviseringar</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> har <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> avisering</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inaktiverat av administratören"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Tillåt rotering av startskärmen"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"När mobilen vrids"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Aviseringsprickar"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"På"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Av"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Aviseringsprickar"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"På"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Av"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Åtkomst till aviseringar krävs"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Aktivera appaviseringar för <xliff:g id="NAME">%1$s</xliff:g> om du vill att aviseringsprickar ska visas"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Ändra inställningar"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Visa aviseringsprickar"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Visa aviseringsprickar"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Lägg till ikonen på startskärmen"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"För nya appar"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Ändra form på ikoner"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"på startskärmen"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Använd systemstandard"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Kvirkel"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Cirkel"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Droppe"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Ikonernas form ändras"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Okänt"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Ta bort"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Sök"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Aviseringar och appar är inaktiverade"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Stäng"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Stängd"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Misslyckades: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index c315061..b705b8e 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Inapakia programu..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Haikupata programu zozote zinazolingana na \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tafuta programu zaidi"</string>
+    <string name="label_application" msgid="8531721983832654978">"Programu"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Arifa"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Gusa na ushikilie ili uchague njia ya mkato."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Gusa mara mbili na ushikilie ili uchague njia ya mkato au utumie vitendo maalum."</string>
@@ -49,7 +50,7 @@
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"Orodha ya programu za kazini"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"Mwanzo"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"Ondoa"</string>
-    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Ondoa"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Sakinua"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"Maelezo ya programu"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"Sakinisha"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"kuweka njia za mkato"</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Hii ni programu ya mfumo na haiwezi kuondolewa."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Folda isiyo na jina"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> imezimwa"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, ina arifa <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, ina arifa <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g></item>
     </plurals>
@@ -85,23 +86,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Imezimwa na msimamizi wako"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Ruhusu kuzungusha skrini ya Kwanza"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Simu inapozungushwa"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Vitone vya arifa"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Imewashwa"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Imezimwa"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Vitone vya arifa"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Imewashwa"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Imezimwa"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Inahitaji idhini ya kufikia arifa"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Ili kuonyesha Vitone vya Arifa, washa kipengele cha arifa za programu katika <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Badilisha mipangilio"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Onyesha kitone cha arifa"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Onyesha vitone vya arifa"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ongeza aikoni kwenye Skrini ya kwanza"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Kwa ajili ya programu mpya"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Badilisha umbo la aikoni"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"kwenye Skrini ya mwanzo"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Tumia umbo chaguomsingi la mfumo"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Mraba"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Mstatili wenye pembe duara"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Mduara"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Umbo la chozi"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Inabadilisha umbo la aikoni"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Yasiyojulikana"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Ondoa"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Tafuta"</string>
@@ -147,4 +140,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Vipenge vya arifa na programu vimezimwa"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Funga"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Imefungwa"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Hitilafu: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index ed0f09d..28c6a04 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"பயன்பாடுகளை ஏற்றுகிறது…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் பயன்பாடுகள் இல்லை"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"கூடுதல் பயன்பாடுகளைத் தேடு"</string>
+    <string name="label_application" msgid="8531721983832654978">"ஆப்ஸ்"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"இது அமைப்பு பயன்பாடு என்பதால் நிறுவல் நீக்கம் செய்ய முடியாது."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"பெயரிடப்படாத கோப்புறை"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> முடக்கப்பட்டது"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> பயன்பாட்டில், <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> அறிவிப்புகள் வந்துள்ளன</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> பயன்பாட்டில், <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> அறிவிப்பு வந்துள்ளது</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ஆப்ஸில் <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> அறிவிப்புகள் வந்துள்ளன</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> ஆப்ஸில் <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> அறிவிப்பு வந்துள்ளது</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"பக்கம் %1$d / %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"முகப்புத் திரை %1$d of %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"உங்கள் நிர்வாகி முடக்கியுள்ளார்"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"முகப்புத் திரை சுழற்சியை அனுமதி"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"மொபைலைச் சுழற்றும் போது"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"அறிவிப்புப் புள்ளிகள்"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ஆன்"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"முடக்கப்பட்டுள்ளது"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"அறிவிப்புப் புள்ளிகள்"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ஆன்"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ஆஃப்"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"அறிவிப்பிற்கான அணுகல் தேவை"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"அறிவிப்புப் புள்ளிகளைக் காட்ட, <xliff:g id="NAME">%1$s</xliff:g> இன் பயன்பாட்டு அறிவிப்புகளை இயக்கவும்"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"அமைப்புகளை மாற்று"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"அறிவிப்புப் புள்ளிகளைக் காட்டு"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"அறிவிப்புப் புள்ளிகளைக் காட்டு"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"முகப்புத் திரையில் ஐகானைச் சேர்"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"புதிய பயன்பாடுகளுக்கு"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"ஐகான் வடிவத்தை மாற்று"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"முகப்புத் திரையில்"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"அமைப்பின் இயல்புநிலையைப் பயன்படுத்து"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"சதுரம்"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"சதுரவட்டம்"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"வட்டம்"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"கண்ணீர்துளி"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"ஐகான் வடிவத்தை மாற்றுகிறது"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"தெரியாதது"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"அகற்று"</string>
     <string name="abandoned_search" msgid="891119232568284442">"தேடு"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"ஆப்ஸும் அறிவிப்புகளும் ஆஃப் செய்யப்பட்டுள்ளன"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"மூடுக"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"மூடப்பட்டது"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"தோல்வி: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 19ab7e7..744a79a 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"అప్లికేషన్‌లను లోడ్ చేస్తోంది…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"మరిన్ని యాప్‌ల కోసం వెతుకు"</string>
+    <string name="label_application" msgid="8531721983832654978">"యాప్"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"ఇది సిస్టమ్ యాప్ మరియు దీన్ని అన్‌ఇన్‌స్టాల్ చేయడం సాధ్యపడదు."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"పేరు లేని ఫోల్డర్"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> నిలిపివేయబడింది"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> నోటిఫికేషన్‌‌లను కలిగి ఉన్నారు</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> నోటిఫికేషన్‌ను కలిగి ఉన్నారు</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, నుంచి <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> నోటిఫికేషన్‌లు ఉన్నాయి</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, నుంచి <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> నోటిఫికేషన్ ఉంది</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%2$dలో %1$dవ పేజీ"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dలో %1$dవ హోమ్ స్క్రీన్"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"మీ నిర్వాహకులు నిలిపివేసారు"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ఫోన్‌‌ను తిప్పినప్పుడు"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"నోటిఫికేషన్ డాట్‌లు"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"ఆన్"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ఆఫ్"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"నోటిఫికేషన్ డాట్‌లు"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"ఆన్"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ఆఫ్"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"నోటిఫికేషన్ యాక్సెస్ అవసరం"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"నోటిఫికేషన్ డాట్‌లను చూపించడానికి <xliff:g id="NAME">%1$s</xliff:g>కు యాప్ నోటిఫికేషన్‌లను ఆన్ చేయండి"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"సెట్టింగ్‌లను మార్చు"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"నోటిఫికేషన్ డాట్‌లను చూపుతుంది"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"నోటిఫికేషన్ డాట్‌లను చూపు"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"హోమ్ స్క్రీన్‌కి చిహ్నాన్ని జోడించు"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"కొత్త యాప్‌ల కోసం"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"చిహ్న ఆకారాన్ని మార్చు"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"హోమ్ స్క్రీన్‌పై"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"సిస్టమ్ డిఫాల్ట్‌ను ఉపయోగించండి"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"చతురస్రం"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"చతురస్రాకార వృత్తం"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"వృత్తం"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"కన్నీటి చుక్క"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"చిహ్న ఆకార మార్పులను వర్తింపజేస్తోంది"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"తెలియదు"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"తీసివేయి"</string>
     <string name="abandoned_search" msgid="891119232568284442">"వెతుకు"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"నోటిఫికేషన్‌లు మరియు యాప్‌లు ఆఫ్ చేయబడ్డాయి"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"మూసివేయి"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"మూసివేయబడింది"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"విఫలమైంది: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 7564bd0..6bac806 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"กำลังโหลดแอป…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"ไม่พบแอปที่ตรงกับ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ค้นหาแอปเพิ่มเติม"</string>
+    <string name="label_application" msgid="8531721983832654978">"แอป"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"นี่เป็นแอประบบและไม่สามารถถอนการติดตั้งได้"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"โฟลเดอร์ที่ไม่มีชื่อ"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"ปิดใช้ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> มีการแจ้งเตือน <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> รายการ</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> มีการแจ้งเตือน <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> รายการ</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ปิดใช้โดยผู้ดูแลระบบ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"อนุญาตให้หมุนหน้าจอหลัก"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"เมื่อหมุนโทรศัพท์"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"จุดแจ้งเตือน"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"เปิด"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"ปิด"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"เครื่องหมายจุดแสดงการแจ้งเตือน"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"เปิด"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"ปิด"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"ต้องได้รับสิทธิ์เข้าถึงการแจ้งเตือน"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"เปิดการแจ้งเตือนแอปของ <xliff:g id="NAME">%1$s</xliff:g> เพื่อแสดงจุดแจ้งเตือน"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"เปลี่ยนการตั้งค่า"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"แสดงจุดแจ้งเตือน"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"แสดงเครื่องหมายจุดแสดงการแจ้งเตือน"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"เพิ่มไอคอนในหน้าจอหลัก"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"สำหรับแอปใหม่"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"เปลี่ยนรูปร่างไอคอน"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"ในหน้าจอหลัก"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"ใช้ค่าเริ่มต้นของระบบ"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"สี่เหลี่ยมจัตุรัส"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"สี่เหลี่ยมขอบมน"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"วงกลม"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"หยดน้ำตา"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"กำลังนำการเปลี่ยนรูปร่างไอคอนไปใช้"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"ไม่รู้จัก"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"ลบ"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ค้นหา"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"ปิดการแจ้งเตือนและแอปอยู่"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"ปิด"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"ปิด"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"ไม่สำเร็จ: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index ac54075..b555240 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Naglo-load ng mga app…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Walang nahanap na app na tumutugma sa \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Maghanap ng higit pang mga app"</string>
+    <string name="label_application" msgid="8531721983832654978">"App"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Mga Notification"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Pindutin nang matagal para kumuha ng shortcut."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"I-double tap nang matagal para kumuha ng shortcut o gumamit ng mga custom na pagkilos."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Isa itong app ng system at hindi maaaring i-uninstall."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Walang Pangalang Folder"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Naka-disable ang <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one">May <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> notification ang <xliff:g id="APP_NAME_2">%1$s</xliff:g></item>
-      <item quantity="other">May <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> na notification ang <xliff:g id="APP_NAME_2">%1$s</xliff:g></item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one">May <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> (na) notification ang <xliff:g id="APP_NAME_2">%1$s</xliff:g></item>
+      <item quantity="other">May <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> (na) notification ang <xliff:g id="APP_NAME_2">%1$s</xliff:g></item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Pahina %1$d ng %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Home screen %1$d ng %2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Na-disable ng iyong admin"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Payagan ang pag-rotate ng Home screen"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Kailan maro-rotate ang telepono"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Mga notification dot"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Naka-on"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Naka-off"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Mga notification dot"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Naka-on"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Naka-off"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Kinakailangan ng access sa notification"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Upang ipakita ang Mga Notification Dot, i-on ang mga notification ng app para sa <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Baguhin ang mga setting"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Ipakita ang mga notification dot"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Ipakita ang mga notification dot"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Idagdag ang icon sa Home screen"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Para sa mga bagong app"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Baguhin ang hugis ng icon"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"sa Home screen"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Gamitin ang default ng system"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Parisukat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Squircle"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Bilog"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Teardrop"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Inilalapat ang mga pagbabago sa hugis ng icon"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Hindi kilala"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Alisin"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Maghanap"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Naka-off ang mga notification at app"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Isara"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Nakasara"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Hindi nagawa: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 6483db5..10635f9 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Uygulamalar yükleniyor…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ile eşleşen uygulama bulunamadı"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Başka uygulamalar ara"</string>
+    <string name="label_application" msgid="8531721983832654978">"Uygulama"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Bildirimler"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Kısayol seçmek için dokunun ve basılı tutun."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Bir kısayolu seçmek veya özel işlemleri kullanmak için iki kez dokunun ve basılı tutun."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu bir sistem uygulamasıdır ve yüklemesi kaldırılamaz."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Adsız Klasör"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> devre dışı"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> uygulamasının <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> bildirimi var</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> uygulamasının <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> bildirimi var</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Yöneticiniz tarafından devre dışı bırakıldı"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Ana ekranı döndürmeye izin ver"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon döndürüldüğünde"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Bildirim noktaları"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Açık"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Kapalı"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Bildirim noktaları"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Açık"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Kapalı"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Bildirim erişimi gerekli"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Bildirim Noktaları\'nı göstermek için <xliff:g id="NAME">%1$s</xliff:g> uygulamasının bildirimlerini açın"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Ayarları değiştir"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Bildirim noktalarını göster"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Bildirim noktalarını göster"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ana ekrana simge ekle"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yeni uygulamalar için"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Simge şeklini değiştir"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"Ana ekranda"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Sistem varsayılanını kullan"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kare"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Kare-daire"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Daire"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Gözyaşı damlası"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Simge şekli değişiklikleri uygulanıyor"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Bilinmiyor"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Kaldır"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Ara"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Bildirimler ve uygulamalar kapalı"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Kapat"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Kapalı"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Başarısız: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 505ad92..f7ce822 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Завантаження додатків…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Немає додатків для запиту \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукати ще додатки"</string>
+    <string name="label_application" msgid="8531721983832654978">"Додаток"</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>
@@ -49,7 +50,7 @@
     <string name="all_apps_button_work_label" msgid="7270707118948892488">"Список робочих додатків"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"Головний екран"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"Видалити"</string>
-    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Видалити"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Видалити додаток"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"Про додаток"</string>
     <string name="install_drop_target_label" msgid="2539096853673231757">"Установити"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"створення ярликів"</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Це системна програма, її неможливо видалити."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Папка без назви"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> вимкнено"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="one">Додаток <xliff:g id="APP_NAME_2">%1$s</xliff:g> має <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> сповіщення</item>
       <item quantity="few">Додаток <xliff:g id="APP_NAME_2">%1$s</xliff:g> має <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> сповіщення</item>
       <item quantity="many">Додаток <xliff:g id="APP_NAME_2">%1$s</xliff:g> має <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> сповіщень</item>
@@ -85,25 +86,17 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Вимкнув адміністратор"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Дозволити обертання головного екрана"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Коли телефон обертається"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Значки сповіщень"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Увімкнено"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Вимкнено"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Значки сповіщень"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Увімкнено"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Вимкнено"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Потрібен доступ до сповіщень"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Щоб показувати значки сповіщень, увімкніть сповіщення в додатку <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Змінити налаштування"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Показувати значки сповіщень"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Показувати значки сповіщень"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додати значок на головний екран"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Для нових додатків"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Змінити форму значка"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"на головному екрані"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Використовувати налаштування системи за умовчанням"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Квадрат"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Квадрат із заокругленими кутами"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Круг"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Сльоза"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Змінюється форма значка"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Невідомо"</string>
-    <string name="abandoned_clean_this" msgid="7610119707847920412">"Видалити"</string>
+    <string name="abandoned_clean_this" msgid="7610119707847920412">"Прибрати"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Шукати"</string>
     <string name="abandoned_promises_title" msgid="7096178467971716750">"Цей додаток не встановлено"</string>
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Додаток для цього значка не встановлено. Можна видалити значок або знайти додаток і встановити його вручну."</string>
@@ -147,4 +140,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Сповіщення та додатки вимкнено"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Закрити"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Закрито"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Не вдалося <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index 56c8d32..010275c 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"ایپس لوڈ کی جا رہی ہیں…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" سے مماثل کوئی ایپس نہیں ملیں"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"مزید ایپس تلاش کریں"</string>
+    <string name="label_application" msgid="8531721983832654978">"ایپ"</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>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"یہ ایک سسٹم ایپ ہے اور اسے اَن انسٹال نہیں کیا جا سکتا ہے۔"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"بلا نام فولڈر"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> غیر فعال ہے"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> میں <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> اطلاعات ہیں</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> میں <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> اطلاع ہے</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> میں<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> اطلاعات ہیں</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> میں<xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> اطلاع ہے</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"‏صفحہ ‎%1$d از ‎%2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"‏ہوم اسکرین ‎%1$d از ‎%2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ہوم اسکرین گھمانے کی اجازت دیں"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"جب فون گھمایا جاتا ہے"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"اطلاعاتی ڈاٹس"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"آن"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"آف"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"اطلاعاتی ڈاٹس"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"آن ہے"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"آف ہے"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"اطلاعاتی رسائی درکار ہے"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"اطلاعاتی ڈاٹس دکھانے کی خاطر <xliff:g id="NAME">%1$s</xliff:g> کیلئے ایپ کی اطلاعات آن کریں"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"ترتیبات تبدیل کریں"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"اطلاعاتی ڈاٹس دکھائیں"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"اطلاعاتی ڈاٹس دکھائیں"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"آئیکن کو ہوم اسکرین میں شامل کریں"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"نئی ایپس کیلئے"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"آئیکن کی شکل تبدیل کریں"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"ہوم اسکرین پر"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"سسٹم ڈیفالٹ کا استعمال کریں"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"مربع"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"اسکورکل"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"حلقہ"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"آنسو کا قطرہ"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"آئيکن کی شکل کی تبدیلیاں لاگو ہو رہی ہیں"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"نامعلوم"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"ہٹائیں"</string>
     <string name="abandoned_search" msgid="891119232568284442">"تلاش کریں"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"اطلاعات اور ایپس آف ہیں"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"بند کریں"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"بند"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"ناکام ہو گيا: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index c3b3dde..9b4493c 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Ilovalar yuklanmoqda…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"“<xliff:g id="QUERY">%1$s</xliff:g>” bilan mos hech qanday ilova topilmadi"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Boshqa ilovalarni qidirish"</string>
+    <string name="label_application" msgid="8531721983832654978">"Ilova"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Bildirishnomalar"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Yorliqni tanlab olish uchun bosib turing."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu tizim ilovasi, shuning uchun o‘chirib bo‘lmaydi."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Nomsiz jild"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi o‘chirib qo‘yildi"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ta bildirishnoma bor</item>
-      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ta bildirishnoma bor</item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g> ilovasida <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> ta bildirishnoma bor</item>
+      <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g> ilovasida <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> ta bildirishnoma bor</item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"%2$ddan %1$d ta sahifa"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Uy ekrani %2$ddan %1$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator tomonidan o‘chirilgan"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Asosiy ekranni aylantirishga ruxsat berish"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Telefon burilganda"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Bildirishnoma belgilari"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Yoniq"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"O‘chiq"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Bildirishnoma belgilari"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Yoniq"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Yoqilmagan"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Bildirishnomalarga ruxsat berilmagan"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Bildirishnoma belgilarini ko‘rsatish uchun <xliff:g id="NAME">%1$s</xliff:g> ilovasida bildirishnomalarni yoqing"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Sozlamalarni o‘zgartirish"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Bildirishnoma belgilarini ko‘rsatish"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Bildirishnoma belgilarini chiqarish"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Bosh ekranga ikonka chiqarish"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yangi o‘rnatilgan ilovalar ikonkasini bosh ekranga chiqarish"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Ikonka shaklini o‘zgartirish"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"Bosh ekranda"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Standart tizim parametrlaridan foydalanish"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Kvadrat"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Qirralari aylana kvadrat"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Aylana"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Tomchi"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Ikonka shakli o‘zgartirilmoqda"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Noma’lum"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"O‘chirish"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Qidirish"</string>
diff --git a/res/values-v26/bools.xml b/res/values-v26/bools.xml
index 30537fe..ad8c7a1 100644
--- a/res/values-v26/bools.xml
+++ b/res/values-v26/bools.xml
@@ -17,7 +17,7 @@
 -->
 
 <resources>
-    <bool name="notification_badging_enabled">true</bool>
+    <bool name="notification_dots_enabled">true</bool>
 
     <bool name="enable_install_shortcut_api">false</bool>
 </resources>
\ No newline at end of file
diff --git a/res/values-v26/styles.xml b/res/values-v26/styles.xml
index e810ab2..8fb408b 100644
--- a/res/values-v26/styles.xml
+++ b/res/values-v26/styles.xml
@@ -19,6 +19,7 @@
 <resources>
     <!-- Theme for the widget container. -->
     <style name="WidgetContainerTheme" parent="@android:style/Theme.DeviceDefault.Settings">
+        <item name="android:colorPrimaryDark">#E8EAED</item>
         <item name="android:colorEdgeEffect">?android:attr/textColorSecondary</item>
     </style>
     <style name="WidgetContainerTheme.Dark" parent="AppTheme.Dark">
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 6ead214..1f2de46 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Đang tải ứng dụng…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Không tìm thấy ứng dụng nào phù hợp với \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tìm kiếm thêm ứng dụng"</string>
+    <string name="label_application" msgid="8531721983832654978">"Ứng dụng"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Thông báo"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Chạm và giữ để chọn lối tắt."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Nhấn đúp và giữ để chọn lối tắt hoặc sử dụng hành động tùy chỉnh."</string>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Đây là ứng dụng hệ thống và không thể gỡ cài đặt."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Thư mục chưa đặt tên"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Đã vô hiệu hóa <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, có <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> thông báo</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>, có <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> thông báo</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Bị tắt bởi quản trị viên của bạn"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Cho phép xoay Màn hình chính"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Khi xoay điện thoại"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Dấu chấm thông báo"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Đang bật"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Đã tắt"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Dấu chấm thông báo"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Bật"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Tắt"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Cần quyền truy cập thông báo"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Để hiển thị Dấu chấm thông báo, hãy bật thông báo ứng dụng cho <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Thay đổi cài đặt"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Hiển thị dấu chấm thông báo"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Hiển thị dấu chấm thông báo"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Thêm biểu tượng vào màn hình chính"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Cho ứng dụng mới"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Thay đổi hình dạng biểu tượng"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"trên Màn hình chính"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Sử dụng mặc định của hệ thống"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Hình vuông"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"Hình vuông cạnh bo tròn"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Hình tròn"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"Hình giọt nước"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Đang áp dụng các thay đổi hình dạng biểu tượng"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Không xác định"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Xóa"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Tìm kiếm"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"Thông báo và ứng dụng đang tắt"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"Đóng"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"Đã đóng"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"Không thực hiện được thao tác: <xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 09d2d78..12935ca 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"正在加载应用…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"未找到与“<xliff:g id="QUERY">%1$s</xliff:g>”相符的应用"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜索更多应用"</string>
+    <string name="label_application" msgid="8531721983832654978">"应用"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"这是系统应用,无法卸载。"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"未命名文件夹"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"已停用<xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> 个通知</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> 个通知</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"已被您的管理员停用"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"允许旋转主屏幕"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"手机旋转时"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"通知圆点"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"开启"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"关闭"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"通知圆点"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"开启"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"关闭"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"需要获取通知使用权"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"要显示通知圆点,请开启<xliff:g id="NAME">%1$s</xliff:g>的应用通知功能"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"更改设置"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"显示通知圆点"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"显示通知圆点"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"将图标添加到主屏幕"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"适用于新应用"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"更改图标形状"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"在主屏幕上"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"使用系统默认设置"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"方形"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"方圆形"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"圆形"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"泪珠形"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"正在应用图标形状更改"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"未知"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
     <string name="abandoned_search" msgid="891119232568284442">"搜索"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"通知和应用均已关闭"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"关闭"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"已关闭"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"失败:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index ce42d66..2178d87 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
+    <string name="label_application" msgid="8531721983832654978">"應用程式"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"這是系統應用程式,無法將其解除安裝。"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"未命名的資料夾"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已停用"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> 項通知</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> 項通知</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由您的管理員停用"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"允許主畫面旋轉"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"通知圓點"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"開啟"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"關閉"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"通知圓點"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"開啟"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"關閉"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"需要獲取通知存取權"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"如要顯示「通知圓點」,請開啟「<xliff:g id="NAME">%1$s</xliff:g>」的應用程式通知功能"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"變更設定"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"顯示通知圓點"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"顯示通知圓點"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"將圖示加到主畫面"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"適用於新安裝的應用程式"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"變更圖示形狀"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"在主畫面上"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"使用系統預設設定"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"正方形"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"方圓形"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"圓形"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"淚珠形"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"正在套用圖示形狀變更"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
     <string name="abandoned_search" msgid="891119232568284442">"搜尋"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"通知和應用程式已關閉"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"關閉"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"已關閉"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"操作失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 343cddc..66f104b 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
+    <string name="label_application" msgid="8531721983832654978">"應用程式"</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>
@@ -64,7 +65,7 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"這是系統應用程式,不可解除安裝。"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"未命名的資料夾"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"已停用 <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
       <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g> 則通知</item>
       <item quantity="one"><xliff:g id="APP_NAME_0">%1$s</xliff:g>,有 <xliff:g id="NOTIFICATION_COUNT_1">%2$d</xliff:g> 則通知</item>
     </plurals>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由你的管理員停用"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"允許旋轉主螢幕"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"當手機旋轉時"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"通知圓點"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"已啟用"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"已停用"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"通知圓點"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"開啟"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"關閉"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"需要取得通知存取權"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"如要顯示通知圓點,請開啟「<xliff:g id="NAME">%1$s</xliff:g>」的應用程式通知功能"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"變更設定"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"顯示通知圓點"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"顯示通知圓點"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"將圖示加到主螢幕"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"適用於新安裝的應用程式"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"變更圖示形狀"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"在主螢幕上"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"使用系統預設值"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"正方形"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"方圓形"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"圓形"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"淚珠形"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"正在套用圖示形狀變更"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"移除"</string>
     <string name="abandoned_search" msgid="891119232568284442">"搜尋"</string>
@@ -145,4 +138,5 @@
     <string name="work_mode_off_label" msgid="3194894777601421047">"已關閉通知和應用程式"</string>
     <string name="bottom_work_tab_user_education_close_button" msgid="4224492243977802135">"關閉"</string>
     <string name="bottom_work_tab_user_education_closed" msgid="1098340939861869465">"已關閉"</string>
+    <string name="remote_action_failed" msgid="1383965239183576790">"失敗:<xliff:g id="WHAT">%1$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index c25319e..1d38ff8 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -39,6 +39,7 @@
     <string name="all_apps_loading_message" msgid="5813968043155271636">"Ilayisha izinhlelo zokusebenza..."</string>
     <string name="all_apps_no_search_results" msgid="3200346862396363786">"Azikho izinhlelo zokusebenza ezitholiwe ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sesha izinhlelo zokusebenza eziningi"</string>
+    <string name="label_application" msgid="8531721983832654978">"Uhlelo lokusebenza"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Izaziso"</string>
     <string name="long_press_shortcut_to_add" msgid="4524750017792716791">"Thinta futhi ubambe ukuze ukhethe isinqamuleli."</string>
     <string name="long_accessible_way_to_add_shortcut" msgid="3327314059613154633">"Thepha kabili uphinde ubambe ukuze uphakamise isinqamuleli noma usebenzise izenzo zangokwezifiso."</string>
@@ -64,9 +65,9 @@
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Lolu uhlelo lokusebenza lwesistimu futhi alikwazi ukukhishwa."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Ifolda engenagama"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"Kukhutshaziwe <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
-    <plurals name="badged_app_label" formatted="false" msgid="7948068486082879291">
-      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, inezaziso ezingu-<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
-      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, inezaziso ezingu-<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
+    <plurals name="dotted_app_label" formatted="false" msgid="5194538107138265416">
+      <item quantity="one"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, unezaziso ezingu-<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
+      <item quantity="other"><xliff:g id="APP_NAME_2">%1$s</xliff:g>, unezaziso ezingu-<xliff:g id="NOTIFICATION_COUNT_3">%2$d</xliff:g></item>
     </plurals>
     <string name="default_scroll_format" msgid="7475544710230993317">"Ikhasi elingu-%1$d kwangu-%2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Isikrini sasekhaya esingu-%1$d se-%2$d"</string>
@@ -83,23 +84,15 @@
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Kukhutshazwe umlawuli wakho"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Vumela ukuphendukiswa kwesikrini sasekhaya"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Uma ifoni iphendukiswa"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Amachashazi esaziso"</string>
-    <string name="icon_badging_desc_on" msgid="2627952638544674079">"Kuvuliwe"</string>
-    <string name="icon_badging_desc_off" msgid="5503319969924580241">"Kuvaliwe"</string>
+    <string name="notification_dots_title" msgid="9062440428204120317">"Amacashazi esaziso"</string>
+    <string name="notification_dots_desc_on" msgid="1679848116452218908">"Vuliwe"</string>
+    <string name="notification_dots_desc_off" msgid="1760796511504341095">"Valiwe"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Ukufinyelela izaziso kuyadingeka"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"Ukuze ubonisa amcashazi esaziso, vula izaziso zohlelo lokusebenza ze-<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Shintsha izilungiselelo"</string>
-    <string name="icon_badging_service_title" msgid="2309733118428242174">"Bonisa amacashazi esaziso"</string>
+    <string name="notification_dots_service_title" msgid="4284221181793592871">"Bonisa amacashazi esaziso"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Engeza isithonjana eskrinini sasekhaya"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Kwezinhlelo zokusebenza ezintsha"</string>
-    <string name="icon_shape_override_label" msgid="2977264953998281004">"Shintsha isimo sesithonjana"</string>
-    <string name="icon_shape_override_label_location" msgid="3841607380657692863">"kusikrini sasekhaya"</string>
-    <string name="icon_shape_system_default" msgid="1709762974822753030">"Sebenzisa okuzenzakalelayo kwesistimu"</string>
-    <string name="icon_shape_square" msgid="633575066111622774">"Isikwele"</string>
-    <string name="icon_shape_squircle" msgid="5658049910802669495">"I-Squircle"</string>
-    <string name="icon_shape_circle" msgid="6550072265930144217">"Indingiliza"</string>
-    <string name="icon_shape_teardrop" msgid="4525869388200835463">"I-Teardrop"</string>
-    <string name="icon_shape_override_progress" msgid="3461735694970239908">"Ifaka izinguquko zesimo sesithonjana"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"Akwaziwa"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Susa"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Sesha"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 956270c..53877ff 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -33,9 +33,11 @@
     <attr name="workspaceKeyShadowColor" format="color" />
     <attr name="workspaceStatusBarScrim" format="reference" />
     <attr name="widgetsTheme" format="reference" />
-    <attr name="folderBadgeColor" format="color" />
     <attr name="loadingIconColor" format="color" />
 
+    <attr name="folderDotColor" format="color" />
+    <attr name="folderIconRadius" format="float" />
+
     <!-- BubbleTextView specific attributes. -->
     <declare-styleable name="BubbleTextView">
         <attr name="layoutHorizontal" format="boolean" />
@@ -93,10 +95,8 @@
         <attr name="layout_ignoreInsets" format="boolean" />
     </declare-styleable>
 
-    <declare-styleable name="InvariantDeviceProfile">
+    <declare-styleable name="GridDisplayOption">
         <attr name="name" format="string" />
-        <attr name="minWidthDps" format="float" />
-        <attr name="minHeightDps" format="float" />
 
         <attr name="numRows" format="integer" />
         <attr name="numColumns" format="integer" />
@@ -106,13 +106,21 @@
         <!-- numHotseatIcons defaults to numColumns, if not specified -->
         <attr name="numHotseatIcons" format="integer" />
 
+        <attr name="defaultLayoutId" format="reference" />
+        <attr name="demoModeLayoutId" format="reference" />
+    </declare-styleable>
+
+    <declare-styleable name="ProfileDisplayOption">
+        <attr name="name" />
+        <attr name="minWidthDps" format="float" />
+        <attr name="minHeightDps" format="float" />
+
         <attr name="iconSize" format="float" />
         <!-- landscapeIconSize defaults to iconSize, if not specified -->
         <attr name="landscapeIconSize" format="float" />
         <attr name="iconTextSize" format="float" />
-
-        <attr name="defaultLayoutId" format="reference" />
-        <attr name="demoModeLayoutId" format="reference" />
+        <!-- If true, this display option is used to determine the default grid -->
+        <attr name="canBeDefault" format="boolean" />
     </declare-styleable>
 
     <declare-styleable name="CellLayout">
@@ -148,4 +156,9 @@
         <attr name="numMinRows" format="integer" />
         <attr name="numMinColumns" format="integer" />
     </declare-styleable>
+
+    <declare-styleable name="PreviewFragment">
+        <attr name="android:name" />
+        <attr name="android:id" />
+    </declare-styleable>
 </resources>
diff --git a/res/values/bools.xml b/res/values/bools.xml
index 53c67e2..bc2c678 100644
--- a/res/values/bools.xml
+++ b/res/values/bools.xml
@@ -17,7 +17,7 @@
 -->
 
 <resources>
-    <bool name="notification_badging_enabled">false</bool>
+    <bool name="notification_dots_enabled">false</bool>
 
     <bool name="enable_install_shortcut_api">true</bool>
 </resources>
\ No newline at end of file
diff --git a/res/values/config.xml b/res/values/config.xml
index b33cfa1..6bd01b5 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -21,25 +21,6 @@
     <!-- String representing the fragment class for settings activity.-->
     <string name="settings_fragment_name" translatable="false">com.android.launcher3.settings.SettingsActivity$LauncherSettingsFragment</string>
 
-    <!-- Values for icon shape overrides. These should correspond to entries defined
-     in icon_shape_override_paths_names -->
-    <string-array translatable="false" name="icon_shape_override_paths_values">
-        <item></item>
-        <item>M50,0L100,0 100,100 0,100 0,0z</item>
-        <item>M50,0 C10,0 0,10 0,50 0,90 10,100 50,100 90,100 100,90 100,50 100,10 90,0 50,0 Z</item>
-        <item>M50 0A50 50,0,1,1,50 100A50 50,0,1,1,50 0</item>
-        <item>M50,0A50,50,0,0 1 100,50 L100,85 A15,15,0,0 1 85,100 L50,100 A50,50,0,0 1 50,0z</item>
-    </string-array>
-
-    <string-array translatable="false" name="icon_shape_override_paths_names">
-        <!-- Option to not change the icon shape on home screen. [CHAR LIMIT=50] -->
-        <item>@string/icon_shape_system_default</item>
-        <item>@string/icon_shape_square</item>
-        <item>@string/icon_shape_squircle</item>
-        <item>@string/icon_shape_circle</item>
-        <item>@string/icon_shape_teardrop</item>
-    </string-array>
-
 <!-- DragController -->
     <item type="id" name="drag_event_parity" />
 
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 8adae36..078ce60 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -36,7 +36,7 @@
     <dimen name="dynamic_grid_hotseat_bottom_padding">2dp</dimen>
     <!-- Extra bottom padding for non-tall devices. -->
     <dimen name="dynamic_grid_hotseat_bottom_non_tall_padding">0dp</dimen>
-    <dimen name="dynamic_grid_hotseat_size">80dp</dimen>
+    <dimen name="dynamic_grid_hotseat_extra_vertical_size">34dp</dimen>
     <dimen name="dynamic_grid_hotseat_side_padding">0dp</dimen>
 
     <!-- Hotseat/all-apps scrim -->
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7e5784d..51350c0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -66,6 +66,8 @@
     <string name="all_apps_no_search_results">No apps found matching \"<xliff:g id="query" example="Android">%1$s</xliff:g>\"</string>
     <!-- Label for the button which allows the user to get app search results. [CHAR_LIMIT=50] -->
     <string name="all_apps_search_market_message">Search for more apps</string>
+    <!-- Label for an icon representing any generic app. [CHAR_LIMIT=50] -->
+    <string name="label_application">App</string>
 
     <!-- Popup items -->
     <!-- Text to display as the header above notifications. [CHAR_LIMIT=30] -->
@@ -92,9 +94,11 @@
          for accessibilty (spoken when the button gets focus). -->
     <string name="all_apps_home_button_label">Home</string>
 
-    <!-- Label for remove drop target. [CHAR_LIMIT=20] -->
+    <!-- Label for remove drop target (from the homescreen only).
+         May appear next to uninstall_drop_target_label [CHAR_LIMIT=20] -->
     <string name="remove_drop_target_label">Remove</string>
-    <!-- Label for uninstall drop target. [CHAR_LIMIT=20]-->
+    <!-- Label for uninstall drop target (from the device).
+         May appear next to remove_drop_target_label [CHAR_LIMIT=20]-->
     <string name="uninstall_drop_target_label">Uninstall</string>
     <!-- Label for app info drop target. [CHAR_LIMIT=20] -->
     <string name="app_info_drop_target_label">App info</string>
@@ -141,7 +145,7 @@
     <!-- The format string for when an app is temporarily disabled. -->
     <string name="disabled_app_label">Disabled <xliff:g id="app_name" example="Messenger">%1$s</xliff:g></string>
     <!-- The format string for when an app has a notification dot (meaning it has associated notifications). -->
-    <plurals name="badged_app_label">
+    <plurals name="dotted_app_label">
         <item quantity="one"><xliff:g id="app_name" example="Messenger">%1$s</xliff:g>, has <xliff:g id="notification_count" example="1">%2$d</xliff:g> notification</item>
         <item quantity="other"><xliff:g id="app_name" example="Messenger">%1$s</xliff:g>, has <xliff:g id="notification_count" example="3">%2$d</xliff:g> notifications</item>
     </plurals>
@@ -184,11 +188,11 @@
     <!-- Text explaining when the home screen will get rotated. [CHAR LIMIT=100] -->
     <string name="allow_rotation_desc">When phone is rotated</string>
     <!-- Title for Notification dots setting. Tapping this will link to the system Notifications settings screen where the user can turn off notification dots globally. [CHAR LIMIT=50] -->
-    <string name="icon_badging_title">Notification dots</string>
-    <!-- Text to indicate that the system icon badging setting is on [CHAR LIMIT=100] -->
-    <string name="icon_badging_desc_on">On</string>
-    <!-- Text to indicate that the system icon badging setting is off [CHAR LIMIT=100] -->
-    <string name="icon_badging_desc_off">Off</string>
+    <string name="notification_dots_title">Notification dots</string>
+    <!-- Text to indicate that the system notification dots setting is on [CHAR LIMIT=100] -->
+    <string name="notification_dots_desc_on">On</string>
+    <!-- Text to indicate that the system notification dots setting is off [CHAR LIMIT=100] -->
+    <string name="notification_dots_desc_off">Off</string>
     <!-- Title for the dialog shown when the app does not has notification access, explaining the requirement for notification access [CHAR LIMIT=50] -->
     <string name="title_missing_notification_access">Notification access needed</string>
     <!-- Message explaining to the user that the notification access is required by the app for showing 'Notification dots' [CHAR LIMIT=NONE] -->
@@ -196,31 +200,13 @@
     <!-- Button text in the confirmation dialog which would take the user to the system settings [CHAR LIMIT=50] -->
     <string name="title_change_settings">Change settings</string>
     <!-- Summary for Notification dots setting. Tapping this will link enable/disable notification dots feature on the home screen. [CHAR LIMIT=50] -->
-    <string name="icon_badging_service_title">Show notification dots</string>
+    <string name="notification_dots_service_title">Show notification dots</string>
 
     <!-- Label for the setting that allows the automatic placement of launcher shortcuts for applications and games installed on the device [CHAR LIMIT=40] -->
     <string name="auto_add_shortcuts_label">Add icon to Home screen</string>
     <!-- Text description of the setting that allows the automatic placement of launcher shortcuts for applications and games installed on the device [CHAR LIMIT=NONE] -->
     <string name="auto_add_shortcuts_description">For new apps</string>
 
-    <!-- Developer setting to change the shape of icons on home screen. [CHAR LIMIT=50] -->
-    <string name="icon_shape_override_label">Change icon shape</string>
-    <!-- Subtext explaining that the icons will only be affected on the home screen. This text follows the actual icon action: Change icon shape, on Home screen [CHAR LIMIT=100] -->
-    <string name="icon_shape_override_label_location">on Home screen</string>
-    <!-- Option to not change the icon shape on home screen and use the system default setting instead. [CHAR LIMIT=50] -->
-    <string name="icon_shape_system_default">Use system default</string>
-    <!-- Option to change the shape of the home screen icons to a square. [CHAR LIMIT=50] -->
-    <string name="icon_shape_square">Square</string>
-    <!-- Option to change the shape of the home screen icons to a squircle. This represents the name of the shape somewhere between a circle and a square. [CHAR LIMIT=50] -->
-    <string name="icon_shape_squircle">Squircle</string>
-    <!-- Option to change the shape of the home screen icons to a circle. [CHAR LIMIT=50] -->
-    <string name="icon_shape_circle">Circle</string>
-    <!-- Option to change the shape of the home screen icons to a teardrop. This represents the name of the shape similar to a circle with with the bottom right corner pushed out like a square [CHAR LIMIT=50] -->
-    <string name="icon_shape_teardrop">Teardrop</string>
-
-    <!-- Message shown in the progress dialog when the icon shape override is being applied [CHAR LIMIT=100]-->
-    <string name="icon_shape_override_progress">Applying icon shape changes</string>
-
     <!-- Label on an icon that references an uninstalled package, for which we have no information about when it might be installed. [CHAR_LIMIT=15] -->
     <string name="package_state_unknown">Unknown</string>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index e6791aa..a1ea3b4 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -42,7 +42,7 @@
         <item name="workspaceKeyShadowColor">#44000000</item>
         <item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
         <item name="widgetsTheme">@style/WidgetContainerTheme</item>
-        <item name="folderBadgeColor">?android:attr/colorPrimary</item>
+        <item name="folderDotColor">?android:attr/colorPrimary</item>
         <item name="loadingIconColor">#FFF</item>
 
         <item name="android:windowTranslucentStatus">false</item>
@@ -76,7 +76,7 @@
         <item name="popupColorSecondary">#424242</item> <!-- Gray 800 -->
         <item name="popupColorTertiary">#757575</item> <!-- Gray 600 -->
         <item name="widgetsTheme">@style/WidgetContainerTheme.Dark</item>
-        <item name="folderBadgeColor">#FF464646</item>
+        <item name="folderDotColor">#FF464646</item>
         <item name="isMainColorDark">true</item>
         <item name="loadingIconColor">#000</item>
     </style>
diff --git a/res/xml/default_workspace_3x3.xml b/res/xml/default_workspace_3x3.xml
index 8d99404..31376e1 100644
--- a/res/xml/default_workspace_3x3.xml
+++ b/res/xml/default_workspace_3x3.xml
@@ -68,21 +68,4 @@
         <favorite launcher:uri="market://details?id=com.android.launcher" />
     </resolve>
 
-    <!-- Second last row -->
-    <resolve
-        launcher:screen="0"
-        launcher:x="0"
-        launcher:y="-2" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
-        <favorite launcher:uri="http://www.example.com/" />
-    </resolve>
-
-    <resolve
-        launcher:screen="0"
-        launcher:x="2"
-        launcher:y="-2" >
-        <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
-        <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
-    </resolve>
-
 </favorites>
diff --git a/res/xml/default_workspace_4x4.xml b/res/xml/default_workspace_4x4.xml
index 979a1b4..bf3c62c 100644
--- a/res/xml/default_workspace_4x4.xml
+++ b/res/xml/default_workspace_4x4.xml
@@ -16,8 +16,48 @@
 
 <favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
 
-    <!-- Hotseat -->
-    <include launcher:workspace="@xml/dw_phone_hotseat" />
+    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+    <!-- Dialer, Messaging, Browser, Camera -->
+    <resolve
+        launcher:container="-101"
+        launcher:screen="0"
+        launcher:x="0"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+        <favorite launcher:uri="tel:123" />
+        <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="1"
+        launcher:x="1"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+        <favorite launcher:uri="sms:" />
+        <favorite launcher:uri="smsto:" />
+        <favorite launcher:uri="mms:" />
+        <favorite launcher:uri="mmsto:" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="2"
+        launcher:x="2"
+        launcher:y="0" >
+        <favorite
+            launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+        <favorite launcher:uri="http://www.example.com/" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="3"
+        launcher:x="3"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
+        <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
+    </resolve>
 
     <!-- Bottom row -->
     <resolve
diff --git a/res/xml/default_workspace_5x5.xml b/res/xml/default_workspace_5x5.xml
index f9cc0e7..ccdde2c 100644
--- a/res/xml/default_workspace_5x5.xml
+++ b/res/xml/default_workspace_5x5.xml
@@ -16,8 +16,57 @@
 
 <favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
 
-    <!-- Hotseat -->
-    <include launcher:workspace="@xml/dw_phone_hotseat" />
+    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
+    <!-- Dialer, Messaging, [Maps/Music], Browser, Camera -->
+    <resolve
+        launcher:container="-101"
+        launcher:screen="0"
+        launcher:x="0"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
+        <favorite launcher:uri="tel:123" />
+        <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="1"
+        launcher:x="1"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
+        <favorite launcher:uri="sms:" />
+        <favorite launcher:uri="smsto:" />
+        <favorite launcher:uri="mms:" />
+        <favorite launcher:uri="mmsto:" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="2"
+        launcher:x="2"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" />
+        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="3"
+        launcher:x="3"
+        launcher:y="0" >
+        <favorite
+            launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
+        <favorite launcher:uri="http://www.example.com/" />
+    </resolve>
+
+    <resolve
+        launcher:container="-101"
+        launcher:screen="4"
+        launcher:x="4"
+        launcher:y="0" >
+        <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
+        <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
+    </resolve>
 
     <!-- Bottom row -->
     <resolve
diff --git a/res/xml/default_workspace_5x6.xml b/res/xml/default_workspace_5x6.xml
deleted file mode 100644
index 8493c26..0000000
--- a/res/xml/default_workspace_5x6.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2012 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
-
-    <!-- Hotseat -->
-    <include launcher:workspace="@xml/dw_tablet_hotseat" />
-
-    <!-- Bottom row -->
-    <favorite
-        launcher:screen="0"
-        launcher:x="0"
-        launcher:y="-1"
-        launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_CONTACTS;end" />
-
-    <resolve
-        launcher:screen="0"
-        launcher:x="-1"
-        launcher:y="-1" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MARKET;end" />
-        <favorite launcher:uri="market://details?id=com.android.launcher" />
-    </resolve>
-
-</favorites>
diff --git a/res/xml/device_profiles.xml b/res/xml/device_profiles.xml
index ef6e145..88b1bc9 100644
--- a/res/xml/device_profiles.xml
+++ b/res/xml/device_profiles.xml
@@ -17,158 +17,109 @@
 
 <profiles xmlns:launcher="http://schemas.android.com/apk/res-auto" >
 
-    <profile
-        launcher:name="Super Short Stubby"
-        launcher:minWidthDps="255"
-        launcher:minHeightDps="300"
-        launcher:numRows="2"
+    <grid-option
+        launcher:name="3_by_3"
+        launcher:numRows="3"
         launcher:numColumns="3"
         launcher:numFolderRows="2"
         launcher:numFolderColumns="3"
-        launcher:iconSize="48"
-        launcher:iconTextSize="13.0"
         launcher:numHotseatIcons="3"
-        launcher:defaultLayoutId="@xml/default_workspace_3x3"
-        />
+        launcher:defaultLayoutId="@xml/default_workspace_3x3" >
 
-    <profile
-        launcher:name="Shorter Stubby"
-        launcher:minWidthDps="255"
-        launcher:minHeightDps="400"
-        launcher:numRows="3"
-        launcher:numColumns="3"
-        launcher:numFolderRows="3"
-        launcher:numFolderColumns="3"
-        launcher:iconSize="48"
-        launcher:iconTextSize="13.0"
-        launcher:numHotseatIcons="3"
-        launcher:defaultLayoutId="@xml/default_workspace_3x3"
-        />
+        <display-option
+            launcher:name="Super Short Stubby"
+            launcher:minWidthDps="255"
+            launcher:minHeightDps="300"
+            launcher:iconSize="48"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
 
-    <profile
-        launcher:name="Short Stubby"
-        launcher:minWidthDps="275"
-        launcher:minHeightDps="420"
-        launcher:numRows="3"
+        <display-option
+            launcher:name="Shorter Stubby"
+            launcher:minWidthDps="255"
+            launcher:minHeightDps="400"
+            launcher:iconSize="48"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
+
+    </grid-option>
+
+    <grid-option
+        launcher:name="4_by_4"
+        launcher:numRows="4"
         launcher:numColumns="4"
         launcher:numFolderRows="3"
         launcher:numFolderColumns="4"
-        launcher:iconSize="48"
-        launcher:iconTextSize="13.0"
-        launcher:numHotseatIcons="5"
-        launcher:defaultLayoutId="@xml/default_workspace_4x4"
-        />
+        launcher:numHotseatIcons="4"
+        launcher:defaultLayoutId="@xml/default_workspace_4x4" >
 
-    <profile
-        launcher:name="Stubby"
-        launcher:minWidthDps="255"
-        launcher:minHeightDps="450"
-        launcher:numRows="3"
-        launcher:numColumns="4"
-        launcher:numFolderRows="3"
-        launcher:numFolderColumns="4"
-        launcher:iconSize="48"
-        launcher:iconTextSize="13.0"
-        launcher:numHotseatIcons="5"
-        launcher:defaultLayoutId="@xml/default_workspace_4x4"
-        />
+        <display-option
+            launcher:name="Short Stubby"
+            launcher:minWidthDps="275"
+            launcher:minHeightDps="420"
+            launcher:iconSize="48"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
 
-    <profile
-        launcher:name="Nexus S"
-        launcher:minWidthDps="296"
-        launcher:minHeightDps="491.33"
-        launcher:numRows="4"
-        launcher:numColumns="4"
-        launcher:numFolderRows="4"
-        launcher:numFolderColumns="4"
-        launcher:iconSize="48"
-        launcher:iconTextSize="13.0"
-        launcher:numHotseatIcons="5"
-        launcher:defaultLayoutId="@xml/default_workspace_4x4"
-        />
+        <display-option
+            launcher:name="Stubby"
+            launcher:minWidthDps="255"
+            launcher:minHeightDps="450"
+            launcher:iconSize="48"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
 
-    <profile
-        launcher:name="Nexus 4"
-        launcher:minWidthDps="359"
-        launcher:minHeightDps="567"
-        launcher:numRows="4"
-        launcher:numColumns="4"
-        launcher:numFolderRows="4"
-        launcher:numFolderColumns="4"
-        launcher:iconSize="54"
-        launcher:iconTextSize="13.0"
-        launcher:numHotseatIcons="5"
-        launcher:defaultLayoutId="@xml/default_workspace_4x4"
-        />
+        <display-option
+            launcher:name="Nexus S"
+            launcher:minWidthDps="296"
+            launcher:minHeightDps="491.33"
+            launcher:iconSize="48"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
 
-    <profile
-        launcher:name="Nexus 5"
-        launcher:minWidthDps="335"
-        launcher:minHeightDps="567"
-        launcher:numRows="4"
-        launcher:numColumns="4"
-        launcher:numFolderRows="4"
-        launcher:numFolderColumns="4"
-        launcher:iconSize="54"
-        launcher:iconTextSize="13.0"
-        launcher:numHotseatIcons="5"
-        launcher:defaultLayoutId="@xml/default_workspace_4x4"
-        />
+        <display-option
+            launcher:name="Nexus 4"
+            launcher:minWidthDps="359"
+            launcher:minHeightDps="567"
+            launcher:iconSize="54"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
 
-    <profile
-        launcher:name="Large Phone"
-        launcher:minWidthDps="406"
-        launcher:minHeightDps="694"
+        <display-option
+            launcher:name="Nexus 5"
+            launcher:minWidthDps="335"
+            launcher:minHeightDps="567"
+            launcher:iconSize="54"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
+
+    </grid-option>
+
+    <grid-option
+        launcher:name="5_by_5"
         launcher:numRows="5"
         launcher:numColumns="5"
         launcher:numFolderRows="4"
         launcher:numFolderColumns="4"
-        launcher:iconSize="56"
-        launcher:iconTextSize="14.4"
         launcher:numHotseatIcons="5"
-        launcher:defaultLayoutId="@xml/default_workspace_5x5"
-        />
+        launcher:defaultLayoutId="@xml/default_workspace_5x5" >
 
-    <profile
-        launcher:name="Nexus 7"
-        launcher:minWidthDps="575"
-        launcher:minHeightDps="904"
-        launcher:numRows="6"
-        launcher:numColumns="6"
-        launcher:numFolderRows="4"
-        launcher:numFolderColumns="5"
-        launcher:iconSize="64"
-        launcher:iconTextSize="14.4"
-        launcher:numHotseatIcons="6"
-        launcher:defaultLayoutId="@xml/default_workspace_5x6"
-        />
+        <display-option
+            launcher:name="Large Phone"
+            launcher:minWidthDps="406"
+            launcher:minHeightDps="694"
+            launcher:iconSize="56"
+            launcher:iconTextSize="14.4"
+            launcher:canBeDefault="true" />
 
-    <profile
-        launcher:name="Nexus 10"
-        launcher:minWidthDps="727"
-        launcher:minHeightDps="1207"
-        launcher:numRows="6"
-        launcher:numColumns="7"
-        launcher:numFolderRows="4"
-        launcher:numFolderColumns="5"
-        launcher:iconSize="76"
-        launcher:iconTextSize="14.4"
-        launcher:numHotseatIcons="7"
-        launcher:defaultLayoutId="@xml/default_workspace_5x6"
-        />
+        <display-option
+            launcher:name="Shorter Stubby"
+            launcher:minWidthDps="255"
+            launcher:minHeightDps="400"
+            launcher:iconSize="48"
+            launcher:iconTextSize="13.0"
+            launcher:canBeDefault="true" />
 
-    <profile
-        launcher:name="20-inch Tablet"
-        launcher:minWidthDps="1527"
-        launcher:minHeightDps="2527"
-        launcher:numRows="7"
-        launcher:numColumns="7"
-        launcher:numFolderRows="6"
-        launcher:numFolderColumns="6"
-        launcher:iconSize="100"
-        launcher:iconTextSize="20.0"
-        launcher:numHotseatIcons="7"
-        launcher:defaultLayoutId="@xml/default_workspace_5x6"
-        />
+    </grid-option>
 
 </profiles>
\ No newline at end of file
diff --git a/res/xml/dw_phone_hotseat.xml b/res/xml/dw_phone_hotseat.xml
deleted file mode 100644
index c691ebc..0000000
--- a/res/xml/dw_phone_hotseat.xml
+++ /dev/null
@@ -1,70 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
-    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
-    <!-- Dialer, Messaging, [Maps/Music], Browser, Camera -->
-    <resolve
-        launcher:container="-101"
-        launcher:screen="0"
-        launcher:x="0"
-        launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.DIAL;end" />
-        <favorite launcher:uri="tel:123" />
-        <favorite launcher:uri="#Intent;action=android.intent.action.CALL_BUTTON;end" />
-    </resolve>
-
-    <resolve
-        launcher:container="-101"
-        launcher:screen="1"
-        launcher:x="1"
-        launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
-        <favorite launcher:uri="sms:" />
-        <favorite launcher:uri="smsto:" />
-        <favorite launcher:uri="mms:" />
-        <favorite launcher:uri="mmsto:" />
-    </resolve>
-
-    <resolve
-        launcher:container="-101"
-        launcher:screen="2"
-        launcher:x="2"
-        launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" />
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" />
-    </resolve>
-
-    <resolve
-        launcher:container="-101"
-        launcher:screen="3"
-        launcher:x="3"
-        launcher:y="0" >
-        <favorite
-            launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
-        <favorite launcher:uri="http://www.example.com/" />
-    </resolve>
-
-    <resolve
-        launcher:container="-101"
-        launcher:screen="4"
-        launcher:x="4"
-        launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
-        <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
-    </resolve>
-
-</favorites>
diff --git a/res/xml/dw_tablet_hotseat.xml b/res/xml/dw_tablet_hotseat.xml
deleted file mode 100644
index 6fe7f93..0000000
--- a/res/xml/dw_tablet_hotseat.xml
+++ /dev/null
@@ -1,84 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
-    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
-    <!-- Messaging, Email, Browser, Maps, Music, Gallery, Camera -->
-    <resolve
-        launcher:container="-101"
-        launcher:screen="0"
-        launcher:x="0"
-        launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MESSAGING;end" />
-        <favorite launcher:uri="sms:" />
-        <favorite launcher:uri="smsto:" />
-        <favorite launcher:uri="mms:" />
-        <favorite launcher:uri="mmsto:" />
-    </resolve>
-
-    <resolve
-        launcher:container="-101"
-        launcher:screen="1"
-        launcher:x="1"
-        launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_EMAIL;end" />
-        <favorite launcher:uri="mailto:" />
-    </resolve>
-
-    <resolve
-        launcher:container="-101"
-        launcher:screen="2"
-        launcher:x="2"
-        launcher:y="0" >
-        <favorite
-            launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_BROWSER;end" />
-        <favorite launcher:uri="http://www.example.com/" />
-    </resolve>
-
-    <resolve
-        launcher:container="-101"
-        launcher:screen="3"
-        launcher:x="3"
-        launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MAPS;end" />
-    </resolve>
-
-    <favorite
-        launcher:container="-101"
-        launcher:screen="4"
-        launcher:x="4"
-        launcher:y="0"
-        launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_MUSIC;end" />
-
-    <resolve
-        launcher:container="-101"
-        launcher:screen="5"
-        launcher:x="5"
-        launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.intent.action.MAIN;category=android.intent.category.APP_GALLERY;end" />
-        <favorite launcher:uri="#Intent;type=images/*;end" />
-    </resolve>
-
-    <resolve
-        launcher:container="-101"
-        launcher:screen="6"
-        launcher:x="6"
-        launcher:y="0" >
-        <favorite launcher:uri="#Intent;action=android.media.action.STILL_IMAGE_CAMERA;end" />
-        <favorite launcher:uri="#Intent;action=android.intent.action.CAMERA_BUTTON;end" />
-    </resolve>
-
-</favorites>
diff --git a/res/xml/folder_shapes.xml b/res/xml/folder_shapes.xml
new file mode 100644
index 0000000..e60d333
--- /dev/null
+++ b/res/xml/folder_shapes.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<shapes xmlns:launcher="http://schemas.android.com/apk/res-auto" >
+
+    <Circle launcher:folderIconRadius="1" />
+
+    <!-- Default icon for AOSP -->
+    <RoundedSquare launcher:folderIconRadius="0.16" />
+
+    <!-- Rounded icon from RRO -->
+    <RoundedSquare launcher:folderIconRadius="0.6" />
+
+    <!-- Square icon -->
+    <RoundedSquare launcher:folderIconRadius="0" />
+
+    <TearDrop launcher:folderIconRadius="0.3" />
+    <Squircle launcher:folderIconRadius="0.2" />
+
+</shapes>
\ No newline at end of file
diff --git a/res/xml/launcher_preferences.xml b/res/xml/launcher_preferences.xml
index 2c86f8e..7e72208 100644
--- a/res/xml/launcher_preferences.xml
+++ b/res/xml/launcher_preferences.xml
@@ -17,18 +17,18 @@
 <androidx.preference.PreferenceScreen
     xmlns:android="http://schemas.android.com/apk/res/android">
 
-    <com.android.launcher3.settings.IconBadgingPreference
+    <com.android.launcher3.settings.NotificationDotsPreference
         android:key="pref_icon_badging"
-        android:title="@string/icon_badging_title"
+        android:title="@string/notification_dots_title"
         android:persistent="false"
         android:widgetLayout="@layout/notification_pref_warning" >
         <intent android:action="android.settings.NOTIFICATION_SETTINGS">
-            <!-- This extra highlights the "Allow icon badges" field in Notification settings -->
+            <!-- This extra highlights the "Allow notification dots" field in Notification settings -->
             <extra
                 android:name=":settings:fragment_args_key"
                 android:value="notification_badging" />
         </intent>
-    </com.android.launcher3.settings.IconBadgingPreference>
+    </com.android.launcher3.settings.NotificationDotsPreference>
 
     <SwitchPreference
         android:key="pref_add_icon_to_home"
@@ -44,15 +44,6 @@
         android:defaultValue="@bool/allow_rotation"
         android:persistent="true" />
 
-    <ListPreference
-        android:key="pref_override_icon_shape"
-        android:title="@string/icon_shape_override_label"
-        android:summary="%s"
-        android:entries="@array/icon_shape_override_paths_names"
-        android:entryValues="@array/icon_shape_override_paths_values"
-        android:defaultValue=""
-        android:persistent="false" />
-
     <androidx.preference.PreferenceScreen
         android:key="pref_developer_options"
         android:persistent="false"
diff --git a/robolectric_tests/Android.mk b/robolectric_tests/Android.mk
index 5011764..a57b97a 100644
--- a/robolectric_tests/Android.mk
+++ b/robolectric_tests/Android.mk
@@ -29,6 +29,8 @@
 LOCAL_JAVA_LIBRARIES := \
     platform-robolectric-3.6.1-prebuilt
 
+LOCAL_JAVA_RESOURCE_DIRS := resources config
+
 LOCAL_INSTRUMENTATION_FOR := Launcher3
 LOCAL_MODULE_TAGS := optional
 
diff --git a/robolectric_tests/config/robolectric.properties b/robolectric_tests/config/robolectric.properties
new file mode 100644
index 0000000..e0d6e53
--- /dev/null
+++ b/robolectric_tests/config/robolectric.properties
@@ -0,0 +1,2 @@
+manifest=packages/apps/Launcher3/AndroidManifest.xml
+sdk=26
diff --git a/tests/res/raw/cache_data_updated_task_data.txt b/robolectric_tests/resources/cache_data_updated_task_data.txt
similarity index 100%
rename from tests/res/raw/cache_data_updated_task_data.txt
rename to robolectric_tests/resources/cache_data_updated_task_data.txt
diff --git a/tests/res/raw/db_schema_v10.json b/robolectric_tests/resources/db_schema_v10.json
similarity index 100%
rename from tests/res/raw/db_schema_v10.json
rename to robolectric_tests/resources/db_schema_v10.json
diff --git a/tests/res/raw/package_install_state_change_task_data.txt b/robolectric_tests/resources/package_install_state_change_task_data.txt
similarity index 100%
rename from tests/res/raw/package_install_state_change_task_data.txt
rename to robolectric_tests/resources/package_install_state_change_task_data.txt
diff --git a/robolectric_tests/src/com/android/launcher3/config/FlagOverrideRule.java b/robolectric_tests/src/com/android/launcher3/config/FlagOverrideRule.java
new file mode 100644
index 0000000..92bcc64
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/config/FlagOverrideRule.java
@@ -0,0 +1,116 @@
+package com.android.launcher3.config;
+
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.robolectric.RuntimeEnvironment;
+
+import java.lang.annotation.Annotation;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Test rule that makes overriding flags in Robolectric tests easier. This rule clears all flags
+ * before and after your test, avoiding one test method affecting subsequent methods.
+ *
+ * <p>Usage:
+ * <pre>
+ * {@literal @}Rule public final FlagOverrideRule flags = new FlagOverrideRule();
+ *
+ * {@literal @}FlagOverride(flag = "FOO", value=true)
+ * {@literal @}Test public void myTest() {
+ *     ...
+ * }
+ * </pre>
+ */
+public final class FlagOverrideRule implements TestRule {
+
+    /**
+     * Container annotation for handling multiple {@link FlagOverride} annotations.
+     * <p>
+     * <p>Don't use this directly, use repeated {@link FlagOverride} annotations instead.
+     */
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.METHOD})
+    public @interface FlagOverrides {
+        FlagOverride[] value();
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.METHOD})
+    @Repeatable(FlagOverrides.class)
+    public @interface FlagOverride {
+        String key();
+
+        boolean value();
+    }
+
+    private boolean ruleInProgress;
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new Statement() {
+            @Override
+            public void evaluate() throws Throwable {
+                FeatureFlags.initialize(RuntimeEnvironment.application.getApplicationContext());
+                ruleInProgress = true;
+                try {
+                    clearOverrides();
+                    applyAnnotationOverrides(description);
+                    base.evaluate();
+                } finally {
+                    ruleInProgress = false;
+                    clearOverrides();
+                }
+            }
+        };
+    }
+
+    private void override(BaseFlags.TogglableFlag flag, boolean newValue) {
+        if (!ruleInProgress) {
+            throw new IllegalStateException(
+                    "Rule isn't in progress. Did you remember to mark it with @Rule?");
+        }
+        flag.setForTests(newValue);
+    }
+
+    private void applyAnnotationOverrides(Description description) {
+        for (Annotation annotation : description.getAnnotations()) {
+            if (annotation.annotationType() == FlagOverride.class) {
+                applyAnnotation((FlagOverride) annotation);
+            } else if (annotation.annotationType() == FlagOverrides.class) {
+                // Note: this branch is hit if the annotation is repeated
+                for (FlagOverride flagOverride : ((FlagOverrides) annotation).value()) {
+                    applyAnnotation(flagOverride);
+                }
+            }
+        }
+    }
+
+    private void applyAnnotation(FlagOverride flagOverride) {
+        boolean found = false;
+        for (BaseFlags.TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
+            if (flag.getKey().equals(flagOverride.key())) {
+                override(flag, flagOverride.value());
+                found = true;
+                break;
+            }
+        }
+        if (!found) {
+            throw new IllegalStateException("Flag " + flagOverride.key() + " not found");
+        }
+    }
+
+    /**
+     * Resets all flags to their default values.
+     */
+    private void clearOverrides() {
+        for (BaseFlags.TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
+            flag.setForTests(flag.getDefaultValue());
+        }
+    }
+}
diff --git a/robolectric_tests/src/com/android/launcher3/config/FlagOverrideSampleTest.java b/robolectric_tests/src/com/android/launcher3/config/FlagOverrideSampleTest.java
new file mode 100644
index 0000000..c5a0820
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/config/FlagOverrideSampleTest.java
@@ -0,0 +1,38 @@
+package com.android.launcher3.config;
+
+import com.android.launcher3.config.FlagOverrideRule.FlagOverride;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Sample Robolectric test that demonstrates flag-overriding.
+ */
+@RunWith(RobolectricTestRunner.class)
+public class FlagOverrideSampleTest {
+
+    // Check out https://junit.org/junit4/javadoc/4.12/org/junit/Rule.html for more information
+    // on @Rules.
+    @Rule
+    public final FlagOverrideRule flags = new FlagOverrideRule();
+
+    @FlagOverride(key = "EXAMPLE_FLAG", value = true)
+    @FlagOverride(key = "QUICK_SWITCH", value = false)
+    @Test
+    public void withFlagOn() {
+        assertTrue(FeatureFlags.EXAMPLE_FLAG.get());
+        assertFalse(FeatureFlags.QUICK_SWITCH.get());
+    }
+
+
+    @FlagOverride(key = "EXAMPLE_FLAG", value = false)
+    @Test
+    public void withFlagOff() {
+        assertFalse(FeatureFlags.EXAMPLE_FLAG.get());
+    }
+}
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
similarity index 80%
rename from tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
rename to robolectric_tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
index 6673ba9..4f49817 100644
--- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
@@ -15,13 +15,12 @@
 import android.net.Uri;
 import android.util.Pair;
 
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.util.ContentWriter;
 import com.android.launcher3.util.GridOccupancy;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSparseArrayMap;
@@ -30,15 +29,17 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.robolectric.RobolectricTestRunner;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 
 /**
  * Tests for {@link AddWorkspaceItemsTask}
  */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
 public class AddWorkspaceItemsTaskTest extends BaseModelUpdateTaskTestCase {
 
     private final ComponentName mComponent1 = new ComponentName("a", "b");
@@ -63,15 +64,11 @@
         for (ItemInfo item : items) {
             list.add(Pair.create(item, null));
         }
-        return new AddWorkspaceItemsTask(list) {
-
-            @Override
-            protected void updateScreens(Context context, IntArray workspaceScreens) { }
-        };
+        return new AddWorkspaceItemsTask(list);
     }
 
     @Test
-    public void testFindSpaceForItem_prefers_second() {
+    public void testFindSpaceForItem_prefers_second() throws Exception {
         // First screen has only one hole of size 1
         int nextId = setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
 
@@ -96,7 +93,6 @@
     public void testFindSpaceForItem_adds_new_screen() throws Exception {
         // First screen has 2 holes of sizes 3x2 and 2x3
         setupWorkspaceWithHoles(1, 1, new Rect(2, 0, 5, 2), new Rect(0, 2, 2, 5));
-        commitScreensToDb();
 
         IntArray oldScreens = existingScreens.clone();
         int[] spaceFound = newTask()
@@ -112,7 +108,6 @@
 
         // Setup a screen with a hole
         setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
-        commitScreensToDb();
 
         // Nothing was added
         assertTrue(executeTaskForTest(newTask(info)).isEmpty());
@@ -128,7 +123,6 @@
 
         // Setup a screen with a hole
         setupWorkspaceWithHoles(1, 1, new Rect(2, 2, 3, 3));
-        commitScreensToDb();
 
         executeTaskForTest(newTask(info, info2)).get(0).run();
         ArgumentCaptor<ArrayList> notAnimated = ArgumentCaptor.forClass(ArrayList.class);
@@ -144,7 +138,7 @@
         assertTrue(animated.getValue().contains(info2));
     }
 
-    private int setupWorkspaceWithHoles(int startId, int screenId, Rect... holes) {
+    private int setupWorkspaceWithHoles(int startId, int screenId, Rect... holes) throws Exception {
         GridOccupancy occupancy = new GridOccupancy(idp.numColumns, idp.numRows);
         occupancy.markCells(0, 0, idp.numColumns, idp.numRows, true);
         for (Rect r : holes) {
@@ -154,6 +148,7 @@
         existingScreens.add(screenId);
         screenOccupancy.append(screenId, occupancy);
 
+        ExecutorService executor = Executors.newSingleThreadExecutor();
         for (int x = 0; x < idp.numColumns; x++) {
             for (int y = 0; y < idp.numRows; y++) {
                 if (!occupancy.cells[x][y]) {
@@ -168,27 +163,19 @@
                 info.cellY = y;
                 info.container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
                 bgDataModel.addItem(targetContext, info, false);
+
+                executor.execute(() -> {
+                    ContentWriter writer = new ContentWriter(targetContext);
+                    info.writeToValues(writer);
+                    writer.put(Favorites._ID, info.id);
+                    targetContext.getContentResolver().insert(Favorites.CONTENT_URI,
+                            writer.getValues(targetContext));
+                });
             }
         }
+
+        executor.submit(() -> null).get();
+        executor.shutdown();
         return startId;
     }
-
-    private void commitScreensToDb() throws Exception {
-        LauncherSettings.Settings.call(mProviderRule.getResolver(),
-                LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
-
-        Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
-        ArrayList<ContentProviderOperation> ops = new ArrayList<>();
-        // Clear the table
-        ops.add(ContentProviderOperation.newDelete(uri).build());
-        int count = existingScreens.size();
-        for (int i = 0; i < count; i++) {
-            ContentValues v = new ContentValues();
-            int screenId = existingScreens.get(i);
-            v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
-            v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
-            ops.add(ContentProviderOperation.newInsert(uri).withValues(v).build());
-        }
-        mProviderRule.getResolver().applyBatch(LauncherProvider.AUTHORITY, ops);
-    }
 }
diff --git a/robolectric_tests/src/com/android/launcher3/model/BaseGridChangesTestCase.java b/robolectric_tests/src/com/android/launcher3/model/BaseGridChangesTestCase.java
new file mode 100644
index 0000000..07834fc
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/model/BaseGridChangesTestCase.java
@@ -0,0 +1,121 @@
+package com.android.launcher3.model;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.sqlite.SQLiteDatabase;
+
+import com.android.launcher3.LauncherProvider;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.util.TestLauncherProvider;
+
+import org.junit.Before;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowContentResolver;
+import org.robolectric.shadows.ShadowLog;
+
+public abstract class BaseGridChangesTestCase {
+
+
+    public static final int DESKTOP = LauncherSettings.Favorites.CONTAINER_DESKTOP;
+    public static final int HOTSEAT = LauncherSettings.Favorites.CONTAINER_HOTSEAT;
+
+    public static final int APP_ICON = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+    public static final int SHORTCUT = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
+    public static final int NO__ICON = -1;
+
+    public static final String TEST_PACKAGE = "com.android.launcher3.validpackage";
+
+    public Context mContext;
+    public TestLauncherProvider mProvider;
+    public SQLiteDatabase mDb;
+
+    @Before
+    public void setUpBaseCase() {
+        ShadowLog.stream = System.out;
+
+        mContext = RuntimeEnvironment.application;
+        mProvider = Robolectric.setupContentProvider(TestLauncherProvider.class);
+        ShadowContentResolver.registerProviderInternal(LauncherProvider.AUTHORITY, mProvider);
+        mDb = mProvider.getDb();
+    }
+
+    /**
+     * Adds a dummy item in the DB.
+     * @param type {@link #APP_ICON} or {@link #SHORTCUT} or >= 2 for
+     *             folder (where the type represents the number of items in the folder).
+     */
+    public int addItem(int type, int screen, int container, int x, int y) {
+        int id = LauncherSettings.Settings.call(mContext.getContentResolver(),
+                LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
+                .getInt(LauncherSettings.Settings.EXTRA_VALUE);
+
+        ContentValues values = new ContentValues();
+        values.put(LauncherSettings.Favorites._ID, id);
+        values.put(LauncherSettings.Favorites.CONTAINER, container);
+        values.put(LauncherSettings.Favorites.SCREEN, screen);
+        values.put(LauncherSettings.Favorites.CELLX, x);
+        values.put(LauncherSettings.Favorites.CELLY, y);
+        values.put(LauncherSettings.Favorites.SPANX, 1);
+        values.put(LauncherSettings.Favorites.SPANY, 1);
+
+        if (type == APP_ICON || type == SHORTCUT) {
+            values.put(LauncherSettings.Favorites.ITEM_TYPE, type);
+            values.put(LauncherSettings.Favorites.INTENT,
+                    new Intent(Intent.ACTION_MAIN).setPackage(TEST_PACKAGE).toUri(0));
+        } else {
+            values.put(LauncherSettings.Favorites.ITEM_TYPE,
+                    LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
+            // Add folder items.
+            for (int i = 0; i < type; i++) {
+                addItem(APP_ICON, 0, id, 0, 0);
+            }
+        }
+
+        mContext.getContentResolver().insert(LauncherSettings.Favorites.CONTENT_URI, values);
+        return id;
+    }
+
+    public int[][][] createGrid(int[][][] typeArray) {
+        return createGrid(typeArray, 1);
+    }
+
+    /**
+     * Initializes the DB with dummy elements to represent the provided grid structure.
+     * @param typeArray A 3d array of item types. {@see #addItem(int, long, long, int, int)} for
+     *                  type definitions. The first dimension represents the screens and the next
+     *                  two represent the workspace grid.
+     * @param startScreen First screen id from where the icons will be added.
+     * @return the same grid representation where each entry is the corresponding item id.
+     */
+    public int[][][] createGrid(int[][][] typeArray, int startScreen) {
+        LauncherSettings.Settings.call(mContext.getContentResolver(),
+                LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
+        int[][][] ids = new int[typeArray.length][][];
+
+        for (int i = 0; i < typeArray.length; i++) {
+            // Add screen to DB
+            int screenId = startScreen + i;
+
+            // Keep the screen id counter up to date
+            LauncherSettings.Settings.call(mContext.getContentResolver(),
+                    LauncherSettings.Settings.METHOD_NEW_SCREEN_ID);
+
+            ids[i] = new int[typeArray[i].length][];
+            for (int y = 0; y < typeArray[i].length; y++) {
+                ids[i][y] = new int[typeArray[i][y].length];
+                for (int x = 0; x < typeArray[i][y].length; x++) {
+                    if (typeArray[i][y][x] < 0) {
+                        // Empty cell
+                        ids[i][y][x] = -1;
+                    } else {
+                        ids[i][y][x] = addItem(typeArray[i][y][x], screenId, DESKTOP, x, y);
+                    }
+                }
+            }
+        }
+
+        return ids;
+    }
+}
diff --git a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java b/robolectric_tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
similarity index 86%
rename from tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
rename to robolectric_tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
index 8503547..92d065e 100644
--- a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
+++ b/robolectric_tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
@@ -7,24 +7,17 @@
 import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
-import android.content.ContentResolver;
 import android.content.Context;
-import android.content.ContextWrapper;
 import android.content.Intent;
-import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
 import android.graphics.Color;
 import android.os.Process;
 import android.os.UserHandle;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.rule.provider.ProviderTestRule;
 
 import com.android.launcher3.AllAppsList;
 import com.android.launcher3.AppFilter;
 import com.android.launcher3.AppInfo;
-import com.android.launcher3.icons.CachingLogic;
-import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppState;
@@ -33,13 +26,18 @@
 import com.android.launcher3.LauncherModel.ModelUpdateTask;
 import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.icons.cache.CachingLogic;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.TestLauncherProvider;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.mockito.ArgumentCaptor;
+import org.robolectric.Robolectric;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.shadows.ShadowContentResolver;
+import org.robolectric.shadows.ShadowLog;
 
 import java.io.BufferedReader;
 import java.io.InputStreamReader;
@@ -55,12 +53,8 @@
  */
 public class BaseModelUpdateTaskTestCase {
 
-    @Rule
-    public ProviderTestRule mProviderRule =
-            new ProviderTestRule.Builder(TestLauncherProvider.class, LauncherProvider.AUTHORITY)
-                    .build();
-
     public final HashMap<Class, HashMap<String, Field>> fieldCache = new HashMap<>();
+    private TestLauncherProvider mProvider;
 
     public Context targetContext;
     public UserHandle myUser;
@@ -77,6 +71,11 @@
 
     @Before
     public void setUp() throws Exception {
+        ShadowLog.stream = System.out;
+
+        mProvider = Robolectric.setupContentProvider(TestLauncherProvider.class);
+        ShadowContentResolver.registerProviderInternal(LauncherProvider.AUTHORITY, mProvider);
+
         callbacks = mock(Callbacks.class);
         appState = mock(LauncherAppState.class);
         model = mock(LauncherModel.class);
@@ -89,12 +88,8 @@
         myUser = Process.myUserHandle();
 
         bgDataModel = new BgDataModel();
-        targetContext = new ContextWrapper(InstrumentationRegistry.getTargetContext()) {
-            @Override
-            public ContentResolver getContentResolver() {
-                return mProviderRule.getResolver();
-            }
-        };
+        targetContext = RuntimeEnvironment.application;
+
         idp = new InvariantDeviceProfile();
         iconCache = new MyIconCache(targetContext, idp);
 
@@ -103,7 +98,6 @@
         when(appState.getIconCache()).thenReturn(iconCache);
         when(appState.getInvariantDeviceProfile()).thenReturn(idp);
         when(appState.getContext()).thenReturn(targetContext);
-
     }
 
     /**
@@ -126,11 +120,8 @@
      * Initializes mock data for the test.
      */
     public void initializeData(String resourceName) throws Exception {
-        Context myContext = InstrumentationRegistry.getContext();
-        Resources res = myContext.getResources();
-        int id = res.getIdentifier(resourceName, "raw", myContext.getPackageName());
-        try (BufferedReader reader =
-                     new BufferedReader(new InputStreamReader(res.openRawResource(id)))) {
+        try (BufferedReader reader = new BufferedReader(new InputStreamReader(
+                this.getClass().getResourceAsStream(resourceName)))) {
             String line;
             HashMap<String, Class> classMap = new HashMap<>();
             while((line = reader.readLine()) != null) {
@@ -227,10 +218,5 @@
         public Bitmap newIcon() {
             return Bitmap.createBitmap(1, 1, Config.ARGB_8888);
         }
-
-        @Override
-        protected BitmapInfo makeDefaultIcon(UserHandle user) {
-            return BitmapInfo.fromBitmap(newIcon());
-        }
     }
 }
diff --git a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
similarity index 90%
rename from tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
rename to robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
index 5fe9018..2334993 100644
--- a/tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/CacheDataUpdatedTaskTest.java
@@ -6,16 +6,15 @@
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertNull;
 
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.ShortcutInfo;
 
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
 
 import java.util.Arrays;
 import java.util.HashSet;
@@ -23,15 +22,14 @@
 /**
  * Tests for {@link CacheDataUpdatedTask}
  */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
 public class CacheDataUpdatedTaskTest extends BaseModelUpdateTaskTestCase {
 
     private static final String NEW_LABEL_PREFIX = "new-label-";
 
     @Before
     public void initData() throws Exception {
-        initializeData("cache_data_updated_task_data");
+        initializeData("/cache_data_updated_task_data.txt");
         // Add dummy entries in the cache to simulate update
         for (ItemInfo info : bgDataModel.itemsIdMap) {
             iconCache.addCache(info.getTargetComponent(), NEW_LABEL_PREFIX + info.id);
@@ -43,6 +41,7 @@
     }
 
     @Test
+    @Ignore("This test fails with resource errors")
     public void testCacheUpdate_update_apps() throws Exception {
         // Clear all icons from apps list so that its easy to check what was updated
         for (AppInfo info : allAppsList.data) {
@@ -67,6 +66,7 @@
     }
 
     @Test
+    @Ignore("This test fails with resource errors")
     public void testSessionUpdate_ignores_normal_apps() throws Exception {
         executeTaskForTest(newTask(CacheDataUpdatedTask.OP_SESSION_UPDATE, "app1"));
 
@@ -75,6 +75,7 @@
     }
 
     @Test
+    @Ignore("This test fails with resource errors")
     public void testSessionUpdate_updates_pending_apps() throws Exception {
         executeTaskForTest(newTask(CacheDataUpdatedTask.OP_SESSION_UPDATE, "app3"));
 
diff --git a/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java b/robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
similarity index 81%
rename from tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
rename to robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
index 0903ddc..a46617e 100644
--- a/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
@@ -20,14 +20,17 @@
 import static junit.framework.Assert.assertNotSame;
 import static junit.framework.Assert.assertTrue;
 
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
 import android.content.ContentValues;
 import android.content.Context;
+import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteOpenHelper;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
 
 import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.LauncherProvider.DatabaseHelper;
@@ -37,14 +40,15 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.RuntimeEnvironment;
 
 import java.io.File;
 
 /**
  * Tests for {@link DbDowngradeHelper}
  */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
 public class DbDowngradeHelperTest {
 
     private static final String SCHEMA_FILE = "test_schema.json";
@@ -56,35 +60,47 @@
 
     @Before
     public void setup() {
-        mContext = InstrumentationRegistry.getTargetContext();
+        mContext = RuntimeEnvironment.application;
         mSchemaFile = mContext.getFileStreamPath(SCHEMA_FILE);
         mDbFile = mContext.getDatabasePath(DB_FILE);
     }
 
     @Test
+    public void testDowngradeSchemaMatchesVersion() throws Exception {
+        mSchemaFile.delete();
+        assertFalse(mSchemaFile.exists());
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 0, mContext);
+        assertEquals(LauncherProvider.SCHEMA_VERSION, DbDowngradeHelper.parse(mSchemaFile).version);
+    }
+
+    @Test
     public void testUpdateSchemaFile() throws Exception {
-        Context myContext = InstrumentationRegistry.getContext();
-        int testResId = myContext.getResources().getIdentifier(
-                "db_schema_v10", "raw", myContext.getPackageName());
+        // Setup mock resources
+        Resources res = spy(mContext.getResources());
+        doAnswer(i ->this.getClass().getResourceAsStream("/db_schema_v10.json"))
+                .when(res).openRawResource(eq(R.raw.downgrade_schema));
+        Context context = spy(mContext);
+        when(context.getResources()).thenReturn(res);
+
         mSchemaFile.delete();
         assertFalse(mSchemaFile.exists());
 
-        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, myContext, testResId);
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, context);
         assertTrue(mSchemaFile.exists());
         assertEquals(10, DbDowngradeHelper.parse(mSchemaFile).version);
 
         // Schema is updated on version upgrade
         assertTrue(mSchemaFile.setLastModified(0));
-        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 11, myContext, testResId);
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 11, context);
         assertNotSame(0, mSchemaFile.lastModified());
 
         // Schema is not updated when version is same
         assertTrue(mSchemaFile.setLastModified(0));
-        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, myContext, testResId);
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, context);
         assertEquals(0, mSchemaFile.lastModified());
 
         // Schema is not updated on version downgrade
-        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 3, myContext, testResId);
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 3, context);
         assertEquals(0, mSchemaFile.lastModified());
     }
 
@@ -143,8 +159,7 @@
         mSchemaFile.delete();
         mDbFile.delete();
 
-        DbDowngradeHelper.updateSchemaFile(mSchemaFile, LauncherProvider.SCHEMA_VERSION, mContext,
-                R.raw.downgrade_schema);
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, LauncherProvider.SCHEMA_VERSION, mContext);
 
         DatabaseHelper dbHelper = new DatabaseHelper(mContext, null, DB_FILE) {
             @Override
diff --git a/robolectric_tests/src/com/android/launcher3/model/GridBackupTableTest.java b/robolectric_tests/src/com/android/launcher3/model/GridBackupTableTest.java
new file mode 100644
index 0000000..53287a9
--- /dev/null
+++ b/robolectric_tests/src/com/android/launcher3/model/GridBackupTableTest.java
@@ -0,0 +1,115 @@
+package com.android.launcher3.model;
+
+
+import static android.database.DatabaseUtils.queryNumEntries;
+
+import static com.android.launcher3.LauncherSettings.Favorites.BACKUP_TABLE_NAME;
+import static com.android.launcher3.LauncherSettings.Favorites.TABLE_NAME;
+import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.content.ContentValues;
+import android.graphics.Point;
+
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.Settings;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+
+/**
+ * Unit tests for {@link GridBackupTable}
+ */
+@RunWith(RobolectricTestRunner.class)
+public class GridBackupTableTest extends BaseGridChangesTestCase {
+
+    private static final int BACKUP_ITEM_COUNT = 12;
+
+    @Before
+    public void setupGridData() {
+        createGrid(new int[][][]{{
+                { APP_ICON, APP_ICON, SHORTCUT, SHORTCUT},
+                { SHORTCUT, SHORTCUT, NO__ICON, NO__ICON},
+                { NO__ICON, NO__ICON, SHORTCUT, SHORTCUT},
+                { APP_ICON, SHORTCUT, SHORTCUT, APP_ICON},
+        }});
+        assertEquals(BACKUP_ITEM_COUNT, queryNumEntries(mDb, TABLE_NAME));
+    }
+
+    @Test
+    public void backupTableCreated() {
+        GridBackupTable backupTable = new GridBackupTable(mContext, mDb, 4, 4, 4);
+        assertFalse(backupTable.backupOrRestoreAsNeeded());
+        Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+        assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+
+        // One extra entry for properties
+        assertEquals(BACKUP_ITEM_COUNT + 1, queryNumEntries(mDb, BACKUP_TABLE_NAME));
+    }
+
+    @Test
+    public void backupTableRestored() {
+        assertFalse(new GridBackupTable(mContext, mDb, 4, 4, 4).backupOrRestoreAsNeeded());
+        Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+        // Delete entries
+        mDb.delete(TABLE_NAME, null, null);
+        assertEquals(0, queryNumEntries(mDb, TABLE_NAME));
+
+        GridBackupTable backupTable = new GridBackupTable(mContext, mDb, 3, 3, 3);
+        assertTrue(backupTable.backupOrRestoreAsNeeded());
+
+        // Items have been restored
+        assertEquals(BACKUP_ITEM_COUNT, queryNumEntries(mDb, TABLE_NAME));
+
+        Point outSize = new Point();
+        assertEquals(4, backupTable.getRestoreHotseatAndGridSize(outSize));
+        assertEquals(4, outSize.x);
+        assertEquals(4, outSize.y);
+    }
+
+    @Test
+    public void backupTableRemovedOnAdd() {
+        assertFalse(new GridBackupTable(mContext, mDb, 4, 4, 4).backupOrRestoreAsNeeded());
+        Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+        assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+
+        addItem(1, 2, DESKTOP, 1, 1);
+        assertFalse(tableExists(mDb, BACKUP_TABLE_NAME));
+    }
+
+    @Test
+    public void backupTableRemovedOnDelete() {
+        assertFalse(new GridBackupTable(mContext, mDb, 4, 4, 4).backupOrRestoreAsNeeded());
+        Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+        assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+
+        mContext.getContentResolver().delete(Favorites.CONTENT_URI, null, null);
+        assertFalse(tableExists(mDb, BACKUP_TABLE_NAME));
+    }
+
+    @Test
+    public void backupTableRetainedOnUpdate() {
+        assertFalse(new GridBackupTable(mContext, mDb, 4, 4, 4).backupOrRestoreAsNeeded());
+        Settings.call(mContext.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
+
+        assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+
+        ContentValues values = new ContentValues();
+        values.put(Favorites.RANK, 4);
+        // Something was updated
+        assertTrue(mContext.getContentResolver()
+                .update(Favorites.CONTENT_URI, values, null, null) > 0);
+
+        // Backup table remains
+        assertTrue(tableExists(mDb, BACKUP_TABLE_NAME));
+    }
+}
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
similarity index 64%
rename from tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
rename to robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
index 7fa401b..ce07a27 100644
--- a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
@@ -1,90 +1,60 @@
 package com.android.launcher3.model;
 
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.ContextWrapper;
-import android.content.Intent;
+import static com.android.launcher3.model.GridSizeMigrationTask.getWorkspaceScreenIds;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 import android.database.Cursor;
 import android.graphics.Point;
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.MediumTest;
-import androidx.test.rule.provider.ProviderTestRule;
-import androidx.test.runner.AndroidJUnit4;
 
 import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.config.FlagOverrideRule;
+import com.android.launcher3.config.FlagOverrideRule.FlagOverride;
 import com.android.launcher3.model.GridSizeMigrationTask.MultiStepMigrationTask;
 import com.android.launcher3.util.IntArray;
-import com.android.launcher3.util.TestLauncherProvider;
 
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
 
 import java.util.HashSet;
 import java.util.LinkedList;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
 /**
  * Unit tests for {@link GridSizeMigrationTask}
  */
-@MediumTest
-@RunWith(AndroidJUnit4.class)
-public class GridSizeMigrationTaskTest {
+@RunWith(RobolectricTestRunner.class)
+public class GridSizeMigrationTaskTest extends BaseGridChangesTestCase {
 
     @Rule
-    public ProviderTestRule mProviderRule =
-            new ProviderTestRule.Builder(TestLauncherProvider.class, LauncherProvider.AUTHORITY)
-                    .build();
-
-    private static final int DESKTOP = LauncherSettings.Favorites.CONTAINER_DESKTOP;
-    private static final int HOTSEAT = LauncherSettings.Favorites.CONTAINER_HOTSEAT;
-
-    private static final int APPLICATION = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
-    private static final int SHORTCUT = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
-
-    private static final String TEST_PACKAGE = "com.android.launcher3.validpackage";
-    private static final String VALID_INTENT =
-            new Intent(Intent.ACTION_MAIN).setPackage(TEST_PACKAGE).toUri(0);
+    public final FlagOverrideRule flags = new FlagOverrideRule();
 
     private HashSet<String> mValidPackages;
     private InvariantDeviceProfile mIdp;
-    private Context mContext;
 
     @Before
-    public void setUp() throws Exception {
+    public void setUp() {
         mValidPackages = new HashSet<>();
         mValidPackages.add(TEST_PACKAGE);
-
         mIdp = new InvariantDeviceProfile();
-
-        mContext = new ContextWrapper(InstrumentationRegistry.getTargetContext()) {
-
-            @Override
-            public ContentResolver getContentResolver() {
-                return mProviderRule.getResolver();
-            }
-        };
     }
 
     @Test
     public void testHotseatMigration_apps_dropped() throws Exception {
         int[] hotseatItems = {
-                addItem(APPLICATION, 0, HOTSEAT, 0, 0),
+                addItem(APP_ICON, 0, HOTSEAT, 0, 0),
                 addItem(SHORTCUT, 1, HOTSEAT, 0, 0),
                 -1,
                 addItem(SHORTCUT, 3, HOTSEAT, 0, 0),
-                addItem(APPLICATION, 4, HOTSEAT, 0, 0),
+                addItem(APP_ICON, 4, HOTSEAT, 0, 0),
         };
 
         mIdp.numHotseatIcons = 3;
-        new GridSizeMigrationTask(mContext, mIdp, mValidPackages, 5, 3)
+        new GridSizeMigrationTask(mContext, mDb, mValidPackages, 5, 3)
                 .migrateHotseat();
         // First item is dropped as it has the least weight.
         verifyHotseat(hotseatItems[1], hotseatItems[3], hotseatItems[4]);
@@ -93,7 +63,7 @@
     @Test
     public void testHotseatMigration_shortcuts_dropped() throws Exception {
         int[] hotseatItems = {
-                addItem(APPLICATION, 0, HOTSEAT, 0, 0),
+                addItem(APP_ICON, 0, HOTSEAT, 0, 0),
                 addItem(30, 1, HOTSEAT, 0, 0),
                 -1,
                 addItem(SHORTCUT, 3, HOTSEAT, 0, 0),
@@ -101,7 +71,7 @@
         };
 
         mIdp.numHotseatIcons = 3;
-        new GridSizeMigrationTask(mContext, mIdp, mValidPackages, 5, 3)
+        new GridSizeMigrationTask(mContext, mDb, mValidPackages, 5, 3)
                 .migrateHotseat();
         // First item is dropped as it has the least weight.
         verifyHotseat(hotseatItems[1], hotseatItems[3], hotseatItems[4]);
@@ -112,7 +82,7 @@
         int total = 0;
 
         for (int id : sortedIds) {
-            Cursor c = mProviderRule.getResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+            Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
                     new String[]{LauncherSettings.Favorites._ID},
                     "container=-101 and screen=" + screenId, null, null, null);
 
@@ -130,7 +100,7 @@
         }
 
         // Verify that not other entry exist in the DB.
-        Cursor c = mProviderRule.getResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+        Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
                 new String[]{LauncherSettings.Favorites._ID},
                 "container=-101", null, null, null);
         assertEquals(total, c.getCount());
@@ -146,7 +116,7 @@
                 {  5,  2, -1,  6},
         }});
 
-        new GridSizeMigrationTask(mContext, mIdp, mValidPackages,
+        new GridSizeMigrationTask(mContext, mDb, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Column 2 and row 2 got removed.
@@ -166,7 +136,7 @@
                 {  5,  2, -1,  6},
         }});
 
-        new GridSizeMigrationTask(mContext, mIdp, mValidPackages,
+        new GridSizeMigrationTask(mContext, mDb, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Items in the second column get moved to new screen
@@ -191,7 +161,7 @@
                 {  3,  1, -1,  4},
         }});
 
-        new GridSizeMigrationTask(mContext, mIdp, mValidPackages,
+        new GridSizeMigrationTask(mContext, mDb, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Items in the second column of the first screen should get placed on the 3rd
@@ -223,7 +193,7 @@
                 {  5,  2, -1,  6},
         }});
 
-        new GridSizeMigrationTask(mContext, mIdp, mValidPackages,
+        new GridSizeMigrationTask(mContext, mDb, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Items in the second column of the first screen should get placed on a new screen.
@@ -240,6 +210,7 @@
         }});
     }
 
+    @FlagOverride(key = "QSB_ON_FIRST_SCREEN", value = true)
     @Test
     public void testWorkspace_first_row_blocked() throws Exception {
         // The first screen has one item on the 4th column which needs moving, as the first row
@@ -251,7 +222,7 @@
                 {  5,  2,  7, -1},
         }}, 0);
 
-        new GridSizeMigrationTask(mContext, mIdp, mValidPackages,
+        new GridSizeMigrationTask(mContext, mDb, mValidPackages,
                 new Point(4, 4), new Point(3, 4)).migrateWorkspace();
 
         // Items in the second column of the first screen should get placed on a new screen.
@@ -265,6 +236,7 @@
         }});
     }
 
+    @FlagOverride(key = "QSB_ON_FIRST_SCREEN", value = true)
     @Test
     public void testWorkspace_items_moved_to_empty_first_row() throws Exception {
         // Items will get moved to the next screen to keep the first screen empty.
@@ -275,7 +247,7 @@
                 {  5,  6,  7, -1},
         }}, 0);
 
-        new GridSizeMigrationTask(mContext, mIdp, mValidPackages,
+        new GridSizeMigrationTask(mContext, mDb, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Items in the second column of the first screen should get placed on a new screen.
@@ -289,58 +261,13 @@
         }});
     }
 
-    private int[][][] createGrid(int[][][] typeArray) throws Exception {
-        return createGrid(typeArray, 1);
-    }
-
-    /**
-     * Initializes the DB with dummy elements to represent the provided grid structure.
-     * @param typeArray A 3d array of item types. {@see #addItem(int, long, long, int, int)} for
-     *                  type definitions. The first dimension represents the screens and the next
-     *                  two represent the workspace grid.
-     * @return the same grid representation where each entry is the corresponding item id.
-     */
-    private int[][][] createGrid(int[][][] typeArray, int startScreen) throws Exception {
-        LauncherSettings.Settings.call(mProviderRule.getResolver(),
-                LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
-        int[][][] ids = new int[typeArray.length][][];
-
-        for (int i = 0; i < typeArray.length; i++) {
-            // Add screen to DB
-            int screenId = startScreen + i;
-
-            // Keep the screen id counter up to date
-            LauncherSettings.Settings.call(mProviderRule.getResolver(),
-                    LauncherSettings.Settings.METHOD_NEW_SCREEN_ID);
-
-            ContentValues v = new ContentValues();
-            v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
-            v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
-            mProviderRule.getResolver().insert(LauncherSettings.WorkspaceScreens.CONTENT_URI, v);
-
-            ids[i] = new int[typeArray[i].length][];
-            for (int y = 0; y < typeArray[i].length; y++) {
-                ids[i][y] = new int[typeArray[i][y].length];
-                for (int x = 0; x < typeArray[i][y].length; x++) {
-                    if (typeArray[i][y][x] < 0) {
-                        // Empty cell
-                        ids[i][y][x] = -1;
-                    } else {
-                        ids[i][y][x] = addItem(typeArray[i][y][x], screenId, DESKTOP, x, y);
-                    }
-                }
-            }
-        }
-        return ids;
-    }
-
     /**
      * Verifies that the workspace items are arranged in the provided order.
      * @param ids A 3d array where the first dimension represents the screen, and the rest two
      *            represent the workspace grid.
      */
     private void verifyWorkspace(int[][][] ids) {
-        IntArray allScreens = LauncherModel.loadWorkspaceScreensDb(mContext);
+        IntArray allScreens = getWorkspaceScreenIds(mDb);
         assertEquals(ids.length, allScreens.size());
         int total = 0;
 
@@ -350,7 +277,7 @@
                 for (int x = 0; x < ids[i][y].length; x++) {
                     int id = ids[i][y][x];
 
-                    Cursor c = mProviderRule.getResolver().query(
+                    Cursor c = mContext.getContentResolver().query(
                             LauncherSettings.Favorites.CONTENT_URI,
                             new String[]{LauncherSettings.Favorites._ID},
                             "container=-100 and screen=" + screenId +
@@ -370,48 +297,13 @@
         }
 
         // Verify that not other entry exist in the DB.
-        Cursor c = mProviderRule.getResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+        Cursor c = mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
                 new String[]{LauncherSettings.Favorites._ID},
                 "container=-100", null, null, null);
         assertEquals(total, c.getCount());
         c.close();
     }
 
-    /**
-     * Adds a dummy item in the DB.
-     * @param type {@link #APPLICATION} or {@link #SHORTCUT} or >= 2 for
-     *             folder (where the type represents the number of items in the folder).
-     */
-    private int addItem(int type, int screen, int container, int x, int y) throws Exception {
-        int id = LauncherSettings.Settings.call(mProviderRule.getResolver(),
-                LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
-                .getInt(LauncherSettings.Settings.EXTRA_VALUE);
-
-        ContentValues values = new ContentValues();
-        values.put(LauncherSettings.Favorites._ID, id);
-        values.put(LauncherSettings.Favorites.CONTAINER, container);
-        values.put(LauncherSettings.Favorites.SCREEN, screen);
-        values.put(LauncherSettings.Favorites.CELLX, x);
-        values.put(LauncherSettings.Favorites.CELLY, y);
-        values.put(LauncherSettings.Favorites.SPANX, 1);
-        values.put(LauncherSettings.Favorites.SPANY, 1);
-
-        if (type == APPLICATION || type == SHORTCUT) {
-            values.put(LauncherSettings.Favorites.ITEM_TYPE, type);
-            values.put(LauncherSettings.Favorites.INTENT, VALID_INTENT);
-        } else {
-            values.put(LauncherSettings.Favorites.ITEM_TYPE,
-                    LauncherSettings.Favorites.ITEM_TYPE_FOLDER);
-            // Add folder items.
-            for (int i = 0; i < type; i++) {
-                addItem(APPLICATION, 0, id, 0, 0);
-            }
-        }
-
-        mProviderRule.getResolver().insert(LauncherSettings.Favorites.CONTENT_URI, values);
-        return id;
-    }
-
     @Test
     public void testMultiStepMigration_small_to_large() throws Exception {
         MultiStepMigrationTaskVerifier verifier = new MultiStepMigrationTaskVerifier();
@@ -444,7 +336,7 @@
         private final LinkedList<Point> mPoints;
 
         public MultiStepMigrationTaskVerifier(int... points) {
-            super(null, null);
+            super(null, null, null);
 
             mPoints = new LinkedList<>();
             for (int i = 0; i < points.length; i += 2) {
diff --git a/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java b/robolectric_tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
similarity index 91%
rename from tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
rename to robolectric_tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
index 25100dc..c7b4613 100644
--- a/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
+++ b/robolectric_tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
@@ -2,9 +2,6 @@
 
 import static org.junit.Assert.assertEquals;
 
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.ShortcutInfo;
@@ -14,6 +11,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
 
 import java.util.Arrays;
 import java.util.HashSet;
@@ -21,13 +19,12 @@
 /**
  * Tests for {@link PackageInstallStateChangedTask}
  */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(RobolectricTestRunner.class)
 public class PackageInstallStateChangedTaskTest extends BaseModelUpdateTaskTestCase {
 
     @Before
     public void initData() throws Exception {
-        initializeData("package_install_state_change_task_data");
+        initializeData("/package_install_state_change_task_data.txt");
     }
 
     private PackageInstallStateChangedTask newTask(String pkg, int progress) {
diff --git a/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java b/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java
index faec380..f846de5 100644
--- a/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java
+++ b/robolectric_tests/src/com/android/launcher3/util/IntSetTest.java
@@ -31,7 +31,6 @@
  * Robolectric unit tests for {@link IntSet}
  */
 @RunWith(RobolectricTestRunner.class)
-@Config(sdk = 26)
 public class IntSetTest {
 
     @Test
diff --git a/tests/src/com/android/launcher3/util/TestLauncherProvider.java b/robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java
similarity index 92%
rename from tests/src/com/android/launcher3/util/TestLauncherProvider.java
rename to robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java
index 1d6c18b..31e303e 100644
--- a/tests/src/com/android/launcher3/util/TestLauncherProvider.java
+++ b/robolectric_tests/src/com/android/launcher3/util/TestLauncherProvider.java
@@ -23,9 +23,9 @@
         }
     }
 
-    public SQLiteOpenHelper getHelper() {
+    public SQLiteDatabase getDb() {
         createDbIfNotExists();
-        return mOpenHelper;
+        return mOpenHelper.getWritableDatabase();
     }
 
     @Override
@@ -48,4 +48,4 @@
         @Override
         protected void handleOneTimeDataUpgrade(SQLiteDatabase db) { }
     }
-}
\ No newline at end of file
+}
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index c7c1d6a..e5b1448 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -39,6 +39,7 @@
 
 import com.android.launcher3.LauncherProvider.SqlArguments;
 import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.Thunk;
@@ -47,7 +48,6 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Locale;
 
 /**
@@ -436,7 +436,7 @@
 
             // Auto installs should always support the current platform version.
             LauncherIcons li = LauncherIcons.obtain(mContext);
-            mValues.put(LauncherSettings.Favorites.ICON, Utilities.flattenBitmap(
+            mValues.put(LauncherSettings.Favorites.ICON, GraphicsUtils.flattenBitmap(
                     li.createBadgedIconBitmap(icon, Process.myUserHandle(), VERSION.SDK_INT).icon));
             li.recycle();
 
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 77b6010..1b953d4 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -36,6 +36,7 @@
 import com.android.launcher3.uioverrides.UiFactory;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.util.SystemUiController;
+import com.android.launcher3.views.ActivityContext;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -44,7 +45,8 @@
 
 import androidx.annotation.IntDef;
 
-public abstract class BaseActivity extends Activity implements UserEventDelegate, LogStateProvider{
+public abstract class BaseActivity extends Activity
+        implements UserEventDelegate, LogStateProvider, ActivityContext {
 
     public static final int INVISIBLE_BY_STATE_HANDLER = 1 << 0;
     public static final int INVISIBLE_BY_APP_TRANSITIONS = 1 << 1;
@@ -100,14 +102,11 @@
     // animation
     @InvisibilityFlags private int mForceInvisible;
 
+    @Override
     public DeviceProfile getDeviceProfile() {
         return mDeviceProfile;
     }
 
-    public AccessibilityDelegate getAccessibilityDelegate() {
-        return null;
-    }
-
     public int getCurrentState() { return StatsLogUtils.LAUNCHER_STATE_BACKGROUND; }
 
     public void modifyUserEvent(LauncherLogProto.LauncherEvent event) {}
diff --git a/src/com/android/launcher3/BaseDraggingActivity.java b/src/com/android/launcher3/BaseDraggingActivity.java
index 152dc84..12d443b 100644
--- a/src/com/android/launcher3/BaseDraggingActivity.java
+++ b/src/com/android/launcher3/BaseDraggingActivity.java
@@ -21,7 +21,6 @@
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.graphics.Rect;
-import android.os.Build;
 import android.os.Bundle;
 import android.os.Process;
 import android.os.StrictMode;
@@ -32,19 +31,16 @@
 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.shortcuts.DeepShortcutManager;
 import com.android.launcher3.uioverrides.DisplayRotationListener;
 import com.android.launcher3.uioverrides.WallpaperColorInfo;
-import com.android.launcher3.views.BaseDragLayer;
-import com.android.launcher3.views.ActivityContext;
 
 /**
  * Extension of BaseActivity allowing support for drag-n-drop
  */
 public abstract class BaseDraggingActivity extends BaseActivity
-        implements WallpaperColorInfo.OnChangeListener, ActivityContext {
+        implements WallpaperColorInfo.OnChangeListener {
 
     private static final String TAG = "BaseDraggingActivity";
 
@@ -139,16 +135,10 @@
         return false;
     }
 
-    public abstract BaseDragLayer getDragLayer();
-
     public abstract <T extends View> T getOverviewPanel();
 
     public abstract View getRootView();
 
-    public abstract BadgeInfo getBadgeInfoForItem(ItemInfo info);
-
-    public abstract void invalidateParent(ItemInfo info);
-
     public Rect getViewBounds(View v) {
         int[] pos = new int[2];
         v.getLocationOnScreen(pos);
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 8513d63..d96855e 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3;
 
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
@@ -25,7 +27,6 @@
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
@@ -40,21 +41,20 @@
 import android.view.ViewDebug;
 import android.widget.TextView;
 
-import com.android.launcher3.icons.IconCache.IconLoadRequest;
-import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
 import com.android.launcher3.Launcher.OnResumeCallback;
-import com.android.launcher3.badge.BadgeInfo;
-import com.android.launcher3.badge.BadgeRenderer;
+import com.android.launcher3.dot.DotInfo;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.graphics.DrawableFactory;
 import com.android.launcher3.graphics.IconPalette;
 import com.android.launcher3.graphics.PreloadIconDrawable;
+import com.android.launcher3.icons.DotRenderer;
+import com.android.launcher3.icons.IconCache.IconLoadRequest;
+import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
 import com.android.launcher3.model.PackageItemInfo;
+import com.android.launcher3.views.ActivityContext;
 
 import java.text.NumberFormat;
 
-import androidx.core.graphics.ColorUtils;
-
 /**
  * TextView that draws a bubble behind the text. We cannot use a LineBackgroundSpan
  * because we want to make the bubble taller than the text and TextView's clip is
@@ -69,16 +69,16 @@
     private static final int[] STATE_PRESSED = new int[] {android.R.attr.state_pressed};
 
 
-    private static final Property<BubbleTextView, Float> BADGE_SCALE_PROPERTY
-            = new Property<BubbleTextView, Float>(Float.TYPE, "badgeScale") {
+    private static final Property<BubbleTextView, Float> DOT_SCALE_PROPERTY
+            = new Property<BubbleTextView, Float>(Float.TYPE, "dotScale") {
         @Override
         public Float get(BubbleTextView bubbleTextView) {
-            return bubbleTextView.mBadgeScale;
+            return bubbleTextView.mDotParams.scale;
         }
 
         @Override
         public void set(BubbleTextView bubbleTextView, Float value) {
-            bubbleTextView.mBadgeScale = value;
+            bubbleTextView.mDotParams.scale = value;
             bubbleTextView.invalidate();
         }
     };
@@ -96,7 +96,7 @@
         }
     };
 
-    private final BaseDraggingActivity mActivity;
+    private final ActivityContext mActivity;
     private Drawable mIcon;
     private final boolean mCenterVertically;
 
@@ -115,15 +115,12 @@
     private float mTextAlpha = 1;
 
     @ViewDebug.ExportedProperty(category = "launcher")
-    private BadgeInfo mBadgeInfo;
-    private BadgeRenderer mBadgeRenderer;
-    private int mBadgeColor;
-    @ViewDebug.ExportedProperty(category = "launcher")
-    private float mBadgeScale;
-    private Animator mBadgeScaleAnim;
-    private boolean mForceHideBadge;
-    private Point mTempSpaceForBadgeOffset = new Point();
-    private Rect mTempIconBounds = new Rect();
+    private DotInfo mDotInfo;
+    private DotRenderer mDotRenderer;
+    @ViewDebug.ExportedProperty(category = "launcher", deepExport = true)
+    private DotRenderer.DrawParams mDotParams;
+    private Animator mDotScaleAnim;
+    private boolean mForceHideDot;
 
     @ViewDebug.ExportedProperty(category = "launcher")
     private boolean mStayPressed;
@@ -144,7 +141,7 @@
 
     public BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mActivity = BaseDraggingActivity.fromContext(context);
+        mActivity = ActivityContext.lookupContext(context);
         DeviceProfile grid = mActivity.getDeviceProfile();
         mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
 
@@ -175,6 +172,8 @@
         mLongPressHelper = new CheckLongPressHelper(this);
         mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
 
+        mDotParams = new DotRenderer.DrawParams();
+
         setEllipsize(TruncateAt.END);
         setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
         setTextAlpha(1f);
@@ -191,29 +190,29 @@
      * Resets the view so it can be recycled.
      */
     public void reset() {
-        mBadgeInfo = null;
-        mBadgeColor = Color.TRANSPARENT;
-        cancelBadgeScaleAnim();
-        mBadgeScale = 0f;
-        mForceHideBadge = false;
+        mDotInfo = null;
+        mDotParams.color = Color.TRANSPARENT;
+        cancelDotScaleAnim();
+        mDotParams.scale = 0f;
+        mForceHideDot = false;
     }
 
-    private void cancelBadgeScaleAnim() {
-        if (mBadgeScaleAnim != null) {
-            mBadgeScaleAnim.cancel();
+    private void cancelDotScaleAnim() {
+        if (mDotScaleAnim != null) {
+            mDotScaleAnim.cancel();
         }
     }
 
-    private void animateBadgeScale(float... badgeScales) {
-        cancelBadgeScaleAnim();
-        mBadgeScaleAnim = ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, badgeScales);
-        mBadgeScaleAnim.addListener(new AnimatorListenerAdapter() {
+    private void animateDotScale(float... dotScales) {
+        cancelDotScaleAnim();
+        mDotScaleAnim = ObjectAnimator.ofFloat(this, DOT_SCALE_PROPERTY, dotScales);
+        mDotScaleAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                mBadgeScaleAnim = null;
+                mDotScaleAnim = null;
             }
         });
-        mBadgeScaleAnim.start();
+        mDotScaleAnim.start();
     }
 
     public void applyFromShortcutInfo(ShortcutInfo info) {
@@ -227,7 +226,7 @@
             applyPromiseState(promiseStateChanged);
         }
 
-        applyBadgeState(info, false /* animate */);
+        applyDotState(info, false /* animate */);
     }
 
     public void applyFromApplicationInfo(AppInfo info) {
@@ -243,7 +242,7 @@
             PromiseAppInfo promiseAppInfo = (PromiseAppInfo) info;
             applyProgressLevel(promiseAppInfo.level);
         }
-        applyBadgeState(info, false /* animate */);
+        applyDotState(info, false /* animate */);
     }
 
     public void applyFromPackageItemInfo(PackageItemInfo info) {
@@ -258,7 +257,7 @@
     private void applyIconAndLabel(ItemInfoWithIcon info) {
         FastBitmapDrawable iconDrawable = DrawableFactory.INSTANCE.get(getContext())
                 .newIcon(getContext(), info);
-        mBadgeColor = IconPalette.getMutedColor(info.iconColor, 0.54f);
+        mDotParams.color = IconPalette.getMutedColor(info.iconColor, 0.54f);
 
         setIcon(iconDrawable);
         setText(info.title);
@@ -343,6 +342,14 @@
     }
 
     @Override
+    public void onVisibilityAggregated(boolean isVisible) {
+        super.onVisibilityAggregated(isVisible);
+        if (mIcon != null) {
+            mIcon.setVisible(isVisible, false);
+        }
+    }
+
+    @Override
     public void onLauncherResume() {
         // Reset the pressed state of icon that was locked in the press state while activity
         // was launching
@@ -367,48 +374,47 @@
     }
 
     @SuppressWarnings("wrongcall")
-    protected void drawWithoutBadge(Canvas canvas) {
+    protected void drawWithoutDot(Canvas canvas) {
         super.onDraw(canvas);
     }
 
     @Override
     public void onDraw(Canvas canvas) {
         super.onDraw(canvas);
-        drawBadgeIfNecessary(canvas);
+        drawDotIfNecessary(canvas);
     }
 
     /**
-     * Draws the icon badge in the top right corner of the icon bounds.
+     * Draws the notification dot in the top right corner of the icon bounds.
      * @param canvas The canvas to draw to.
      */
-    protected void drawBadgeIfNecessary(Canvas canvas) {
-        if (!mForceHideBadge && (hasBadge() || mBadgeScale > 0)) {
-            getIconBounds(mTempIconBounds);
-            mTempSpaceForBadgeOffset.set((getWidth() - mIconSize) / 2, getPaddingTop());
+    protected void drawDotIfNecessary(Canvas canvas) {
+        if (!mForceHideDot && (hasDot() || mDotParams.scale > 0)) {
+            getIconBounds(mDotParams.iconBounds);
+            mDotParams.spaceForOffset.set((getWidth() - mIconSize) / 2, getPaddingTop());
             final int scrollX = getScrollX();
             final int scrollY = getScrollY();
             canvas.translate(scrollX, scrollY);
-            mBadgeRenderer.draw(canvas, mBadgeColor, mTempIconBounds, mBadgeScale,
-                    mTempSpaceForBadgeOffset);
+            mDotRenderer.draw(canvas, mDotParams);
             canvas.translate(-scrollX, -scrollY);
         }
     }
 
-    public void forceHideBadge(boolean forceHideBadge) {
-        if (mForceHideBadge == forceHideBadge) {
+    public void forceHideDot(boolean forceHideDot) {
+        if (mForceHideDot == forceHideDot) {
             return;
         }
-        mForceHideBadge = forceHideBadge;
+        mForceHideDot = forceHideDot;
 
-        if (forceHideBadge) {
+        if (forceHideDot) {
             invalidate();
-        } else if (hasBadge()) {
-            animateBadgeScale(0, 1);
+        } else if (hasDot()) {
+            animateDotScale(0, 1);
         }
     }
 
-    private boolean hasBadge() {
-        return mBadgeInfo != null;
+    private boolean hasDot() {
+        return mDotInfo != null;
     }
 
     public void getIconBounds(Rect outBounds) {
@@ -473,8 +479,7 @@
             // Special case to prevent text shadows in high contrast mode
             return Color.TRANSPARENT;
         }
-        return ColorUtils.setAlphaComponent(
-                mTextColor, Math.round(Color.alpha(mTextColor) * mTextAlpha));
+        return setColorAlphaBound(mTextColor, Math.round(Color.alpha(mTextColor) * mTextAlpha));
     }
 
     /**
@@ -539,28 +544,28 @@
         return null;
     }
 
-    public void applyBadgeState(ItemInfo itemInfo, boolean animate) {
+    public void applyDotState(ItemInfo itemInfo, boolean animate) {
         if (mIcon instanceof FastBitmapDrawable) {
-            boolean wasBadged = mBadgeInfo != null;
-            mBadgeInfo = mActivity.getBadgeInfoForItem(itemInfo);
-            boolean isBadged = mBadgeInfo != null;
-            float newBadgeScale = isBadged ? 1f : 0;
-            mBadgeRenderer = mActivity.getDeviceProfile().mBadgeRenderer;
-            if (wasBadged || isBadged) {
-                // Animate when a badge is first added or when it is removed.
-                if (animate && (wasBadged ^ isBadged) && isShown()) {
-                    animateBadgeScale(newBadgeScale);
+            boolean wasDotted = mDotInfo != null;
+            mDotInfo = mActivity.getDotInfoForItem(itemInfo);
+            boolean isDotted = mDotInfo != null;
+            float newDotScale = isDotted ? 1f : 0;
+            mDotRenderer = mActivity.getDeviceProfile().mDotRenderer;
+            if (wasDotted || isDotted) {
+                // Animate when a dot is first added or when it is removed.
+                if (animate && (wasDotted ^ isDotted) && isShown()) {
+                    animateDotScale(newDotScale);
                 } else {
-                    cancelBadgeScaleAnim();
-                    mBadgeScale = newBadgeScale;
+                    cancelDotScaleAnim();
+                    mDotParams.scale = newDotScale;
                     invalidate();
                 }
             }
             if (itemInfo.contentDescription != null) {
-                if (hasBadge()) {
-                    int count = mBadgeInfo.getNotificationCount();
+                if (hasDot()) {
+                    int count = mDotInfo.getNotificationCount();
                     setContentDescription(getContext().getResources().getQuantityString(
-                            R.plurals.badged_app_label, count, itemInfo.contentDescription, count));
+                            R.plurals.dotted_app_label, count, itemInfo.contentDescription, count));
                 } else {
                     setContentDescription(itemInfo.contentDescription);
                 }
@@ -576,6 +581,9 @@
             applyCompoundDrawables(icon);
         }
         mIcon = icon;
+        if (mIcon != null) {
+            mIcon.setVisible(getWindowVisibility() == VISIBLE && isShown(), false);
+        }
     }
 
     public void setIconVisible(boolean visible) {
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 92404d4..a117cfd 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -62,6 +62,7 @@
 import com.android.launcher3.util.ParcelableSparseArray;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
+import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 
 import java.lang.annotation.Retention;
@@ -82,7 +83,7 @@
     private static final String TAG = "CellLayout";
     private static final boolean LOGD = false;
 
-    private final Launcher mLauncher;
+    protected final ActivityContext mActivity;
     @ViewDebug.ExportedProperty(category = "launcher")
     @Thunk int mCellWidth;
     @ViewDebug.ExportedProperty(category = "launcher")
@@ -106,7 +107,6 @@
     private GridOccupancy mTmpOccupied;
 
     private OnTouchListener mInterceptTouchListener;
-    private final StylusEventHelper mStylusEventHelper;
 
     private final ArrayList<PreviewBackground> mFolderBackgrounds = new ArrayList<>();
     final PreviewBackground mFolderLeaveBehind = new PreviewBackground();
@@ -201,9 +201,9 @@
         // the user where a dragged item will land when dropped.
         setWillNotDraw(false);
         setClipToPadding(false);
-        mLauncher = Launcher.getLauncher(context);
+        mActivity = ActivityContext.lookupContext(context);
 
-        DeviceProfile grid = mLauncher.getDeviceProfile();
+        DeviceProfile grid = mActivity.getDeviceProfile();
 
         mCellWidth = mCellHeight = -1;
         mFixedCellWidth = mFixedCellHeight = -1;
@@ -286,8 +286,6 @@
 
         mShortcutsAndWidgets = new ShortcutAndWidgetContainer(context, mContainerType);
         mShortcutsAndWidgets.setCellDimensions(mCellWidth, mCellHeight, mCountX, mCountY);
-
-        mStylusEventHelper = new StylusEventHelper(new SimpleOnStylusPressListener(this), this);
         addView(mShortcutsAndWidgets);
     }
 
@@ -337,20 +335,6 @@
         return false;
     }
 
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-        boolean handled = super.onTouchEvent(ev);
-        // Stylus button press on a home screen should not switch between overview mode and
-        // the home screen mode, however, once in overview mode stylus button press should be
-        // enabled to allow rearranging the different home screens. So check what mode
-        // the workspace is in, and only perform stylus button presses while in overview mode.
-        if (mLauncher.isInState(LauncherState.OVERVIEW)
-                && mStylusEventHelper.onMotionEvent(ev)) {
-            return true;
-        }
-        return handled;
-    }
-
     public void enableHardwareLayer(boolean hasLayer) {
         mShortcutsAndWidgets.setLayerType(hasLayer ? LAYER_TYPE_HARDWARE : LAYER_TYPE_NONE, sPaint);
     }
@@ -504,7 +488,7 @@
 
     public void setFolderLeaveBehindCell(int x, int y) {
         View child = getChildAt(x, y);
-        mFolderLeaveBehind.setup(mLauncher, null,
+        mFolderLeaveBehind.setup(getContext(), mActivity, null,
                 child.getMeasuredWidth(), child.getPaddingTop());
 
         mFolderLeaveBehind.delegateCellX = x;
@@ -945,7 +929,7 @@
             if (resize) {
                 cellToRect(cellX, cellY, spanX, spanY, r);
                 if (v instanceof LauncherAppWidgetHostView) {
-                    DeviceProfile profile = mLauncher.getDeviceProfile();
+                    DeviceProfile profile = mActivity.getDeviceProfile();
                     Utilities.shrinkRect(r, profile.appWidgetScale.x, profile.appWidgetScale.y);
                 }
             } else {
@@ -2047,7 +2031,7 @@
                     .translationY(initDeltaY)
                     .build(child)
                     .setDuration(REORDER_ANIMATION_DURATION);
-            mLauncher.getDragController().addFirstFrameAnimationHelper(a);
+            Launcher.cast(mActivity).getDragController().addFirstFrameAnimationHelper(a);
             a.setInterpolator(DEACCEL_1_5);
             a.start();
         }
@@ -2063,7 +2047,7 @@
     private void commitTempPlacement() {
         mTmpOccupied.copyTo(mOccupied);
 
-        int screenId = mLauncher.getWorkspace().getIdForScreen(this);
+        int screenId = Launcher.cast(mActivity).getWorkspace().getIdForScreen(this);
         int container = Favorites.CONTAINER_DESKTOP;
 
         if (mContainerType == HOTSEAT) {
@@ -2089,8 +2073,8 @@
                 info.spanY = lp.cellVSpan;
 
                 if (requiresDbUpdate) {
-                    mLauncher.getModelWriter().modifyItemInDatabase(info, container, screenId,
-                            info.cellX, info.cellY, info.spanX, info.spanY);
+                    Launcher.cast(mActivity).getModelWriter().modifyItemInDatabase(info, container,
+                            screenId, info.cellX, info.cellY, info.spanX, info.spanY);
                 }
             }
         }
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index c80f96b..d60dc87 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -113,10 +113,11 @@
     public void completeDrop(DragObject d) {
         ItemInfo item = d.dragInfo;
         if (canRemove(item)) {
+            int itemPage = mLauncher.getWorkspace().getCurrentPage();
             onAccessibilityDrop(null, item);
             ModelWriter modelWriter = mLauncher.getModelWriter();
             Snackbar.show(mLauncher, R.string.item_removed, R.string.undo,
-                    modelWriter::commitDelete, modelWriter::abortDelete);
+                    modelWriter::commitDelete, () -> modelWriter.abortDelete(itemPage));
         }
     }
 
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 256fd6c..812cf9f 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -29,7 +29,7 @@
 import android.view.WindowManager;
 
 import com.android.launcher3.CellLayout.ContainerType;
-import com.android.launcher3.badge.BadgeRenderer;
+import com.android.launcher3.icons.DotRenderer;
 import com.android.launcher3.icons.IconNormalizer;
 
 public class DeviceProfile {
@@ -128,8 +128,8 @@
     private final Rect mHotseatPadding = new Rect();
     private boolean mIsSeascape;
 
-    // Icon badges
-    public BadgeRenderer mBadgeRenderer;
+    // Notification dots
+    public DotRenderer mDotRenderer;
 
     public DeviceProfile(Context context, InvariantDeviceProfile inv,
             Point minSize, Point maxSize,
@@ -207,11 +207,10 @@
         // Add a bit of space between nav bar and hotseat in multi-window vertical bar layout.
         hotseatBarSidePaddingStartPx = isMultiWindowMode && isVerticalBarLayout()
                 ? edgeMarginPx : 0;
-        hotseatBarSizePx = isVerticalBarLayout()
-                ? Utilities.pxFromDp(inv.iconSize, dm) + hotseatBarSidePaddingStartPx
-                        + hotseatBarSidePaddingEndPx
-                : res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_size)
-                        + hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx;
+        hotseatBarSizePx = Utilities.pxFromDp(inv.iconSize, dm) + (isVerticalBarLayout()
+                ? (hotseatBarSidePaddingStartPx + hotseatBarSidePaddingEndPx)
+                : (res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_extra_vertical_size)
+                        + hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx));
 
         // Calculate all of the remaining variables.
         updateAvailableDimensions(dm, res);
@@ -233,7 +232,7 @@
         updateWorkspacePadding();
 
         // This is done last, after iconSizePx is calculated above.
-        mBadgeRenderer = new BadgeRenderer(iconSizePx);
+        mDotRenderer = new DotRenderer(iconSizePx);
     }
 
     public DeviceProfile copy(Context context) {
diff --git a/src/com/android/launcher3/DropTarget.java b/src/com/android/launcher3/DropTarget.java
index 4d30479..763432d 100644
--- a/src/com/android/launcher3/DropTarget.java
+++ b/src/com/android/launcher3/DropTarget.java
@@ -78,17 +78,17 @@
          */
         public final float[] getVisualCenter(float[] recycle) {
             final float res[] = (recycle == null) ? new float[2] : recycle;
+            Rect dragRegion = dragView.getDragRegion();
 
             // These represent the visual top and left of drag view if a dragRect was provided.
             // If a dragRect was not provided, then they correspond to the actual view left and
             // top, as the dragRect is in that case taken to be the entire dragView.
-            // R.dimen.dragViewOffsetY.
-            int left = x - xOffset;
-            int top = y - yOffset;
+            int left = x - xOffset - dragRegion.left;
+            int top = y - yOffset - dragRegion.top;
 
             // In order to find the visual center, we shift by half the dragRect
-            res[0] = left + dragView.getDragRegion().width() / 2;
-            res[1] = top + dragView.getDragRegion().height() / 2;
+            res[0] = left + dragRegion.width() / 2;
+            res[1] = top + dragRegion.height() / 2;
 
             return res;
         }
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index daf587a..964e8b6 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -17,6 +17,7 @@
 package com.android.launcher3;
 
 import static com.android.launcher3.anim.Interpolators.ACCEL;
+import static com.android.launcher3.anim.Interpolators.DEACCEL;
 
 import android.animation.ObjectAnimator;
 import android.graphics.Bitmap;
@@ -221,8 +222,15 @@
                 mScaleAnimation.setInterpolator(ACCEL);
                 mScaleAnimation.start();
             } else {
-                mScale = 1f;
-                invalidateSelf();
+                if (isVisible()) {
+                    mScaleAnimation = ObjectAnimator.ofFloat(this, SCALE, 1f);
+                    mScaleAnimation.setDuration(CLICK_FEEDBACK_DURATION);
+                    mScaleAnimation.setInterpolator(DEACCEL);
+                    mScaleAnimation.start();
+                } else {
+                    mScale = 1f;
+                    invalidateSelf();
+                }
             }
             return true;
         }
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 6b5db30..cbd3fc0 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -20,7 +20,6 @@
 import android.graphics.Rect;
 import android.util.AttributeSet;
 import android.view.Gravity;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.ViewGroup;
@@ -32,8 +31,6 @@
 
 public class Hotseat extends CellLayout implements LogContainerProvider, Insettable {
 
-    private final Launcher mLauncher;
-
     @ViewDebug.ExportedProperty(category = "launcher")
     private boolean mHasVerticalHotseat;
 
@@ -47,7 +44,6 @@
 
     public Hotseat(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
-        mLauncher = Launcher.getLauncher(context);
     }
 
     /* Get the orientation specific coordinates given an invariant order in the hotseat. */
@@ -59,10 +55,10 @@
         return mHasVerticalHotseat ? (getCountY() - (rank + 1)) : 0;
     }
 
-    void resetLayout(boolean hasVerticalHotseat) {
+    public void resetLayout(boolean hasVerticalHotseat) {
         removeAllViewsInLayout();
         mHasVerticalHotseat = hasVerticalHotseat;
-        InvariantDeviceProfile idp = mLauncher.getDeviceProfile().inv;
+        InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;
         if (hasVerticalHotseat) {
             setGridSize(1, idp.numHotseatIcons);
         } else {
@@ -71,15 +67,6 @@
     }
 
     @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        // We don't want any clicks to go through to the hotseat unless the workspace is in
-        // the normal state or an accessible drag is in progress.
-        return (!mLauncher.getWorkspace().workspaceIconsCanBeDragged()
-                && !mLauncher.getAccessibilityDelegate().isInAccessibleDrag())
-                || super.onInterceptTouchEvent(ev);
-    }
-
-    @Override
     public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
         target.gridX = info.cellX;
         target.gridY = info.cellY;
@@ -89,7 +76,7 @@
     @Override
     public void setInsets(Rect insets) {
         FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
-        DeviceProfile grid = mLauncher.getDeviceProfile();
+        DeviceProfile grid = mActivity.getDeviceProfile();
 
         if (grid.isVerticalBarLayout()) {
             lp.height = ViewGroup.LayoutParams.MATCH_PARENT;
diff --git a/src/com/android/launcher3/IconProvider.java b/src/com/android/launcher3/IconProvider.java
index ed8d03c..e1ef954 100644
--- a/src/com/android/launcher3/IconProvider.java
+++ b/src/com/android/launcher3/IconProvider.java
@@ -3,38 +3,19 @@
 import android.content.Context;
 import android.content.pm.LauncherActivityInfo;
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 
 import com.android.launcher3.util.ResourceBasedOverride;
 
-import java.util.Locale;
-
 public class IconProvider implements ResourceBasedOverride {
 
-    protected String mSystemState;
-
     public static IconProvider newInstance(Context context) {
-        IconProvider provider = Overrides.getObject(
-                IconProvider.class, context, R.string.icon_provider_class);
-        provider.updateSystemStateString(context);
-        return provider;
+        return Overrides.getObject(IconProvider.class, context, R.string.icon_provider_class);
     }
 
     public IconProvider() { }
 
-    public void updateSystemStateString(Context context) {
-        final String locale;
-        if (Utilities.ATLEAST_NOUGAT) {
-            locale = context.getResources().getConfiguration().getLocales().toLanguageTags();
-        } else {
-            locale = Locale.getDefault().toString();
-        }
-
-        mSystemState = locale + "," + Build.VERSION.SDK_INT;
-    }
-
-    public String getIconSystemState(String packageName) {
-        return mSystemState;
+    public String getSystemStateForPackage(String systemState, String packageName) {
+        return systemState;
     }
 
     /**
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 851454b..ea59fff 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -41,6 +41,7 @@
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
@@ -457,7 +458,7 @@
                     .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
                     .key(NAME_KEY).value(name);
                 if (icon != null) {
-                    byte[] iconByteArray = Utilities.flattenBitmap(icon);
+                    byte[] iconByteArray = GraphicsUtils.flattenBitmap(icon);
                     json = json.key(ICON_KEY).value(
                             Base64.encodeToString(
                                     iconByteArray, 0, iconByteArray.length, Base64.DEFAULT));
@@ -659,8 +660,8 @@
         info.applyFrom(iconInfo);
 
         info.title = Utilities.trim(name);
-        info.contentDescription = UserManagerCompat.getInstance(app.getContext())
-                .getBadgedLabelForUser(info.title, info.user);
+        info.contentDescription = app.getContext().getPackageManager()
+                .getUserBadgedLabel(info.title, info.user);
         info.intent = intent;
         return info;
     }
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 0b2f4d9..dafd5bb 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -17,22 +17,29 @@
 package com.android.launcher3;
 
 import static com.android.launcher3.config.FeatureFlags.APPLY_CONFIG_AT_RUNTIME;
+import static com.android.launcher3.Utilities.getDevicePrefs;
 
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.Configuration;
+import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
 import android.graphics.Point;
+import android.text.TextUtils;
+import android.util.AttributeSet;
 import android.util.DisplayMetrics;
 import android.util.Log;
+import android.util.SparseArray;
+import android.util.TypedValue;
 import android.util.Xml;
 import android.view.Display;
 import android.view.WindowManager;
 
 import com.android.launcher3.util.ConfigMonitor;
+import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.launcher3.util.Thunk;
+import com.android.launcher3.util.Themes;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -40,33 +47,36 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 public class InvariantDeviceProfile {
 
+    public static final String TAG = "IDP";
     // We do not need any synchronization for this variable as its only written on UI thread.
     public static final MainThreadInitializedObject<InvariantDeviceProfile> INSTANCE =
             new MainThreadInitializedObject<>(InvariantDeviceProfile::new);
 
+    private static final String KEY_IDP_GRID_NAME = "idp_grid_name";
+
     private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48;
 
     public static final int CHANGE_FLAG_GRID = 1 << 0;
-    public static final int CHANGE_FLAG_ICON_SIZE = 1 << 1;
+    public static final int CHANGE_FLAG_ICON_PARAMS = 1 << 1;
+
+    public static final String KEY_ICON_PATH_REF = "pref_icon_shape_path";
 
     // Constants that affects the interpolation curve between statically defined device profile
     // buckets.
-    private static float KNEARESTNEIGHBOR = 3;
-    private static float WEIGHT_POWER = 5;
+    private static final float KNEARESTNEIGHBOR = 3;
+    private static final float WEIGHT_POWER = 5;
 
     // used to offset float not being able to express extremely small weights in extreme cases.
-    private static float WEIGHT_EFFICIENT = 100000f;
+    private static final float WEIGHT_EFFICIENT = 100000f;
 
-    // Profile-defining invariant properties
-    private String name;
-    private float minWidthDps;
-    private float minHeightDps;
+    private static final int CONFIG_ICON_MASK_RES_ID = Resources.getSystem().getIdentifier(
+            "config_icon_mask", "string", "android");
 
     /**
      * Number of icons per row and column in the workspace.
@@ -80,17 +90,20 @@
     public int numFolderRows;
     public int numFolderColumns;
     public float iconSize;
+    public String iconShapePath;
     public float landscapeIconSize;
     public int iconBitmapSize;
     public int fillResIconDpi;
     public float iconTextSize;
 
+    private SparseArray<TypedValue> mExtraAttrs;
+
     /**
      * Number of icons inside the hotseat area.
      */
     public int numHotseatIcons;
 
-    int defaultLayoutId;
+    public int defaultLayoutId;
     int demoModeLayoutId;
 
     public DeviceProfile landscapeProfile;
@@ -105,37 +118,46 @@
     public InvariantDeviceProfile() {}
 
     private InvariantDeviceProfile(InvariantDeviceProfile p) {
-        this(p.name, p.minWidthDps, p.minHeightDps, p.numRows, p.numColumns,
-                p.numFolderRows, p.numFolderColumns,
-                p.iconSize, p.landscapeIconSize, p.iconTextSize, p.numHotseatIcons,
-                p.defaultLayoutId, p.demoModeLayoutId);
-    }
-
-    private InvariantDeviceProfile(String n, float w, float h, int r, int c, int fr, int fc,
-            float is, float lis, float its, int hs, int dlId, int dmlId) {
-        name = n;
-        minWidthDps = w;
-        minHeightDps = h;
-        numRows = r;
-        numColumns = c;
-        numFolderRows = fr;
-        numFolderColumns = fc;
-        iconSize = is;
-        landscapeIconSize = lis;
-        iconTextSize = its;
-        numHotseatIcons = hs;
-        defaultLayoutId = dlId;
-        demoModeLayoutId = dmlId;
+        numRows = p.numRows;
+        numColumns = p.numColumns;
+        numFolderRows = p.numFolderRows;
+        numFolderColumns = p.numFolderColumns;
+        iconSize = p.iconSize;
+        iconShapePath = p.iconShapePath;
+        landscapeIconSize = p.landscapeIconSize;
+        iconTextSize = p.iconTextSize;
+        numHotseatIcons = p.numHotseatIcons;
+        defaultLayoutId = p.defaultLayoutId;
+        demoModeLayoutId = p.demoModeLayoutId;
+        mExtraAttrs = p.mExtraAttrs;
     }
 
     @TargetApi(23)
     private InvariantDeviceProfile(Context context) {
-        initGrid(context);
+        initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null));
         mConfigMonitor = new ConfigMonitor(context,
                 APPLY_CONFIG_AT_RUNTIME.get() ? this::onConfigChanged : this::killProcess);
     }
 
-    private void initGrid(Context context) {
+    public InvariantDeviceProfile(Context context, String gridName) {
+        String newName = initGrid(context, gridName);
+        if (newName == null || !newName.equals(gridName)) {
+            throw new IllegalArgumentException("Unknown grid name");
+        }
+    }
+
+    /**
+     * Retrieve system defined or RRO overriden icon shape.
+     */
+    private static String getIconShapePath(Context context) {
+        if (CONFIG_ICON_MASK_RES_ID == 0) {
+            Log.e(TAG, "Icon mask res identifier failed to retrieve.");
+            return "";
+        }
+        return context.getResources().getString(CONFIG_ICON_MASK_RES_ID);
+    }
+
+    private String initGrid(Context context, String gridName) {
         WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
         Display display = wm.getDefaultDisplay();
         DisplayMetrics dm = new DisplayMetrics();
@@ -145,16 +167,18 @@
         Point largestSize = new Point();
         display.getCurrentSizeRange(smallestSize, largestSize);
 
+        ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
         // This guarantees that width < height
-        minWidthDps = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y), dm);
-        minHeightDps = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y), dm);
+        float minWidthDps = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y), dm);
+        float minHeightDps = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y), dm);
+        // Sort the profiles based on the closeness to the device size
+        Collections.sort(allOptions, (a, b) ->
+                Float.compare(dist(minWidthDps, minHeightDps, a.minWidthDps, a.minHeightDps),
+                        dist(minWidthDps, minHeightDps, b.minWidthDps, b.minHeightDps)));
+        DisplayOption interpolatedDisplayOption =
+                invDistWeightedInterpolate(minWidthDps,  minHeightDps, allOptions);
 
-        ArrayList<InvariantDeviceProfile> closestProfiles = findClosestDeviceProfiles(
-                minWidthDps, minHeightDps, getPredefinedDeviceProfiles(context));
-        InvariantDeviceProfile interpolatedDeviceProfileOut =
-                invDistWeightedInterpolate(minWidthDps,  minHeightDps, closestProfiles);
-
-        InvariantDeviceProfile closestProfile = closestProfiles.get(0);
+        GridOption closestProfile = allOptions.get(0).grid;
         numRows = closestProfile.numRows;
         numColumns = closestProfile.numColumns;
         numHotseatIcons = closestProfile.numHotseatIcons;
@@ -162,11 +186,18 @@
         demoModeLayoutId = closestProfile.demoModeLayoutId;
         numFolderRows = closestProfile.numFolderRows;
         numFolderColumns = closestProfile.numFolderColumns;
+        mExtraAttrs = closestProfile.extraAttrs;
 
-        iconSize = interpolatedDeviceProfileOut.iconSize;
-        landscapeIconSize = interpolatedDeviceProfileOut.landscapeIconSize;
+        if (!closestProfile.name.equals(gridName)) {
+            Utilities.getPrefs(context).edit()
+                    .putString(KEY_IDP_GRID_NAME, closestProfile.name).apply();
+        }
+
+        iconSize = interpolatedDisplayOption.iconSize;
+        iconShapePath = getIconShapePath(context);
+        landscapeIconSize = interpolatedDisplayOption.landscapeIconSize;
         iconBitmapSize = Utilities.pxFromDp(iconSize, dm);
-        iconTextSize = interpolatedDeviceProfileOut.iconTextSize;
+        iconTextSize = interpolatedDisplayOption.iconTextSize;
         fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
 
         // If the partner customization apk contains any grid overrides, apply them
@@ -194,23 +225,52 @@
         } else {
             defaultWallpaperSize = new Point(Math.max(smallSide * 2, largeSide), largeSide);
         }
+        return closestProfile.name;
+    }
+
+    @Nullable
+    public TypedValue getAttrValue(int attr) {
+        return mExtraAttrs == null ? null : mExtraAttrs.get(attr);
     }
 
     public void addOnChangeListener(OnIDPChangeListener listener) {
         mChangeListeners.add(listener);
     }
 
+    public void removeOnChangeListener(OnIDPChangeListener listener) {
+        mChangeListeners.remove(listener);
+    }
+
     private void killProcess(Context context) {
         Log.e("ConfigMonitor", "restarting launcher");
         android.os.Process.killProcess(android.os.Process.myPid());
     }
 
+    public void verifyConfigChangedInBackground(final Context context) {
+        String savedIconMaskPath = getDevicePrefs(context).getString(KEY_ICON_PATH_REF, "");
+        // Good place to check if grid size changed in themepicker when launcher was dead.
+        if (savedIconMaskPath.isEmpty()) {
+            getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context))
+                    .apply();
+        } else if (!savedIconMaskPath.equals(getIconShapePath(context))) {
+            getDevicePrefs(context).edit().putString(KEY_ICON_PATH_REF, getIconShapePath(context))
+                    .apply();
+            apply(context, CHANGE_FLAG_ICON_PARAMS);
+        }
+    }
+
+    public void setCurrentGrid(Context context, String gridName) {
+        Context appContext = context.getApplicationContext();
+        Utilities.getPrefs(appContext).edit().putString(KEY_IDP_GRID_NAME, gridName).apply();
+        new MainThreadExecutor().execute(() -> onConfigChanged(appContext));
+    }
+
     private void onConfigChanged(Context context) {
         // Config changes, what shall we do?
         InvariantDeviceProfile oldProfile = new InvariantDeviceProfile(this);
 
         // Re-init grid
-        initGrid(context);
+        initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null));
 
         int changeFlags = 0;
         if (numRows != oldProfile.numRows ||
@@ -221,10 +281,14 @@
             changeFlags |= CHANGE_FLAG_GRID;
         }
 
-        if (iconSize != oldProfile.iconSize || iconBitmapSize != oldProfile.iconBitmapSize) {
-            changeFlags |= CHANGE_FLAG_ICON_SIZE;
+        if (iconSize != oldProfile.iconSize || iconBitmapSize != oldProfile.iconBitmapSize ||
+                !iconShapePath.equals(oldProfile.iconShapePath)) {
+            changeFlags |= CHANGE_FLAG_ICON_PARAMS;
         }
+        apply(context, changeFlags);
+    }
 
+    private void apply(Context context, int changeFlags) {
         // Create a new config monitor
         mConfigMonitor.unregister();
         mConfigMonitor = new ConfigMonitor(context, this::onConfigChanged);
@@ -234,41 +298,53 @@
         }
     }
 
-    ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles(Context context) {
-        ArrayList<InvariantDeviceProfile> profiles = new ArrayList<>();
+    static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context, String gridName) {
+        ArrayList<DisplayOption> profiles = new ArrayList<>();
         try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
             final int depth = parser.getDepth();
             int type;
-
             while (((type = parser.next()) != XmlPullParser.END_TAG ||
                     parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
-                if ((type == XmlPullParser.START_TAG) && "profile".equals(parser.getName())) {
-                    TypedArray a = context.obtainStyledAttributes(
-                            Xml.asAttributeSet(parser), R.styleable.InvariantDeviceProfile);
-                    int numRows = a.getInt(R.styleable.InvariantDeviceProfile_numRows, 0);
-                    int numColumns = a.getInt(R.styleable.InvariantDeviceProfile_numColumns, 0);
-                    float iconSize = a.getFloat(R.styleable.InvariantDeviceProfile_iconSize, 0);
-                    profiles.add(new InvariantDeviceProfile(
-                            a.getString(R.styleable.InvariantDeviceProfile_name),
-                            a.getFloat(R.styleable.InvariantDeviceProfile_minWidthDps, 0),
-                            a.getFloat(R.styleable.InvariantDeviceProfile_minHeightDps, 0),
-                            numRows,
-                            numColumns,
-                            a.getInt(R.styleable.InvariantDeviceProfile_numFolderRows, numRows),
-                            a.getInt(R.styleable.InvariantDeviceProfile_numFolderColumns, numColumns),
-                            iconSize,
-                            a.getFloat(R.styleable.InvariantDeviceProfile_landscapeIconSize, iconSize),
-                            a.getFloat(R.styleable.InvariantDeviceProfile_iconTextSize, 0),
-                            a.getInt(R.styleable.InvariantDeviceProfile_numHotseatIcons, numColumns),
-                            a.getResourceId(R.styleable.InvariantDeviceProfile_defaultLayoutId, 0),
-                            a.getResourceId(R.styleable.InvariantDeviceProfile_demoModeLayoutId, 0)));
-                    a.recycle();
+                if ((type == XmlPullParser.START_TAG)
+                        && GridOption.TAG_NAME.equals(parser.getName())) {
+
+                    GridOption gridOption = new GridOption(context, Xml.asAttributeSet(parser));
+                    final int displayDepth = parser.getDepth();
+                    while (((type = parser.next()) != XmlPullParser.END_TAG ||
+                            parser.getDepth() > displayDepth)
+                            && type != XmlPullParser.END_DOCUMENT) {
+                        if ((type == XmlPullParser.START_TAG) && "display-option".equals(
+                                parser.getName())) {
+                            profiles.add(new DisplayOption(
+                                    gridOption, context, Xml.asAttributeSet(parser)));
+                        }
+                    }
                 }
             }
         } catch (IOException|XmlPullParserException e) {
             throw new RuntimeException(e);
         }
-        return profiles;
+
+        ArrayList<DisplayOption> filteredProfiles = new ArrayList<>();
+        if (!TextUtils.isEmpty(gridName)) {
+            for (DisplayOption option : profiles) {
+                if (gridName.equals(option.grid.name)) {
+                    filteredProfiles.add(option);
+                }
+            }
+        }
+        if (filteredProfiles.isEmpty()) {
+            // No grid found, use the default options
+            for (DisplayOption option : profiles) {
+                if (option.canBeDefault) {
+                    filteredProfiles.add(option);
+                }
+            }
+        }
+        if (filteredProfiles.isEmpty()) {
+            throw new RuntimeException("No display option with canBeDefault=true");
+        }
+        return filteredProfiles;
     }
 
     private int getLauncherIconDensity(int requiredSize) {
@@ -307,60 +383,28 @@
         }
     }
 
-    @Thunk float dist(float x0, float y0, float x1, float y1) {
+    private static float dist(float x0, float y0, float x1, float y1) {
         return (float) Math.hypot(x1 - x0, y1 - y0);
     }
 
-    /**
-     * Returns the closest device profiles ordered by closeness to the specified width and height
-     */
-    // Package private visibility for testing.
-    ArrayList<InvariantDeviceProfile> findClosestDeviceProfiles(
-            final float width, final float height, ArrayList<InvariantDeviceProfile> points) {
-
-        // Sort the profiles by their closeness to the dimensions
-        ArrayList<InvariantDeviceProfile> pointsByNearness = points;
-        Collections.sort(pointsByNearness, new Comparator<InvariantDeviceProfile>() {
-            public int compare(InvariantDeviceProfile a, InvariantDeviceProfile b) {
-                return Float.compare(dist(width, height, a.minWidthDps, a.minHeightDps),
-                        dist(width, height, b.minWidthDps, b.minHeightDps));
-            }
-        });
-
-        return pointsByNearness;
-    }
-
-    // Package private visibility for testing.
-    InvariantDeviceProfile invDistWeightedInterpolate(float width, float height,
-                ArrayList<InvariantDeviceProfile> points) {
+    @VisibleForTesting
+    static DisplayOption invDistWeightedInterpolate(float width, float height,
+                ArrayList<DisplayOption> points) {
         float weights = 0;
 
-        InvariantDeviceProfile p = points.get(0);
+        DisplayOption p = points.get(0);
         if (dist(width, height, p.minWidthDps, p.minHeightDps) == 0) {
             return p;
         }
 
-        InvariantDeviceProfile out = new InvariantDeviceProfile();
+        DisplayOption out = new DisplayOption();
         for (int i = 0; i < points.size() && i < KNEARESTNEIGHBOR; ++i) {
-            p = new InvariantDeviceProfile(points.get(i));
+            p = points.get(i);
             float w = weight(width, height, p.minWidthDps, p.minHeightDps, WEIGHT_POWER);
             weights += w;
-            out.add(p.multiply(w));
+            out.add(new DisplayOption().add(p).multiply(w));
         }
-        return out.multiply(1.0f/weights);
-    }
-
-    private void add(InvariantDeviceProfile p) {
-        iconSize += p.iconSize;
-        landscapeIconSize += p.landscapeIconSize;
-        iconTextSize += p.iconTextSize;
-    }
-
-    private InvariantDeviceProfile multiply(float w) {
-        iconSize *= w;
-        landscapeIconSize *= w;
-        iconTextSize *= w;
-        return this;
+        return out.multiply(1.0f / weights);
     }
 
     public DeviceProfile getDeviceProfile(Context context) {
@@ -368,7 +412,7 @@
                 == Configuration.ORIENTATION_LANDSCAPE ? landscapeProfile : portraitProfile;
     }
 
-    private float weight(float x0, float y0, float x1, float y1, float pow) {
+    private static float weight(float x0, float y0, float x1, float y1, float pow) {
         float d = dist(x0, y0, x1, y1);
         if (Float.compare(d, 0f) == 0) {
             return Float.POSITIVE_INFINITY;
@@ -409,4 +453,101 @@
 
         void onIdpChanged(int changeFlags, InvariantDeviceProfile profile);
     }
+
+
+    public static final class GridOption {
+
+        public static final String TAG_NAME = "grid-option";
+
+        public final String name;
+        public final int numRows;
+        public final int numColumns;
+
+        private final int numFolderRows;
+        private final int numFolderColumns;
+
+        private final int numHotseatIcons;
+
+        private final int defaultLayoutId;
+        private final int demoModeLayoutId;
+
+        private final SparseArray<TypedValue> extraAttrs;
+
+        public GridOption(Context context, AttributeSet attrs) {
+            TypedArray a = context.obtainStyledAttributes(
+                    attrs, R.styleable.GridDisplayOption);
+            name = a.getString(R.styleable.GridDisplayOption_name);
+            numRows = a.getInt(R.styleable.GridDisplayOption_numRows, 0);
+            numColumns = a.getInt(R.styleable.GridDisplayOption_numColumns, 0);
+
+            defaultLayoutId = a.getResourceId(
+                    R.styleable.GridDisplayOption_defaultLayoutId, 0);
+            demoModeLayoutId = a.getResourceId(
+                    R.styleable.GridDisplayOption_demoModeLayoutId, defaultLayoutId);
+            numHotseatIcons = a.getInt(
+                    R.styleable.GridDisplayOption_numHotseatIcons, numColumns);
+            numFolderRows = a.getInt(
+                    R.styleable.GridDisplayOption_numFolderRows, numRows);
+            numFolderColumns = a.getInt(
+                    R.styleable.GridDisplayOption_numFolderColumns, numColumns);
+            a.recycle();
+
+            extraAttrs = Themes.createValueMap(context, attrs,
+                    IntArray.wrap(R.styleable.GridDisplayOption));
+        }
+    }
+
+    private static final class DisplayOption {
+        private final GridOption grid;
+
+        private final String name;
+        private final float minWidthDps;
+        private final float minHeightDps;
+        private final boolean canBeDefault;
+
+        private float iconSize;
+        private float landscapeIconSize;
+        private float iconTextSize;
+
+        DisplayOption(GridOption grid, Context context, AttributeSet attrs) {
+            this.grid = grid;
+
+            TypedArray a = context.obtainStyledAttributes(
+                    attrs, R.styleable.ProfileDisplayOption);
+
+            name = a.getString(R.styleable.ProfileDisplayOption_name);
+            minWidthDps = a.getFloat(R.styleable.ProfileDisplayOption_minWidthDps, 0);
+            minHeightDps = a.getFloat(R.styleable.ProfileDisplayOption_minHeightDps, 0);
+            canBeDefault = a.getBoolean(
+                    R.styleable.ProfileDisplayOption_canBeDefault, false);
+
+            iconSize = a.getFloat(R.styleable.ProfileDisplayOption_iconSize, 0);
+            landscapeIconSize = a.getFloat(R.styleable.ProfileDisplayOption_landscapeIconSize,
+                    iconSize);
+            iconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_iconTextSize, 0);
+            a.recycle();
+        }
+
+        DisplayOption() {
+            grid = null;
+            name = null;
+            minWidthDps = 0;
+            minHeightDps = 0;
+            canBeDefault = false;
+        }
+
+        private DisplayOption multiply(float w) {
+            iconSize *= w;
+            landscapeIconSize *= w;
+            iconTextSize *= w;
+            return this;
+        }
+
+        private DisplayOption add(DisplayOption p) {
+            iconSize += p.iconSize;
+            landscapeIconSize += p.landscapeIconSize;
+            iconTextSize += p.iconTextSize;
+            return this;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index bffdd72..a130604 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -204,4 +204,13 @@
     public boolean isDisabled() {
         return false;
     }
+
+    public int getViewId() {
+        // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
+        // This cast is safe as long as the id < 0x00FFFFFF
+        // Since we jail all the dynamically generated views, there should be no clashes
+        // with any other views.
+        return id;
+    }
+
 }
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 4090320..ab83c6c 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -19,6 +19,7 @@
 import static android.content.pm.ActivityInfo.CONFIG_LOCALE;
 import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
 import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
+
 import static com.android.launcher3.AbstractFloatingView.TYPE_SNACKBAR;
 import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
 import static com.android.launcher3.LauncherState.ALL_APPS;
@@ -26,6 +27,8 @@
 import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_LAUNCHER_LOAD;
 import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
 import static com.android.launcher3.logging.LoggerUtils.newTarget;
+import static com.android.launcher3.util.RaceConditionTracker.ENTER;
+import static com.android.launcher3.util.RaceConditionTracker.EXIT;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -71,16 +74,18 @@
 import android.view.animation.OvershootInterpolator;
 import android.widget.Toast;
 
+import androidx.annotation.Nullable;
+
 import com.android.launcher3.DropTarget.DragObject;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.allapps.AllAppsContainerView;
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.allapps.DiscoveryBounce;
 import com.android.launcher3.anim.PropertyListBuilder;
-import com.android.launcher3.badge.BadgeInfo;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.LauncherAppsCompatVO;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.dot.DotInfo;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.dragndrop.DragView;
@@ -116,12 +121,14 @@
 import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.PendingRequestArgs;
+import com.android.launcher3.util.RaceConditionTracker;
 import com.android.launcher3.util.SystemUiController;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.util.TraceHelper;
 import com.android.launcher3.util.UiThreadHelper;
 import com.android.launcher3.util.ViewOnDrawExecutor;
+import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.views.OptionsPopupView;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
@@ -142,8 +149,6 @@
 import java.util.List;
 import java.util.Set;
 
-import androidx.annotation.Nullable;
-
 /**
  * Default launcher application.
  */
@@ -183,6 +188,7 @@
     private static final String RUNTIME_STATE_PENDING_ACTIVITY_RESULT = "launcher.activity_result";
     // Type: SparseArray<Parcelable>
     private static final String RUNTIME_STATE_WIDGET_PANEL = "launcher.widget_panel";
+    public static final String ON_CREATE_EVT = "Launcher.onCreate";
 
     private LauncherStateManager mStateManager;
 
@@ -254,6 +260,7 @@
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
+        RaceConditionTracker.onEvent(ON_CREATE_EVT, ENTER);
         if (DEBUG_STRICT_MODE) {
             StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                     .detectDiskReads()
@@ -348,6 +355,7 @@
         mRotationHelper.initialize();
 
         TraceHelper.endSection("Launcher-onCreate");
+        RaceConditionTracker.onEvent(ON_CREATE_EVT, EXIT);
     }
 
     @Override
@@ -459,21 +467,13 @@
         return !isWorkspaceLoading();
     }
 
-    public int getViewIdForItem(ItemInfo info) {
-        // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
-        // This cast is safe as long as the id < 0x00FFFFFF
-        // Since we jail all the dynamically generated views, there should be no clashes
-        // with any other views.
-        return (int) info.id;
-    }
-
     public PopupDataProvider getPopupDataProvider() {
         return mPopupDataProvider;
     }
 
     @Override
-    public BadgeInfo getBadgeInfoForItem(ItemInfo info) {
-        return mPopupDataProvider.getBadgeInfoForItem(info);
+    public DotInfo getDotInfoForItem(ItemInfo info) {
+        return mPopupDataProvider.getDotInfoForItem(info);
     }
 
     @Override
@@ -940,6 +940,7 @@
         mDropTargetBar.setup(mDragController);
 
         mAllAppsController.setupViews(mAppsView);
+        mHotseat.setOnInterceptTouchListener(mWorkspace::onInterceptHotseatTouch);
     }
 
     /**
@@ -1103,13 +1104,13 @@
         }
     };
 
-    public void updateIconBadges(final Set<PackageUserKey> updatedBadges) {
-        mWorkspace.updateIconBadges(updatedBadges);
-        mAppsView.getAppsStore().updateIconBadges(updatedBadges);
+    public void updateNotificationDots(final Set<PackageUserKey> updatedDots) {
+        mWorkspace.updateNotificationDots(updatedDots);
+        mAppsView.getAppsStore().updateNotificationDots(updatedDots);
 
         PopupContainerWithArrow popup = PopupContainerWithArrow.getOpen(Launcher.this);
         if (popup != null) {
-            popup.updateNotificationHeader(updatedBadges);
+            popup.updateNotificationHeader(updatedDots);
         }
     }
 
@@ -1376,6 +1377,11 @@
     }
 
     private void setWorkspaceLoading(boolean value) {
+        if (com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS
+                && com.android.launcher3.Utilities.IS_DEBUG_DEVICE) {
+            android.util.Log.d("b/117332845", "setWorkspaceLoading " + value + " @ " +
+                    android.util.Log.getStackTraceString(new Throwable()));
+        }
         mWorkspaceLoading = value;
     }
 
@@ -1611,7 +1617,7 @@
         } else if (mStateManager.getState() == LauncherState.OVERVIEW) {
             return StatsLogUtils.LAUNCHER_STATE_OVERVIEW;
         }
-        return StatsLogUtils.LAUNCHER_STATE_BACKGROUND;
+        return StatsLogUtils.LAUNCHER_STATE_HOME;
     }
 
     @Override
@@ -1753,7 +1759,6 @@
                 orderedScreenIds.indexOf(Workspace.FIRST_SCREEN_ID) != 0) {
             orderedScreenIds.removeValue(Workspace.FIRST_SCREEN_ID);
             orderedScreenIds.add(0, Workspace.FIRST_SCREEN_ID);
-            LauncherModel.updateWorkspaceScreenOrder(this, orderedScreenIds);
         } else if (!FeatureFlags.QSB_ON_FIRST_SCREEN.get()
                 && orderedScreenIds.isEmpty()) {
             // If there are no screens, we need to have an empty screen
@@ -2112,7 +2117,7 @@
      *
      * Implementation of the method from LauncherModel.Callbacks.
      */
-    public void finishBindingItems(int currentScreen) {
+    public void finishBindingItems(int pageBoundFirst) {
         TraceHelper.beginSection("finishBindingItems");
         mWorkspace.restoreInstanceStateForRemainingPages();
 
@@ -2127,7 +2132,8 @@
         InstallShortcutReceiver.disableAndFlushInstallQueue(
                 InstallShortcutReceiver.FLAG_LOADER_RUNNING, this);
 
-        mWorkspace.setCurrentPage(currentScreen);
+        // When undoing the removal of the last item on a page, return to that page.
+        mWorkspace.setCurrentPage(pageBoundFirst);
 
         TraceHelper.endSection("finishBindingItems");
     }
@@ -2392,6 +2398,13 @@
     }
 
     /**
+     * Just a wrapper around the type cast to allow easier tracking of calls.
+     */
+    public static <T extends Launcher> T cast(ActivityContext activityContext) {
+        return (T) activityContext;
+    }
+
+    /**
      * Callback for listening for onResume
      */
     public interface OnResumeCallback {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 338c20b..74fa447 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -16,14 +16,15 @@
 
 package com.android.launcher3;
 
+import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_PARAMS;
 import static com.android.launcher3.util.SecureSettingsObserver.newNotificationSettingsObserver;
-import static com.android.launcher3.InvariantDeviceProfile.CHANGE_FLAG_ICON_SIZE;
 
 import android.content.ComponentName;
 import android.content.ContentProviderClient;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.os.Handler;
 import android.util.Log;
 
 import com.android.launcher3.compat.LauncherAppsCompat;
@@ -50,7 +51,7 @@
     private final IconCache mIconCache;
     private final WidgetPreviewLoader mWidgetCache;
     private final InvariantDeviceProfile mInvariantDeviceProfile;
-    private final SecureSettingsObserver mNotificationBadgingObserver;
+    private final SecureSettingsObserver mNotificationDotsObserver;
 
     public static LauncherAppState getInstance(final Context context) {
         return INSTANCE.get(context);
@@ -97,20 +98,21 @@
         mContext.registerReceiver(mModel, filter);
         UserManagerCompat.getInstance(mContext).enableAndResetCache();
         mInvariantDeviceProfile.addOnChangeListener(this::onIdpChanged);
+        new Handler().post( () -> mInvariantDeviceProfile.verifyConfigChangedInBackground(context));
 
-        if (!mContext.getResources().getBoolean(R.bool.notification_badging_enabled)) {
-            mNotificationBadgingObserver = null;
+        if (!mContext.getResources().getBoolean(R.bool.notification_dots_enabled)) {
+            mNotificationDotsObserver = null;
         } else {
-            // Register an observer to rebind the notification listener when badging is re-enabled.
-            mNotificationBadgingObserver =
+            // Register an observer to rebind the notification listener when dots are re-enabled.
+            mNotificationDotsObserver =
                     newNotificationSettingsObserver(mContext, this::onNotificationSettingsChanged);
-            mNotificationBadgingObserver.register();
-            mNotificationBadgingObserver.dispatchOnChange();
+            mNotificationDotsObserver.register();
+            mNotificationDotsObserver.dispatchOnChange();
         }
     }
 
-    protected void onNotificationSettingsChanged(boolean isNotificationBadgingEnabled) {
-        if (isNotificationBadgingEnabled) {
+    protected void onNotificationSettingsChanged(boolean areNotificationDotsEnabled) {
+        if (areNotificationDotsEnabled) {
             NotificationListener.requestRebind(new ComponentName(
                     mContext, NotificationListener.class));
         }
@@ -121,7 +123,7 @@
             return;
         }
 
-        if ((changeFlags & CHANGE_FLAG_ICON_SIZE) != 0) {
+        if ((changeFlags & CHANGE_FLAG_ICON_PARAMS) != 0) {
             LauncherIcons.clearPool();
             mIconCache.updateIconParams(idp.fillResIconDpi, idp.iconBitmapSize);
         }
@@ -137,8 +139,8 @@
         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext);
         launcherApps.removeOnAppsChangedCallback(mModel);
         PackageInstallerCompat.getInstance(mContext).onStop();
-        if (mNotificationBadgingObserver != null) {
-            mNotificationBadgingObserver.unregister();
+        if (mNotificationDotsObserver != null) {
+            mNotificationDotsObserver.unregister();
         }
     }
 
diff --git a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
index b2b05b1..228c07e 100644
--- a/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetProviderInfo.java
@@ -58,19 +58,13 @@
     public void initSpans(Context context) {
         InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
 
-        Point paddingLand = idp.landscapeProfile.getTotalWorkspacePadding();
-        Point paddingPort = idp.portraitProfile.getTotalWorkspacePadding();
+        Point landCellSize = idp.landscapeProfile.getCellSize();
+        Point portCellSize = idp.portraitProfile.getCellSize();
 
         // Always assume we're working with the smallest span to make sure we
         // reserve enough space in both orientations.
-        float smallestCellWidth = DeviceProfile.calculateCellWidth(Math.min(
-                idp.landscapeProfile.widthPx - paddingLand.x,
-                idp.portraitProfile.widthPx - paddingPort.x),
-                idp.numColumns);
-        float smallestCellHeight = DeviceProfile.calculateCellWidth(Math.min(
-                idp.landscapeProfile.heightPx - paddingLand.y,
-                idp.portraitProfile.heightPx - paddingPort.y),
-                idp.numRows);
+        float smallestCellWidth = Math.min(landCellSize.x, portCellSize.x);
+        float smallestCellHeight = Math.min(landCellSize.y, portCellSize.y);
 
         // We want to account for the extra amount of padding that we are adding to the widget
         // to ensure that it gets the full amount of space that it has requested.
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index b3dabae..ebca2ea 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -20,12 +20,8 @@
 import static com.android.launcher3.config.FeatureFlags.IS_DOGFOOD_BUILD;
 
 import android.content.BroadcastReceiver;
-import android.content.ContentProviderOperation;
-import android.content.ContentResolver;
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
-import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -38,8 +34,8 @@
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
 import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.model.AddWorkspaceItemsTask;
 import com.android.launcher3.model.BaseModelUpdateTask;
 import com.android.launcher3.model.BgDataModel;
@@ -51,7 +47,6 @@
 import com.android.launcher3.model.PackageUpdatedTask;
 import com.android.launcher3.model.ShortcutsChangedTask;
 import com.android.launcher3.model.UserLockStateChangedTask;
-import com.android.launcher3.provider.LauncherDbUtils;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 import com.android.launcher3.util.ComponentKey;
@@ -70,7 +65,6 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.List;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.Executor;
@@ -96,10 +90,12 @@
     @Thunk boolean mIsLoaderTaskRunning;
 
     @Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
+    private static final Looper mWorkerLooper;
     static {
         sWorkerThread.start();
+        mWorkerLooper = sWorkerThread.getLooper();
     }
-    @Thunk static final Handler sWorker = new Handler(sWorkerThread.getLooper());
+    @Thunk static final Handler sWorker = new Handler(mWorkerLooper);
 
     // Indicates whether the current model data is valid or not.
     // We start off with everything not loaded. After that, we assume that
@@ -146,7 +142,7 @@
         public void bindItems(List<ItemInfo> shortcuts, boolean forceAnimateIcons);
         public void bindScreens(IntArray orderedScreenIds);
         public void finishFirstPageBind(ViewOnDrawExecutor executor);
-        public void finishBindingItems(int currentScreen);
+        public void finishBindingItems(int pageBoundFirst);
         public void bindAllApplications(ArrayList<AppInfo> apps);
         public void bindAppsAddedOrUpdated(ArrayList<AppInfo> apps);
         public void preAddApps();
@@ -267,53 +263,6 @@
     }
 
     /**
-     * Update the order of the workspace screens in the database. The array list contains
-     * a list of screen ids in the order that they should appear.
-     */
-    public static void updateWorkspaceScreenOrder(Context context, IntArray screens) {
-        final ContentResolver cr = context.getContentResolver();
-        final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
-
-        // Create a copy with only non-negative values
-        final IntArray screensCopy = new IntArray();
-        for (int i = 0; i < screens.size(); i++) {
-            int id = screens.get(i);
-            if (id >= 0) {
-                screensCopy.add(id);
-            }
-        }
-
-        Runnable r = new Runnable() {
-            @Override
-            public void run() {
-                ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
-                // Clear the table
-                ops.add(ContentProviderOperation.newDelete(uri).build());
-                int count = screensCopy.size();
-                for (int i = 0; i < count; i++) {
-                    ContentValues v = new ContentValues();
-                    int screenId = screensCopy.get(i);
-                    v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
-                    v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
-                    ops.add(ContentProviderOperation.newInsert(uri).withValues(v).build());
-                }
-
-                try {
-                    cr.applyBatch(LauncherProvider.AUTHORITY, ops);
-                } catch (Exception ex) {
-                    throw new RuntimeException(ex);
-                }
-
-                synchronized (sBgDataModel) {
-                    sBgDataModel.workspaceScreens.clear();
-                    sBgDataModel.workspaceScreens.addAll(screensCopy);
-                }
-            }
-        };
-        runOnWorkerThread(r);
-    }
-
-    /**
      * Set this as the current Launcher activity object for the loader.
      */
     public void initialize(Callbacks callbacks) {
@@ -423,11 +372,16 @@
         }
     }
 
+    public void forceReload() {
+        forceReload(-1);
+    }
+
     /**
      * Reloads the workspace items from the DB and re-binds the workspace. This should generally
      * not be called as DB updates are automatically followed by UI update
+     * @param synchronousBindPage The page to bind first. Can pass -1 to use the current page.
      */
-    public void forceReload() {
+    public void forceReload(int synchronousBindPage) {
         synchronized (mLock) {
             // Stop any existing loaders first, so they don't set mModelLoaded to true later
             stopLoader();
@@ -438,7 +392,10 @@
         // the next time launcher starts
         Callbacks callbacks = getCallback();
         if (callbacks != null) {
-            startLoader(callbacks.getCurrentWorkspaceScreen());
+            if (synchronousBindPage < 0) {
+                synchronousBindPage = callbacks.getCurrentWorkspaceScreen();
+            }
+            startLoader(synchronousBindPage);
         }
     }
 
@@ -517,18 +474,6 @@
         }
     }
 
-    /**
-     * Loads the workspace screen ids in an ordered list.
-     */
-    public static IntArray loadWorkspaceScreensDb(Context context) {
-        final ContentResolver contentResolver = context.getContentResolver();
-        final Uri screensUri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
-
-        // Get screens ordered by rank.
-        return LauncherDbUtils.getScreenIdsFromCursor(contentResolver.query(
-                screensUri, null, null, null, LauncherSettings.WorkspaceScreens.SCREEN_RANK));
-    }
-
     public void onInstallSessionCreated(final PackageInstallInfo sessionInfo) {
         enqueueModelUpdateTask(new BaseModelUpdateTask() {
             @Override
@@ -708,7 +653,7 @@
      * @return the looper for the worker thread which can be used to start background tasks.
      */
     public static Looper getWorkerLooper() {
-        return sWorkerThread.getLooper();
+        return mWorkerLooper;
     }
 
     public static void setWorkerPriority(final int priority) {
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 7d62ada..24dc17a 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -16,6 +16,9 @@
 
 package com.android.launcher3;
 
+import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
+import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
+
 import android.annotation.TargetApi;
 import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetManager;
@@ -32,6 +35,7 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
 import android.database.Cursor;
+import android.database.DatabaseUtils;
 import android.database.SQLException;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteQueryBuilder;
@@ -45,12 +49,12 @@
 import android.os.Process;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.BaseColumns;
 import android.text.TextUtils;
 import android.util.Log;
 
 import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback;
 import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.LauncherSettings.WorkspaceScreens;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.FileLog;
@@ -70,6 +74,7 @@
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Locale;
 
 public class LauncherProvider extends ContentProvider {
     private static final String TAG = "LauncherProvider";
@@ -79,10 +84,11 @@
 
     /**
      * Represents the schema of the database. Changes in scheme need not be backwards compatible.
+     * When increasing the scheme version, ensure that downgrade_schema.json is updated
      */
-    public static final int SCHEMA_VERSION = 27;
+    public static final int SCHEMA_VERSION = 28;
 
-    public static final String AUTHORITY = FeatureFlags.AUTHORITY;
+    public static final String AUTHORITY = BuildConfig.APPLICATION_ID + ".settings";
 
     static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
 
@@ -175,10 +181,10 @@
         if (values == null) {
             throw new RuntimeException("Error: attempting to insert null values");
         }
-        if (!values.containsKey(LauncherSettings.ChangeLogColumns._ID)) {
+        if (!values.containsKey(LauncherSettings.Favorites._ID)) {
             throw new RuntimeException("Error: attempting to add item without specifying an id");
         }
-        helper.checkId(table, values);
+        helper.checkId(values);
         return (int) db.insert(table, nullColumnHack, values);
     }
 
@@ -207,6 +213,7 @@
         addModifiedTime(initialValues);
         final int rowId = dbInsertAndCheck(mOpenHelper, db, args.table, null, initialValues);
         if (rowId < 0) return null;
+        mOpenHelper.onAddOrDeleteOp(db);
 
         uri = ContentUris.withAppendedId(uri, rowId);
         notifyListeners();
@@ -262,24 +269,7 @@
             }
         }
 
-        // Add screen id if not present
-        int screenId = values.getAsInteger(LauncherSettings.Favorites.SCREEN);
-        SQLiteStatement stmp = null;
-        try {
-            stmp = mOpenHelper.getWritableDatabase().compileStatement(
-                    "INSERT OR IGNORE INTO workspaceScreens (_id, screenRank) " +
-                            "select ?, (ifnull(MAX(screenRank), -1)+1) from workspaceScreens");
-            stmp.bindLong(1, screenId);
-
-            ContentValues valuesInserted = new ContentValues();
-            valuesInserted.put(LauncherSettings.BaseLauncherColumns._ID, stmp.executeInsert());
-            mOpenHelper.checkId(WorkspaceScreens.TABLE_NAME, valuesInserted);
-            return true;
-        } catch (Exception e) {
-            return false;
-        } finally {
-            Utilities.closeSilently(stmp);
-        }
+        return true;
     }
 
     @Override
@@ -296,6 +286,7 @@
                     return 0;
                 }
             }
+            mOpenHelper.onAddOrDeleteOp(db);
             t.commit();
         }
 
@@ -304,15 +295,30 @@
         return values.length;
     }
 
+    @TargetApi(Build.VERSION_CODES.M)
     @Override
     public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
             throws OperationApplicationException {
         createDbIfNotExists();
         try (SQLiteTransaction t = new SQLiteTransaction(mOpenHelper.getWritableDatabase())) {
-            ContentProviderResult[] result =  super.applyBatch(operations);
+            boolean isAddOrDelete = !Utilities.ATLEAST_MARSHMALLOW;
+
+            final int numOperations = operations.size();
+            final ContentProviderResult[] results = new ContentProviderResult[numOperations];
+            for (int i = 0; i < numOperations; i++) {
+                ContentProviderOperation op = operations.get(i);
+                results[i] = op.apply(this, results, i);
+
+                isAddOrDelete |= (op.isInsert() || op.isDelete()) &&
+                        results[i].count != null && results[i].count > 0;
+            }
+            if (isAddOrDelete) {
+                mOpenHelper.onAddOrDeleteOp(t.getDb());
+            }
+
             t.commit();
             reloadLauncherIfExternal();
-            return result;
+            return results;
         }
     }
 
@@ -329,6 +335,7 @@
         }
         int count = db.delete(args.table, args.where, args.args);
         if (count > 0) {
+            mOpenHelper.onAddOrDeleteOp(db);
             notifyListeners();
             reloadLauncherIfExternal();
         }
@@ -395,6 +402,17 @@
                 mOpenHelper.removeGhostWidgets(mOpenHelper.getWritableDatabase());
                 return null;
             }
+            case LauncherSettings.Settings.METHOD_NEW_TRANSACTION: {
+                Bundle result = new Bundle();
+                result.putBinder(LauncherSettings.Settings.EXTRA_VALUE,
+                        new SQLiteTransaction(mOpenHelper.getWritableDatabase()));
+                return result;
+            }
+            case LauncherSettings.Settings.METHOD_REFRESH_BACKUP_TABLE: {
+                mOpenHelper.mBackupTableExists =
+                        tableExists(mOpenHelper.getReadableDatabase(), Favorites.BACKUP_TABLE_NAME);
+                return null;
+            }
         }
         return null;
     }
@@ -404,7 +422,6 @@
      * @return Ids of deleted folders.
      */
     private IntArray deleteEmptyFolders() {
-        IntArray folderIds = new IntArray();
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         try (SQLiteTransaction t = new SQLiteTransaction(db)) {
             // Select folders whose id do not match any container value.
@@ -413,21 +430,19 @@
                     + LauncherSettings.Favorites._ID +  " NOT IN (SELECT " +
                             LauncherSettings.Favorites.CONTAINER + " FROM "
                                 + Favorites.TABLE_NAME + ")";
-            try (Cursor c = db.query(Favorites.TABLE_NAME,
-                    new String[] {LauncherSettings.Favorites._ID},
-                    selection, null, null, null, null)) {
-                LauncherDbUtils.iterateCursor(c, 0, folderIds);
-            }
+
+            IntArray folderIds = LauncherDbUtils.queryIntArray(db, Favorites.TABLE_NAME,
+                    Favorites._ID, selection, null, null);
             if (!folderIds.isEmpty()) {
                 db.delete(Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
                         LauncherSettings.Favorites._ID, folderIds), null);
             }
             t.commit();
+            return folderIds;
         } catch (SQLException ex) {
             Log.e(TAG, ex.getMessage(), ex);
-            folderIds.clear();
+            return new IntArray();
         }
-        return folderIds;
     }
 
     /**
@@ -438,7 +453,7 @@
     }
 
     @Thunk static void addModifiedTime(ContentValues values) {
-        values.put(LauncherSettings.ChangeLogColumns.MODIFIED, System.currentTimeMillis());
+        values.put(LauncherSettings.Favorites.MODIFIED, System.currentTimeMillis());
     }
 
     private void clearFlagEmptyDbCreated() {
@@ -545,18 +560,19 @@
         private final Context mContext;
         private int mMaxItemId = -1;
         private int mMaxScreenId = -1;
+        private boolean mBackupTableExists;
 
         DatabaseHelper(Context context, Handler widgetHostResetHandler) {
             this(context, widgetHostResetHandler, LauncherFiles.LAUNCHER_DB);
             // Table creation sometimes fails silently, which leads to a crash loop.
             // This way, we will try to create a table every time after crash, so the device
             // would eventually be able to recover.
-            if (!tableExists(Favorites.TABLE_NAME) || !tableExists(WorkspaceScreens.TABLE_NAME)) {
+            if (!tableExists(getReadableDatabase(), Favorites.TABLE_NAME)) {
                 Log.e(TAG, "Tables are missing after onCreate has been called. Trying to recreate");
                 // This operation is a no-op if the table already exists.
                 addFavoritesTable(getWritableDatabase(), true);
-                addWorkspacesTable(getWritableDatabase(), true);
             }
+            mBackupTableExists = tableExists(getReadableDatabase(), Favorites.BACKUP_TABLE_NAME);
 
             initIds();
         }
@@ -582,18 +598,6 @@
             }
         }
 
-        private boolean tableExists(String tableName) {
-            Cursor c = getReadableDatabase().query(
-                    true, "sqlite_master", new String[] {"tbl_name"},
-                    "tbl_name = ?", new String[] {tableName},
-                    null, null, null, null, null);
-            try {
-                return c.getCount() > 0;
-            } finally {
-                c.close();
-            }
-        }
-
         @Override
         public void onCreate(SQLiteDatabase db) {
             if (LOGD) Log.d(TAG, "creating new launcher database");
@@ -602,13 +606,19 @@
             mMaxScreenId = 0;
 
             addFavoritesTable(db, false);
-            addWorkspacesTable(db, false);
 
             // Fresh and clean launcher DB.
             mMaxItemId = initializeMaxItemId(db);
             onEmptyDbCreated();
         }
 
+        protected void onAddOrDeleteOp(SQLiteDatabase db) {
+            if (mBackupTableExists) {
+                dropTable(db, Favorites.BACKUP_TABLE_NAME);
+                mBackupTableExists = false;
+            }
+        }
+
         /**
          * Overriden in tests.
          */
@@ -633,46 +643,6 @@
             Favorites.addTableToDb(db, getDefaultUserSerial(), optional);
         }
 
-        private void addWorkspacesTable(SQLiteDatabase db, boolean optional) {
-            String ifNotExists = optional ? " IF NOT EXISTS " : "";
-            db.execSQL("CREATE TABLE " + ifNotExists + WorkspaceScreens.TABLE_NAME + " (" +
-                    LauncherSettings.WorkspaceScreens._ID + " INTEGER PRIMARY KEY," +
-                    LauncherSettings.WorkspaceScreens.SCREEN_RANK + " INTEGER," +
-                    LauncherSettings.ChangeLogColumns.MODIFIED + " INTEGER NOT NULL DEFAULT 0" +
-                    ");");
-        }
-
-        private void removeOrphanedItems(SQLiteDatabase db) {
-            // Delete items directly on the workspace who's screen id doesn't exist
-            //  "DELETE FROM favorites WHERE screen NOT IN (SELECT _id FROM workspaceScreens)
-            //   AND container = -100"
-            String removeOrphanedDesktopItems = "DELETE FROM " + Favorites.TABLE_NAME +
-                    " WHERE " +
-                    LauncherSettings.Favorites.SCREEN + " NOT IN (SELECT " +
-                    LauncherSettings.WorkspaceScreens._ID + " FROM " + WorkspaceScreens.TABLE_NAME + ")" +
-                    " AND " +
-                    LauncherSettings.Favorites.CONTAINER + " = " +
-                    LauncherSettings.Favorites.CONTAINER_DESKTOP;
-            db.execSQL(removeOrphanedDesktopItems);
-
-            // Delete items contained in folders which no longer exist (after above statement)
-            //  "DELETE FROM favorites  WHERE container <> -100 AND container <> -101 AND container
-            //   NOT IN (SELECT _id FROM favorites WHERE itemType = 2)"
-            String removeOrphanedFolderItems = "DELETE FROM " + Favorites.TABLE_NAME +
-                    " WHERE " +
-                    LauncherSettings.Favorites.CONTAINER + " <> " +
-                    LauncherSettings.Favorites.CONTAINER_DESKTOP +
-                    " AND "
-                    + LauncherSettings.Favorites.CONTAINER + " <> " +
-                    LauncherSettings.Favorites.CONTAINER_HOTSEAT +
-                    " AND "
-                    + LauncherSettings.Favorites.CONTAINER + " NOT IN (SELECT " +
-                    LauncherSettings.Favorites._ID + " FROM " + Favorites.TABLE_NAME +
-                    " WHERE " + LauncherSettings.Favorites.ITEM_TYPE + " = " +
-                    LauncherSettings.Favorites.ITEM_TYPE_FOLDER + ")";
-            db.execSQL(removeOrphanedFolderItems);
-        }
-
         @Override
         public void onOpen(SQLiteDatabase db) {
             super.onOpen(db);
@@ -681,8 +651,7 @@
             if (!schemaFile.exists()) {
                 handleOneTimeDataUpgrade(db);
             }
-            DbDowngradeHelper.updateSchemaFile(schemaFile, SCHEMA_VERSION, mContext,
-                    R.raw.downgrade_schema);
+            DbDowngradeHelper.updateSchemaFile(schemaFile, SCHEMA_VERSION, mContext);
         }
 
         /**
@@ -709,12 +678,8 @@
             switch (oldVersion) {
                 // The version cannot be lower that 12, as Launcher3 never supported a lower
                 // version of the DB.
-                case 12: {
-                    // With the new shrink-wrapped and re-orderable workspaces, it makes sense
-                    // to persist workspace screens and their relative order.
-                    mMaxScreenId = 0;
-                    addWorkspacesTable(db, false);
-                }
+                case 12:
+                    // No-op
                 case 13: {
                     try (SQLiteTransaction t = new SQLiteTransaction(db)) {
                         // Insert new column for holding widget provider name
@@ -728,15 +693,7 @@
                     }
                 }
                 case 14: {
-                    try (SQLiteTransaction t = new SQLiteTransaction(db)) {
-                        // Insert new column for holding update timestamp
-                        db.execSQL("ALTER TABLE favorites " +
-                                "ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
-                        db.execSQL("ALTER TABLE workspaceScreens " +
-                                "ADD COLUMN modified INTEGER NOT NULL DEFAULT 0;");
-                        t.commit();
-                    } catch (SQLException ex) {
-                        Log.e(TAG, ex.getMessage(), ex);
+                    if (!addIntegerColumn(db, Favorites.MODIFIED, 0)) {
                         // Old version remains, which means we wipe old data
                         break;
                     }
@@ -747,22 +704,15 @@
                         break;
                     }
                 }
-                case 16: {
+                case 16:
                     // No-op
-                }
-                case 17: {
+                case 17:
                     // No-op
-                }
-                case 18: {
-                    // Due to a data loss bug, some users may have items associated with screen ids
-                    // which no longer exist. Since this can cause other problems, and since the user
-                    // will never see these items anyway, we use database upgrade as an opportunity to
-                    // clean things up.
-                    removeOrphanedItems(db);
-                }
+                case 18:
+                    // No-op
                 case 19: {
                     // Add userId column
-                    if (!addProfileColumn(db)) {
+                    if (!addIntegerColumn(db, Favorites.PROFILE_ID, getDefaultUserSerial())) {
                         // Old version remains, which means we wipe old data
                         break;
                     }
@@ -772,10 +722,7 @@
                         break;
                     }
                 case 21:
-                    // Recreate workspace table with screen id a primary key
-                    if (!recreateWorkspaceTable(db)) {
-                        break;
-                    }
+                    // No-op
                 case 22: {
                     if (!addIntegerColumn(db, Favorites.OPTIONS, 0)) {
                         // Old version remains, which means we wipe old data
@@ -794,7 +741,30 @@
                             !LauncherDbUtils.prepareScreenZeroToHostQsb(mContext, db)) {
                         break;
                     }
-                case 27:
+                case 27: {
+                    // Update the favorites table so that the screen ids are ordered based on
+                    // workspace page rank.
+                    IntArray finalScreens = LauncherDbUtils.queryIntArray(db, "workspaceScreens",
+                            BaseColumns._ID, null, null, "screenRank");
+                    int[] original = finalScreens.toArray();
+                    Arrays.sort(original);
+                    String updatemap = "";
+                    for (int i = 0; i < original.length; i++) {
+                        if (finalScreens.get(i) != original[i]) {
+                            updatemap += String.format(Locale.ENGLISH, " WHEN %1$s=%2$d THEN %3$d",
+                                    Favorites.SCREEN, finalScreens.get(i), original[i]);
+                        }
+                    }
+                    if (!TextUtils.isEmpty(updatemap)) {
+                        String query = String.format(Locale.ENGLISH,
+                                "UPDATE %1$s SET %2$s=CASE %3$s ELSE %2$s END WHERE %4$s = %5$d",
+                                Favorites.TABLE_NAME, Favorites.SCREEN, updatemap,
+                                Favorites.CONTAINER, Favorites.CONTAINER_DESKTOP);
+                        db.execSQL(query);
+                    }
+                    dropTable(db, "workspaceScreens");
+                }
+                case 28:
                     // DB Upgraded successfully
                     return;
             }
@@ -821,8 +791,8 @@
          */
         public void createEmptyDB(SQLiteDatabase db) {
             try (SQLiteTransaction t = new SQLiteTransaction(db)) {
-                db.execSQL("DROP TABLE IF EXISTS " + Favorites.TABLE_NAME);
-                db.execSQL("DROP TABLE IF EXISTS " + WorkspaceScreens.TABLE_NAME);
+                dropTable(db, Favorites.TABLE_NAME);
+                dropTable(db, "workspaceScreens");
                 onCreate(db);
                 t.commit();
             }
@@ -845,17 +815,9 @@
                 Log.e(TAG, "getAppWidgetIds not supported", e);
                 return;
             }
-            final IntSet validWidgets = new IntSet();
-            try (Cursor c = db.query(Favorites.TABLE_NAME,
-                    new String[] {Favorites.APPWIDGET_ID },
-                    "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null, null, null)) {
-                while (c.moveToNext()) {
-                    validWidgets.add(c.getInt(0));
-                }
-            } catch (SQLException ex) {
-                Log.w(TAG, "Error getting widgets list", ex);
-                return;
-            }
+            final IntSet validWidgets = IntSet.wrap(LauncherDbUtils.queryIntArray(db,
+                    Favorites.TABLE_NAME, Favorites.APPWIDGET_ID,
+                    "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null));
             for (int widgetId : allWidgets) {
                 if (!validWidgets.contains(widgetId)) {
                     try {
@@ -910,46 +872,6 @@
             }
         }
 
-        /**
-         * Recreates workspace table and migrates data to the new table.
-         */
-        public boolean recreateWorkspaceTable(SQLiteDatabase db) {
-            try (SQLiteTransaction t = new SQLiteTransaction(db)) {
-                final IntArray sortedIDs;
-
-                try (Cursor c = db.query(WorkspaceScreens.TABLE_NAME,
-                        new String[] {LauncherSettings.WorkspaceScreens._ID},
-                        null, null, null, null,
-                        LauncherSettings.WorkspaceScreens.SCREEN_RANK)) {
-                    // Use LinkedHashSet so that ordering is preserved
-                    sortedIDs = LauncherDbUtils.getScreenIdsFromCursor(c);
-                }
-                db.execSQL("DROP TABLE IF EXISTS " + WorkspaceScreens.TABLE_NAME);
-                addWorkspacesTable(db, false);
-
-                // Add all screen ids back
-                int total = sortedIDs.size();
-                for (int i = 0; i < total; i++) {
-                    ContentValues values = new ContentValues();
-                    values.put(LauncherSettings.WorkspaceScreens._ID, sortedIDs.get(i));
-                    values.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
-                    addModifiedTime(values);
-                    db.insertOrThrow(WorkspaceScreens.TABLE_NAME, null, values);
-                }
-                t.commit();
-
-                mMaxScreenId = 0;
-                for (int i = 0; i < sortedIDs.size(); i++) {
-                    mMaxScreenId = Math.max(mMaxScreenId, sortedIDs.get(i));
-                }
-            } catch (SQLException ex) {
-                // Old version remains, which means we wipe old data
-                Log.e(TAG, ex.getMessage(), ex);
-                return false;
-            }
-            return true;
-        }
-
         @Thunk boolean updateFolderItemsRank(SQLiteDatabase db, boolean addRankColumn) {
             try (SQLiteTransaction t = new SQLiteTransaction(db)) {
                 if (addRankColumn) {
@@ -979,10 +901,6 @@
             return true;
         }
 
-        private boolean addProfileColumn(SQLiteDatabase db) {
-            return addIntegerColumn(db, Favorites.PROFILE_ID, getDefaultUserSerial());
-        }
-
         private boolean addIntegerColumn(SQLiteDatabase db, String columnName, long defaultValue) {
             try (SQLiteTransaction t = new SQLiteTransaction(db)) {
                 db.execSQL("ALTER TABLE favorites ADD COLUMN "
@@ -1018,17 +936,20 @@
             return dbInsertAndCheck(this, db, Favorites.TABLE_NAME, null, values);
         }
 
-        public void checkId(String table, ContentValues values) {
-            int id = values.getAsInteger(LauncherSettings.BaseLauncherColumns._ID);
-            if (WorkspaceScreens.TABLE_NAME.equals(table)) {
-                mMaxScreenId = Math.max(id, mMaxScreenId);
-            }  else {
-                mMaxItemId = Math.max(id, mMaxItemId);
+        public void checkId(ContentValues values) {
+            int id = values.getAsInteger(Favorites._ID);
+            mMaxItemId = Math.max(id, mMaxItemId);
+
+            Integer screen = values.getAsInteger(Favorites.SCREEN);
+            Integer container = values.getAsInteger(Favorites.CONTAINER);
+            if (screen != null && container != null
+                    && container.intValue() == Favorites.CONTAINER_DESKTOP) {
+                mMaxScreenId = Math.max(screen, mMaxScreenId);
             }
         }
 
         private int initializeMaxItemId(SQLiteDatabase db) {
-            return getMaxId(db, Favorites.TABLE_NAME);
+            return getMaxId(db, "SELECT MAX(%1$s) FROM %2$s", Favorites._ID, Favorites.TABLE_NAME);
         }
 
         // Generates a new ID to use for an workspace screen in your database. This method
@@ -1045,34 +966,18 @@
         }
 
         private int initializeMaxScreenId(SQLiteDatabase db) {
-            return getMaxId(db, WorkspaceScreens.TABLE_NAME);
+            return getMaxId(db, "SELECT MAX(%1$s) FROM %2$s WHERE %3$s = %4$d",
+                    Favorites.SCREEN, Favorites.TABLE_NAME, Favorites.CONTAINER,
+                    Favorites.CONTAINER_DESKTOP);
         }
 
         @Thunk int loadFavorites(SQLiteDatabase db, AutoInstallsLayout loader) {
-            IntArray screenIds = new IntArray();
             // TODO: Use multiple loaders with fall-back and transaction.
-            int count = loader.loadLayout(db, screenIds);
-
-            // Add the screens specified by the items above
-            int[] sortedScreenIds = screenIds.toArray();
-            Arrays.sort(sortedScreenIds);
-            int rank = 0;
-            ContentValues values = new ContentValues();
-            for (int id : sortedScreenIds) {
-                values.clear();
-                values.put(LauncherSettings.WorkspaceScreens._ID, id);
-                values.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, rank);
-                if (dbInsertAndCheck(this, db, WorkspaceScreens.TABLE_NAME, null, values) < 0) {
-                    throw new RuntimeException("Failed initialize screen table"
-                            + "from default layout");
-                }
-                rank++;
-            }
+            int count = loader.loadLayout(db, new IntArray());
 
             // Ensure that the max ids are initialized
             mMaxItemId = initializeMaxItemId(db);
             mMaxScreenId = initializeMaxScreenId(db);
-
             return count;
         }
     }
@@ -1080,22 +985,14 @@
     /**
      * @return the max _id in the provided table.
      */
-    @Thunk static int getMaxId(SQLiteDatabase db, String table) {
-        Cursor c = db.rawQuery("SELECT MAX(_id) FROM " + table, null);
-        // get the result
-        int id = -1;
-        if (c != null && c.moveToNext()) {
-            id = c.getInt(0);
+    @Thunk static int getMaxId(SQLiteDatabase db, String query, Object... args) {
+        int max = (int) DatabaseUtils.longForQuery(db,
+                String.format(Locale.ENGLISH, query, args),
+                null);
+        if (max < 0) {
+            throw new RuntimeException("Error: could not query max id");
         }
-        if (c != null) {
-            c.close();
-        }
-
-        if (id == -1) {
-            throw new RuntimeException("Error: could not query max id in " + table);
-        }
-
-        return id;
+        return max;
     }
 
     static class SqlArguments {
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index 0b12b15..e248ba0 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -26,16 +26,17 @@
  * Settings related utilities.
  */
 public class LauncherSettings {
-    /** Columns required on table staht will be subject to backup and restore. */
-    static interface ChangeLogColumns extends BaseColumns {
+
+    /**
+     * Favorites.
+     */
+    public static final class Favorites implements BaseColumns {
         /**
          * The time of the last update to this row.
          * <P>Type: INTEGER</P>
          */
         public static final String MODIFIED = "modified";
-    }
 
-    static public interface BaseLauncherColumns extends ChangeLogColumns {
         /**
          * Descriptive name of the gesture that can be displayed to the user.
          * <P>Type: TEXT</P>
@@ -84,38 +85,15 @@
          * <P>Type: BLOB</P>
          */
         public static final String ICON = "icon";
-    }
-
-    /**
-     * Workspace Screens.
-     *
-     * Tracks the order of workspace screens.
-     */
-    public static final class WorkspaceScreens implements ChangeLogColumns {
-
-        public static final String TABLE_NAME = "workspaceScreens";
-
-        /**
-         * The content:// style URL for this table
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://" +
-                LauncherProvider.AUTHORITY + "/" + TABLE_NAME);
-
-        /**
-         * The rank of this screen -- ie. how it is ordered relative to the other screens.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String SCREEN_RANK = "screenRank";
-    }
-
-    /**
-     * Favorites.
-     */
-    public static final class Favorites implements BaseLauncherColumns {
 
         public static final String TABLE_NAME = "favorites";
 
         /**
+         * Backup table created when when the favorites table is modified during grid migration
+         */
+        public static final String BACKUP_TABLE_NAME = "favorites_bakup";
+
+        /**
          * The content:// style URL for this table
          */
         public static final Uri CONTENT_URI = Uri.parse("content://" +
@@ -258,8 +236,13 @@
         public static final String OPTIONS = "options";
 
         public static void addTableToDb(SQLiteDatabase db, long myProfileId, boolean optional) {
+            addTableToDb(db, myProfileId, optional, TABLE_NAME);
+        }
+
+        public static void addTableToDb(SQLiteDatabase db, long myProfileId, boolean optional,
+                String tableName) {
             String ifNotExists = optional ? " IF NOT EXISTS " : "";
-            db.execSQL("CREATE TABLE " + ifNotExists + TABLE_NAME + " (" +
+            db.execSQL("CREATE TABLE " + ifNotExists + tableName + " (" +
                     "_id INTEGER PRIMARY KEY," +
                     "title TEXT," +
                     "intent TEXT," +
@@ -306,6 +289,10 @@
 
         public static final String METHOD_REMOVE_GHOST_WIDGETS = "remove_ghost_widgets";
 
+        public static final String METHOD_NEW_TRANSACTION = "new_db_transaction";
+
+        public static final String METHOD_REFRESH_BACKUP_TABLE = "refresh_backup_table";
+
         public static final String EXTRA_VALUE = "value";
 
         public static Bundle call(ContentResolver cr, String method) {
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index fe3df95..5d3ff53 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -420,8 +420,6 @@
         }
 
         UiFactory.onLauncherStateOrResumeChanged(mLauncher);
-
-        mLauncher.getDragLayer().requestFocus();
     }
 
     public void onWindowFocusChanged() {
diff --git a/src/com/android/launcher3/MainProcessInitializer.java b/src/com/android/launcher3/MainProcessInitializer.java
index a253893..93df025 100644
--- a/src/com/android/launcher3/MainProcessInitializer.java
+++ b/src/com/android/launcher3/MainProcessInitializer.java
@@ -20,7 +20,6 @@
 
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.FolderShape;
-import com.android.launcher3.graphics.IconShapeOverride;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.util.ResourceBasedOverride;
 
@@ -38,8 +37,7 @@
     protected void init(Context context) {
         FileLog.setDir(context.getApplicationContext().getFilesDir());
         FeatureFlags.initialize(context);
-        IconShapeOverride.apply(context);
         SessionCommitReceiver.applyDefaultUserPrefs(context);
-        FolderShape.init();
+        FolderShape.init(context);
     }
 }
diff --git a/src/com/android/launcher3/ProgressInterface.java b/src/com/android/launcher3/ProgressInterface.java
new file mode 100644
index 0000000..663d8ba
--- /dev/null
+++ b/src/com/android/launcher3/ProgressInterface.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3;
+
+/**
+ * Progress is defined as a value with range [0, 1], and is specific to each implementor.
+ * It is used when there is a transition from one state of the UI to another.
+ */
+public interface ProgressInterface {
+    void setProgress(float progress);
+    float getProgress();
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/SecondaryDropTarget.java b/src/com/android/launcher3/SecondaryDropTarget.java
index 6083415..0cf6e44 100644
--- a/src/com/android/launcher3/SecondaryDropTarget.java
+++ b/src/com/android/launcher3/SecondaryDropTarget.java
@@ -150,7 +150,7 @@
         Intent intent = null;
         UserHandle user = null;
         if (item != null &&
-                item.itemType == LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION) {
+                item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
             intent = item.getIntent();
             user = item.user;
         }
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index baf6d87..30f418d 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -26,6 +26,7 @@
 import android.view.ViewGroup;
 
 import com.android.launcher3.CellLayout.ContainerType;
+import com.android.launcher3.views.ActivityContext;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
 
 public class ShortcutAndWidgetContainer extends ViewGroup {
@@ -43,12 +44,12 @@
 
     private int mCountX;
 
-    private Launcher mLauncher;
+    private ActivityContext mActivity;
     private boolean mInvertIfRtl = false;
 
     public ShortcutAndWidgetContainer(Context context, @ContainerType int containerType) {
         super(context);
-        mLauncher = Launcher.getLauncher(context);
+        mActivity = ActivityContext.lookupContext(context);
         mWallpaperManager = WallpaperManager.getInstance(context);
         mContainerType = containerType;
     }
@@ -92,7 +93,7 @@
     public void setupLp(View child) {
         CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
         if (child instanceof LauncherAppWidgetHostView) {
-            DeviceProfile profile = mLauncher.getDeviceProfile();
+            DeviceProfile profile = mActivity.getDeviceProfile();
             lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX,
                     profile.appWidgetScale.x, profile.appWidgetScale.y);
         } else {
@@ -107,12 +108,12 @@
 
     public int getCellContentHeight() {
         return Math.min(getMeasuredHeight(),
-                mLauncher.getDeviceProfile().getCellHeight(mContainerType));
+                mActivity.getDeviceProfile().getCellHeight(mContainerType));
     }
 
     public void measureChild(View child) {
         CellLayout.LayoutParams lp = (CellLayout.LayoutParams) child.getLayoutParams();
-        final DeviceProfile profile = mLauncher.getDeviceProfile();
+        final DeviceProfile profile = mActivity.getDeviceProfile();
 
         if (child instanceof LauncherAppWidgetHostView) {
             lp.setup(mCellWidth, mCellHeight, invertLayoutHorizontally(), mCountX,
@@ -149,7 +150,7 @@
                     LauncherAppWidgetHostView lahv = (LauncherAppWidgetHostView) child;
 
                     // Scale and center the widget to fit within its cells.
-                    DeviceProfile profile = mLauncher.getDeviceProfile();
+                    DeviceProfile profile = mActivity.getDeviceProfile();
                     float scaleX = profile.appWidgetScale.x;
                     float scaleY = profile.appWidgetScale.y;
 
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 7717d91..c2c3287 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -24,7 +24,6 @@
 import android.text.TextUtils;
 
 import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 import com.android.launcher3.util.ContentWriter;
@@ -90,7 +89,7 @@
     private int mInstallProgress;
 
     public ShortcutInfo() {
-        itemType = LauncherSettings.BaseLauncherColumns.ITEM_TYPE_SHORTCUT;
+        itemType = LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT;
     }
 
     public ShortcutInfo(ShortcutInfo info) {
@@ -115,24 +114,23 @@
     @TargetApi(Build.VERSION_CODES.N)
     public ShortcutInfo(ShortcutInfoCompat shortcutInfo, Context context) {
         user = shortcutInfo.getUserHandle();
-        itemType = LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
+        itemType = Favorites.ITEM_TYPE_DEEP_SHORTCUT;
         updateFromDeepShortcutInfo(shortcutInfo, context);
     }
 
     @Override
     public void onAddToDatabase(ContentWriter writer) {
         super.onAddToDatabase(writer);
-        writer.put(LauncherSettings.BaseLauncherColumns.TITLE, title)
-                .put(LauncherSettings.BaseLauncherColumns.INTENT, getIntent())
-                .put(LauncherSettings.Favorites.RESTORED, status);
+        writer.put(Favorites.TITLE, title)
+                .put(Favorites.INTENT, getIntent())
+                .put(Favorites.RESTORED, status);
 
         if (!usingLowResIcon()) {
             writer.putIcon(iconBitmap, user);
         }
         if (iconResource != null) {
-            writer.put(LauncherSettings.BaseLauncherColumns.ICON_PACKAGE, iconResource.packageName)
-                    .put(LauncherSettings.BaseLauncherColumns.ICON_RESOURCE,
-                            iconResource.resourceName);
+            writer.put(Favorites.ICON_PACKAGE, iconResource.packageName)
+                    .put(Favorites.ICON_RESOURCE, iconResource.resourceName);
         }
     }
 
@@ -172,8 +170,7 @@
         if (TextUtils.isEmpty(label)) {
             label = shortcutInfo.getShortLabel();
         }
-        contentDescription = UserManagerCompat.getInstance(context)
-                .getBadgedLabelForUser(label, user);
+        contentDescription = context.getPackageManager().getUserBadgedLabel(label, user);
         if (shortcutInfo.isEnabled()) {
             runtimeStatusFlags &= ~FLAG_DISABLED_BY_PUBLISHER;
         } else {
@@ -191,7 +188,7 @@
     @Override
     public ComponentName getTargetComponent() {
         ComponentName cn = super.getTargetComponent();
-        if (cn == null && (itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT
+        if (cn == null && (itemType == Favorites.ITEM_TYPE_SHORTCUT
                 || hasStatusFlag(FLAG_SUPPORTS_WEB_UI))) {
             // Legacy shortcuts and promise icons with web UI may not have a componentName but just
             // a packageName. In that case create a dummy componentName instead of adding additional
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index d11cfcb..a0f005c 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -31,6 +31,7 @@
 import android.graphics.Bitmap;
 import android.graphics.Matrix;
 import android.graphics.Paint;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.RectF;
 import android.os.Build;
@@ -357,25 +358,6 @@
     }
 
     /**
-     * Compresses the bitmap to a byte array for serialization.
-     */
-    public static byte[] flattenBitmap(Bitmap bitmap) {
-        // Try go guesstimate how much space the icon will take when serialized
-        // to avoid unnecessary allocations/copies during the write.
-        int size = bitmap.getWidth() * bitmap.getHeight() * 4;
-        ByteArrayOutputStream out = new ByteArrayOutputStream(size);
-        try {
-            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
-            out.flush();
-            out.close();
-            return out.toByteArray();
-        } catch (IOException e) {
-            Log.w(TAG, "Could not write bitmap");
-            return null;
-        }
-    }
-
-    /**
      * Trims the string, removing all whitespace at the beginning and end of the string.
      * Non-breaking whitespaces are also removed.
      */
@@ -606,6 +588,21 @@
         handler.sendMessage(msg);
     }
 
+    /**
+     * Parses a string encoded using {@link #getPointString(int, int)}
+     */
+    public static Point parsePoint(String point) {
+        String[] split = point.split(",");
+        return new Point(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
+    }
+
+    /**
+     * Encodes a point to string to that it can be persisted atomically.
+     */
+    public static String getPointString(int x, int y) {
+        return String.format(Locale.ENGLISH, "%d,%d", x, y);
+    }
+
     public interface Consumer<T> {
         void accept(T var1);
     }
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index d47dcee..050849c 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -31,6 +31,7 @@
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.icons.GraphicsUtils;
 import com.android.launcher3.icons.LauncherIcons;
 import com.android.launcher3.icons.ShadowGenerator;
 import com.android.launcher3.icons.IconCache;
@@ -149,7 +150,7 @@
         values.put(CacheDb.COLUMN_PACKAGE, key.componentName.getPackageName());
         values.put(CacheDb.COLUMN_VERSION, versions[0]);
         values.put(CacheDb.COLUMN_LAST_UPDATED, versions[1]);
-        values.put(CacheDb.COLUMN_PREVIEW_BITMAP, Utilities.flattenBitmap(preview));
+        values.put(CacheDb.COLUMN_PREVIEW_BITMAP, GraphicsUtils.flattenBitmap(preview));
         mDb.insertOrReplace(values);
     }
 
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 7a8d984..eb26961 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -63,7 +63,7 @@
 import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.badge.FolderBadgeInfo;
+import com.android.launcher3.dot.FolderDotInfo;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dragndrop.DragController;
@@ -79,7 +79,6 @@
 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.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -107,8 +106,8 @@
  */
 public class Workspace extends PagedView<WorkspacePageIndicator>
         implements DropTarget, DragSource, View.OnTouchListener,
-        DragController.DragListener, Insettable, LauncherStateManager.StateHandler {
-    private static final String TAG = "Launcher.Workspace";
+        DragController.DragListener, Insettable, LauncherStateManager.StateHandler,
+        WorkspaceLayoutManager {
 
     /** The value that {@link #mTransitionProgress} must be greater than for
      * {@link #transitionStateShouldAllowDrop()} to return true. */
@@ -130,11 +129,6 @@
     public static final boolean MAP_NO_RECURSE = false;
     public static final boolean MAP_RECURSE = true;
 
-    // The screen id used for the empty screen always present to the right.
-    public static final int EXTRA_EMPTY_SCREEN_ID = -201;
-    // The is the first screen. It is always present, even if its empty.
-    public static final int FIRST_SCREEN_ID = 0;
-
     private LayoutTransition mLayoutTransition;
     @Thunk final WallpaperManager mWallpaperManager;
 
@@ -475,6 +469,13 @@
         super.onViewAdded(child);
     }
 
+    protected boolean onInterceptHotseatTouch(View v, MotionEvent ev) {
+        // We don't want any clicks to go through to the hotseat unless the workspace is in
+        // the normal state or an accessible drag is in progress.
+        return !workspaceIconsCanBeDragged()
+                && !mLauncher.getAccessibilityDelegate().isInAccessibleDrag();
+    }
+
     /**
      * Initializes and binds the first page
      * @param qsb an existing qsb to recycle or null.
@@ -618,9 +619,6 @@
             // if this is the last screen, convert it to the empty screen
             mWorkspaceScreens.put(EXTRA_EMPTY_SCREEN_ID, finalScreen);
             mScreenOrder.add(EXTRA_EMPTY_SCREEN_ID);
-
-            // Update the model if we have changed any screens
-            LauncherModel.updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
         }
     }
 
@@ -727,12 +725,20 @@
         mWorkspaceScreens.put(newId, cl);
         mScreenOrder.add(newId);
 
-        // Update the model for the new screen
-        LauncherModel.updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
-
         return newId;
     }
 
+    @Override
+    public Hotseat getHotseat() {
+        return mLauncher.getHotseat();
+    }
+
+    @Override
+    public void onAddDropTarget(DropTarget target) {
+        mDragController.addDropTarget(target);
+    }
+
+    @Override
     public CellLayout getScreenWithId(int screenId) {
         return mWorkspaceScreens.get(screenId);
     }
@@ -816,120 +822,12 @@
             }
         }
 
-        if (!removeScreens.isEmpty()) {
-            // Update the model if we have changed any screens
-            mLauncher.getModelWriter().enqueueDeleteRunnable(
-                    () -> LauncherModel.updateWorkspaceScreenOrder(mLauncher, mScreenOrder));
-
-        }
-
         if (pageShift >= 0) {
             setCurrentPage(currentPage - pageShift);
         }
     }
 
     /**
-     * At bind time, we use the rank (screenId) to compute x and y for hotseat items.
-     * See {@link #addInScreen}.
-     */
-    public void addInScreenFromBind(View child, ItemInfo info) {
-        int x = info.cellX;
-        int y = info.cellY;
-        if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
-            int screenId = (int) info.screenId;
-            x = mLauncher.getHotseat().getCellXFromOrder(screenId);
-            y = mLauncher.getHotseat().getCellYFromOrder(screenId);
-        }
-        addInScreen(child, info.container, info.screenId, x, y, info.spanX, info.spanY);
-    }
-
-    /**
-     * Adds the specified child in the specified screen based on the {@param info}
-     * See {@link #addInScreen(View, int, int, int, int, int, int)}.
-     */
-    public void addInScreen(View child, ItemInfo info) {
-        addInScreen(child, info.container, info.screenId, info.cellX, info.cellY,
-                info.spanX, info.spanY);
-    }
-
-    /**
-     * Adds the specified child in the specified screen. The position and dimension of
-     * the child are defined by x, y, spanX and spanY.
-     *
-     * @param child The child to add in one of the workspace's screens.
-     * @param screenId The screen in which to add the child.
-     * @param x The X position of the child in the screen's grid.
-     * @param y The Y position of the child in the screen's grid.
-     * @param spanX The number of cells spanned horizontally by the child.
-     * @param spanY The number of cells spanned vertically by the child.
-     */
-    private void addInScreen(View child, int container, int screenId, int x, int y,
-            int spanX, int spanY) {
-        if (container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-            if (getScreenWithId(screenId) == null) {
-                Log.e(TAG, "Skipping child, screenId " + screenId + " not found");
-                // DEBUGGING - Print out the stack trace to see where we are adding from
-                new Throwable().printStackTrace();
-                return;
-            }
-        }
-        if (screenId == EXTRA_EMPTY_SCREEN_ID) {
-            // This should never happen
-            throw new RuntimeException("Screen id should not be EXTRA_EMPTY_SCREEN_ID");
-        }
-
-        final CellLayout layout;
-        if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
-            layout = mLauncher.getHotseat();
-
-            // Hide folder title in the hotseat
-            if (child instanceof FolderIcon) {
-                ((FolderIcon) child).setTextVisible(false);
-            }
-        } else {
-            // Show folder title if not in the hotseat
-            if (child instanceof FolderIcon) {
-                ((FolderIcon) child).setTextVisible(true);
-            }
-            layout = getScreenWithId(screenId);
-        }
-
-        ViewGroup.LayoutParams genericLp = child.getLayoutParams();
-        CellLayout.LayoutParams lp;
-        if (genericLp == null || !(genericLp instanceof CellLayout.LayoutParams)) {
-            lp = new CellLayout.LayoutParams(x, y, spanX, spanY);
-        } else {
-            lp = (CellLayout.LayoutParams) genericLp;
-            lp.cellX = x;
-            lp.cellY = y;
-            lp.cellHSpan = spanX;
-            lp.cellVSpan = spanY;
-        }
-
-        if (spanX < 0 && spanY < 0) {
-            lp.isLockedToGrid = false;
-        }
-
-        // Get the canonical child id to uniquely represent this view in this screen
-        ItemInfo info = (ItemInfo) child.getTag();
-        int childId = mLauncher.getViewIdForItem(info);
-
-        boolean markCellsAsOccupied = !(child instanceof Folder);
-        if (!layout.addViewToCellLayout(child, -1, childId, lp, markCellsAsOccupied)) {
-            // TODO: This branch occurs when the workspace is adding views
-            // outside of the defined grid
-            // maybe we should be deleting these items from the LauncherModel?
-            Log.e(TAG, "Failed to add to item at (" + lp.cellX + "," + lp.cellY + ") to CellLayout");
-        }
-
-        child.setHapticFeedbackEnabled(false);
-        child.setOnLongClickListener(ItemLongClickListener.INSTANCE_WORKSPACE);
-        if (child instanceof DropTarget) {
-            mDragController.addDropTarget((DropTarget) child);
-        }
-    }
-
-    /**
      * Called directly from a CellLayout (not by the framework), after we've been added as a
      * listener via setOnInterceptTouchEventListener(). This allows us to tell the CellLayout
      * that it should intercept touch events, which is not something that is normally supported.
@@ -1625,7 +1523,7 @@
             mDragViewVisualCenter = d.getVisualCenter(mDragViewVisualCenter);
 
             // We want the point to be mapped to the dragTarget.
-            mapPointFromDropLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
+            mapPointFromDropLayout(dropTargetLayout, mDragViewVisualCenter);
 
             int spanX;
             int spanY;
@@ -1827,7 +1725,7 @@
 
         // We want the point to be mapped to the dragTarget.
         if (dropTargetLayout != null) {
-            mapPointFromDropLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
+            mapPointFromDropLayout(dropTargetLayout, mDragViewVisualCenter);
         }
 
         boolean droppedOnOriginalCell = false;
@@ -2255,7 +2153,7 @@
         // Handle the drag over
         if (mDragTargetLayout != null) {
             // We want the point to be mapped to the dragTarget.
-            mapPointFromDropLayout(mLauncher.getHotseat(), mDragViewVisualCenter);
+            mapPointFromDropLayout(mDragTargetLayout, mDragViewVisualCenter);
 
             int minSpanX = item.spanX;
             int minSpanY = item.spanY;
@@ -2442,7 +2340,7 @@
             this.cellY = cellY;
 
             BubbleTextView cell = (BubbleTextView) layout.getChildAt(cellX, cellY);
-            bg.setup(mLauncher, null, cell.getMeasuredWidth(), cell.getPaddingTop());
+            bg.setup(mLauncher, mLauncher, null, cell.getMeasuredWidth(), cell.getPaddingTop());
 
             // The full preview background should appear behind the icon
             bg.isClipping = false;
@@ -3161,16 +3059,16 @@
         });
     }
 
-    public void updateIconBadges(final Set<PackageUserKey> updatedBadges) {
+    public void updateNotificationDots(final Set<PackageUserKey> updatedDots) {
         final PackageUserKey packageUserKey = new PackageUserKey(null, null);
         final IntSet folderIds = new IntSet();
         mapOverItems(MAP_RECURSE, new ItemOperator() {
             @Override
             public boolean evaluate(ItemInfo info, View v) {
-                if (info instanceof ShortcutInfo && v instanceof BubbleTextView
-                        && packageUserKey.updateFromItemInfo(info)) {
-                    if (updatedBadges.contains(packageUserKey)) {
-                        ((BubbleTextView) v).applyBadgeState(info, true /* animate */);
+                if (info instanceof ShortcutInfo && v instanceof BubbleTextView) {
+                    if (!packageUserKey.updateFromItemInfo(info)
+                            || updatedDots.contains(packageUserKey)) {
+                        ((BubbleTextView) v).applyDotState(info, true /* animate */);
                         folderIds.add(info.container);
                     }
                 }
@@ -3185,11 +3083,11 @@
             public boolean evaluate(ItemInfo info, View v) {
                 if (info instanceof FolderInfo && folderIds.contains(info.id)
                         && v instanceof FolderIcon) {
-                    FolderBadgeInfo folderBadgeInfo = new FolderBadgeInfo();
+                    FolderDotInfo folderDotInfo = new FolderDotInfo();
                     for (ShortcutInfo si : ((FolderInfo) info).contents) {
-                        folderBadgeInfo.addBadgeInfo(mLauncher.getBadgeInfoForItem(si));
+                        folderDotInfo.addDotInfo(mLauncher.getDotInfoForItem(si));
                     }
-                    ((FolderIcon) v).setBadgeInfo(folderBadgeInfo);
+                    ((FolderIcon) v).setDotInfo(folderDotInfo);
                 }
                 // process all the shortcuts
                 return false;
diff --git a/src/com/android/launcher3/WorkspaceLayoutManager.java b/src/com/android/launcher3/WorkspaceLayoutManager.java
new file mode 100644
index 0000000..ea2d4d0
--- /dev/null
+++ b/src/com/android/launcher3/WorkspaceLayoutManager.java
@@ -0,0 +1,141 @@
+/*
+ * 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;
+
+import android.util.Log;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.launcher3.folder.Folder;
+import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.touch.ItemLongClickListener;
+
+public interface WorkspaceLayoutManager {
+
+    String TAG = "Launcher.Workspace";
+
+    // The screen id used for the empty screen always present to the right.
+    int EXTRA_EMPTY_SCREEN_ID = -201;
+    // The is the first screen. It is always present, even if its empty.
+    int FIRST_SCREEN_ID = 0;
+
+    /**
+     * At bind time, we use the rank (screenId) to compute x and y for hotseat items.
+     * See {@link #addInScreen}.
+     */
+    default void addInScreenFromBind(View child, ItemInfo info) {
+        int x = info.cellX;
+        int y = info.cellY;
+        if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
+            int screenId = info.screenId;
+            x = getHotseat().getCellXFromOrder(screenId);
+            y = getHotseat().getCellYFromOrder(screenId);
+        }
+        addInScreen(child, info.container, info.screenId, x, y, info.spanX, info.spanY);
+    }
+
+    /**
+     * Adds the specified child in the specified screen based on the {@param info}
+     * See {@link #addInScreen(View, int, int, int, int, int, int)}.
+     */
+    default void addInScreen(View child, ItemInfo info) {
+        addInScreen(child, info.container, info.screenId, info.cellX, info.cellY,
+                info.spanX, info.spanY);
+    }
+
+    /**
+     * Adds the specified child in the specified screen. The position and dimension of
+     * the child are defined by x, y, spanX and spanY.
+     *
+     * @param child The child to add in one of the workspace's screens.
+     * @param screenId The screen in which to add the child.
+     * @param x The X position of the child in the screen's grid.
+     * @param y The Y position of the child in the screen's grid.
+     * @param spanX The number of cells spanned horizontally by the child.
+     * @param spanY The number of cells spanned vertically by the child.
+     */
+    default void addInScreen(View child, int container, int screenId, int x, int y,
+            int spanX, int spanY) {
+        if (container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+            if (getScreenWithId(screenId) == null) {
+                Log.e(TAG, "Skipping child, screenId " + screenId + " not found");
+                // DEBUGGING - Print out the stack trace to see where we are adding from
+                new Throwable().printStackTrace();
+                return;
+            }
+        }
+        if (screenId == EXTRA_EMPTY_SCREEN_ID) {
+            // This should never happen
+            throw new RuntimeException("Screen id should not be EXTRA_EMPTY_SCREEN_ID");
+        }
+
+        final CellLayout layout;
+        if (container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
+            layout = getHotseat();
+
+            // Hide folder title in the hotseat
+            if (child instanceof FolderIcon) {
+                ((FolderIcon) child).setTextVisible(false);
+            }
+        } else {
+            // Show folder title if not in the hotseat
+            if (child instanceof FolderIcon) {
+                ((FolderIcon) child).setTextVisible(true);
+            }
+            layout = getScreenWithId(screenId);
+        }
+
+        ViewGroup.LayoutParams genericLp = child.getLayoutParams();
+        CellLayout.LayoutParams lp;
+        if (genericLp == null || !(genericLp instanceof CellLayout.LayoutParams)) {
+            lp = new CellLayout.LayoutParams(x, y, spanX, spanY);
+        } else {
+            lp = (CellLayout.LayoutParams) genericLp;
+            lp.cellX = x;
+            lp.cellY = y;
+            lp.cellHSpan = spanX;
+            lp.cellVSpan = spanY;
+        }
+
+        if (spanX < 0 && spanY < 0) {
+            lp.isLockedToGrid = false;
+        }
+
+        // Get the canonical child id to uniquely represent this view in this screen
+        ItemInfo info = (ItemInfo) child.getTag();
+        int childId = info.getViewId();
+
+        boolean markCellsAsOccupied = !(child instanceof Folder);
+        if (!layout.addViewToCellLayout(child, -1, childId, lp, markCellsAsOccupied)) {
+            // TODO: This branch occurs when the workspace is adding views
+            // outside of the defined grid
+            // maybe we should be deleting these items from the LauncherModel?
+            Log.e(TAG, "Failed to add to item at (" + lp.cellX + "," + lp.cellY + ") to CellLayout");
+        }
+
+        child.setHapticFeedbackEnabled(false);
+        child.setOnLongClickListener(ItemLongClickListener.INSTANCE_WORKSPACE);
+        if (child instanceof DropTarget) {
+            onAddDropTarget((DropTarget) child);
+        }
+    }
+
+    Hotseat getHotseat();
+
+    CellLayout getScreenWithId(int screenId);
+
+    default void onAddDropTarget(DropTarget target) { }
+}
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 3d15c75..86b96b4 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -304,6 +304,8 @@
 
         mNavBarScrimHeight = insets.bottom;
         InsettableFrameLayout.dispatchInsets(this, insets);
+        mLauncher.getAllAppsController()
+                .setScrollRangeDelta(mSearchUiManager.getScrollRangeDelta(insets));
     }
 
     @Override
diff --git a/src/com/android/launcher3/allapps/AllAppsStore.java b/src/com/android/launcher3/allapps/AllAppsStore.java
index dc34892..cf0f2a3 100644
--- a/src/com/android/launcher3/allapps/AllAppsStore.java
+++ b/src/com/android/launcher3/allapps/AllAppsStore.java
@@ -121,12 +121,12 @@
         mIconContainers.remove(container);
     }
 
-    public void updateIconBadges(Set<PackageUserKey> updatedBadges) {
+    public void updateNotificationDots(Set<PackageUserKey> updatedDots) {
         updateAllIcons((child) -> {
             if (child.getTag() instanceof ItemInfo) {
                 ItemInfo info = (ItemInfo) child.getTag();
-                if (mTempKey.updateFromItemInfo(info) && updatedBadges.contains(mTempKey)) {
-                    child.applyBadgeState(info, true /* animate */);
+                if (mTempKey.updateFromItemInfo(info) && updatedDots.contains(mTempKey)) {
+                    child.applyDotState(info, true /* animate */);
                 }
             }
         });
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 2d6be7b..e8e93fe 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -1,7 +1,6 @@
 package com.android.launcher3.allapps;
 
 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.LauncherState.VERTICAL_SWIPE_INDICATOR;
@@ -15,9 +14,7 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
 import android.util.Property;
-import android.view.View;
 import android.view.animation.Interpolator;
 
 import com.android.launcher3.DeviceProfile;
@@ -26,13 +23,17 @@
 import com.android.launcher3.LauncherState;
 import com.android.launcher3.LauncherStateManager.AnimationConfig;
 import com.android.launcher3.LauncherStateManager.StateHandler;
+import com.android.launcher3.ProgressInterface;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.AnimationSuccessListener;
 import com.android.launcher3.anim.AnimatorSetBuilder;
+import com.android.launcher3.anim.SpringObjectAnimator;
 import com.android.launcher3.anim.PropertySetter;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.views.ScrimView;
 
+import androidx.dynamicanimation.animation.FloatPropertyCompat;
+
 /**
  * Handles AllApps view transition.
  * 1) Slides all apps view using direct manipulation
@@ -43,7 +44,8 @@
  * If release velocity < THRES1, snap according to either top or bottom depending on whether it's
  * closer to top or closer to the page indicator.
  */
-public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener {
+public class AllAppsTransitionController implements StateHandler, OnDeviceProfileChangeListener,
+        ProgressInterface {
 
     public static final Property<AllAppsTransitionController, Float> ALL_APPS_PROGRESS =
             new Property<AllAppsTransitionController, Float>(Float.class, "allAppsProgress") {
@@ -59,6 +61,19 @@
         }
     };
 
+    public static final FloatPropertyCompat<AllAppsTransitionController> ALL_APPS_PROGRESS_SPRING
+            = new FloatPropertyCompat<AllAppsTransitionController>("allAppsProgressSpring") {
+        @Override
+        public float getValue(AllAppsTransitionController controller) {
+            return controller.mProgress;
+        }
+
+        @Override
+        public void setValue(AllAppsTransitionController controller, float progress) {
+            controller.setProgress(progress);
+        }
+    };
+
     private AllAppsContainerView mAppsView;
     private ScrimView mScrimView;
 
@@ -112,6 +127,7 @@
      * @see #setState(LauncherState)
      * @see #setStateWithAnimation(LauncherState, AnimatorSetBuilder, AnimationConfig)
      */
+    @Override
     public void setProgress(float progress) {
         mProgress = progress;
         mScrimView.setProgress(progress);
@@ -136,6 +152,7 @@
         }
     }
 
+    @Override
     public float getProgress() {
         return mProgress;
     }
@@ -174,8 +191,8 @@
         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);
+        Animator anim = new SpringObjectAnimator<>(this, ALL_APPS_PROGRESS_SPRING,
+                "allAppsSpringFromAATC", 1f / mShiftRange, mProgress, targetProgress);
         anim.setDuration(config.duration);
         anim.setInterpolator(builder.getInterpolator(ANIM_VERTICAL_PROGRESS, interpolator));
         anim.addListener(getProgressAnimatorListener());
@@ -221,7 +238,7 @@
     /**
      * Updates the total scroll range but does not update the UI.
      */
-    public void setScrollRangeDelta(float delta) {
+    void setScrollRangeDelta(float delta) {
         mScrollRangeDelta = delta;
         mShiftRange = mLauncher.getDeviceProfile().heightPx - mScrollRangeDelta;
 
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderRow.java b/src/com/android/launcher3/allapps/FloatingHeaderRow.java
new file mode 100644
index 0000000..922e4f1
--- /dev/null
+++ b/src/com/android/launcher3/allapps/FloatingHeaderRow.java
@@ -0,0 +1,58 @@
+/*
+ * 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.allapps;
+
+import android.graphics.Rect;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.anim.PropertySetter;
+
+/**
+ * A abstract representation of a row in all-apps view
+ */
+public interface FloatingHeaderRow {
+
+    FloatingHeaderRow[] NO_ROWS = new FloatingHeaderRow[0];
+
+    void setup(FloatingHeaderView parent, FloatingHeaderRow[] allRows, boolean tabsHidden);
+
+    void setInsets(Rect insets, DeviceProfile grid);
+
+    int getExpectedHeight();
+
+    /**
+     * Returns true if the row should draw based on its current position and layout.
+     */
+    boolean shouldDraw();
+
+    /**
+     * Returns true if the view has anything worth drawing. This is different than
+     * {@link #shouldDraw()} as this is called earlier in the layout to determine the view
+     * position.
+     */
+    boolean hasVisibleContent();
+
+    void setContentVisibility(boolean hasHeaderExtra, boolean hasContent,
+            PropertySetter setter, Interpolator fadeInterpolator);
+
+    /**
+     * Scrolls the content vertically.
+     */
+    void setVerticalScroll(int scroll, boolean isScrolledOut);
+
+    Class<? extends FloatingHeaderRow> getTypeClass();
+}
diff --git a/src/com/android/launcher3/allapps/FloatingHeaderView.java b/src/com/android/launcher3/allapps/FloatingHeaderView.java
index 90e195b..66dced9 100644
--- a/src/com/android/launcher3/allapps/FloatingHeaderView.java
+++ b/src/com/android/launcher3/allapps/FloatingHeaderView.java
@@ -19,28 +19,34 @@
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.util.ArrayMap;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.animation.Interpolator;
 import android.widget.LinearLayout;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Insettable;
+import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.anim.PropertySetter;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
 import com.android.systemui.plugins.AllAppsRow;
+import com.android.systemui.plugins.AllAppsRow.OnHeightUpdatedListener;
 import com.android.systemui.plugins.PluginListener;
 
 import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
 import java.util.Map;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.recyclerview.widget.RecyclerView;
+
 public class FloatingHeaderView extends LinearLayout implements
-        ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow> {
+        ValueAnimator.AnimatorUpdateListener, PluginListener<AllAppsRow>, Insettable,
+        OnHeightUpdatedListener {
 
     private final Rect mClip = new Rect(0, 0, Integer.MAX_VALUE, Integer.MAX_VALUE);
     private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
@@ -62,17 +68,18 @@
 
             int current = -mCurrentRV.getCurrentScrollY();
             moved(current);
-            apply();
+            applyVerticalMove();
         }
     };
 
+    private final int mHeaderTopPadding;
+
+    protected final Map<AllAppsRow, PluginHeaderRow> mPluginRows = new ArrayMap<>();
+
     protected ViewGroup mTabLayout;
     private AllAppsRecyclerView mMainRV;
     private AllAppsRecyclerView mWorkRV;
     private AllAppsRecyclerView mCurrentRV;
-    protected final Map<AllAppsRow, View> mPluginRows;
-    // Contains just the values of the above map so we can iterate without extracting a new list.
-    protected final List<View> mPluginRowViews;
     private ViewGroup mParent;
     private boolean mHeaderCollapsed;
     private int mSnappedScrolledY;
@@ -85,20 +92,42 @@
     protected int mMaxTranslation;
     private boolean mMainRVActive = true;
 
+    private boolean mCollapsed = false;
+
+    // This is initialized once during inflation and stays constant after that. Fixed views
+    // cannot be added or removed dynamically.
+    private FloatingHeaderRow[] mFixedRows = FloatingHeaderRow.NO_ROWS;
+
+    // Array of all fixed rows and plugin rows. This is initialized every time a plugin is
+    // enabled or disabled, and represent the current set of all rows.
+    private FloatingHeaderRow[] mAllRows = FloatingHeaderRow.NO_ROWS;
+
     public FloatingHeaderView(@NonNull Context context) {
         this(context, null);
     }
 
     public FloatingHeaderView(@NonNull Context context, @Nullable AttributeSet attrs) {
         super(context, attrs);
-        mPluginRows = new HashMap<>();
-        mPluginRowViews = new ArrayList<>();
+        mHeaderTopPadding = context.getResources()
+                .getDimensionPixelSize(R.dimen.all_apps_header_top_padding);
     }
 
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
         mTabLayout = findViewById(R.id.tabs);
+
+        // Find all floating header rows.
+        ArrayList<FloatingHeaderRow> rows = new ArrayList<>();
+        int count = getChildCount();
+        for (int i = 0; i < count; i++) {
+            View child = getChildAt(i);
+            if (child instanceof FloatingHeaderRow) {
+                rows.add((FloatingHeaderRow) child);
+            }
+        }
+        mFixedRows = rows.toArray(new FloatingHeaderRow[rows.size()]);
+        mAllRows = mFixedRows;
     }
 
     @Override
@@ -114,50 +143,70 @@
         PluginManagerWrapper.INSTANCE.get(getContext()).removePluginListener(this);
     }
 
-    @Override
-    public void onPluginConnected(AllAppsRow allAppsRowPlugin, Context context) {
-        mPluginRows.put(allAppsRowPlugin, null);
-        setupPluginRows();
-        allAppsRowPlugin.setOnHeightUpdatedListener(this::onPluginRowHeightUpdated);
+    private void recreateAllRowsArray() {
+        int pluginCount = mPluginRows.size();
+        if (pluginCount == 0) {
+            mAllRows = mFixedRows;
+        } else {
+            int count = mFixedRows.length;
+            mAllRows = new FloatingHeaderRow[count + pluginCount];
+            for (int i = 0; i < count; i++) {
+                mAllRows[i] = mFixedRows[i];
+            }
+
+            for (PluginHeaderRow row : mPluginRows.values()) {
+                mAllRows[count] = row;
+                count++;
+            }
+        }
     }
 
-    protected void onPluginRowHeightUpdated() {
+    @Override
+    public void onPluginConnected(AllAppsRow allAppsRowPlugin, Context context) {
+        PluginHeaderRow headerRow = new PluginHeaderRow(allAppsRowPlugin, this);
+        addView(headerRow.mView, indexOfChild(mTabLayout));
+        mPluginRows.put(allAppsRowPlugin, headerRow);
+        recreateAllRowsArray();
+        allAppsRowPlugin.setOnHeightUpdatedListener(this);
+    }
+
+    @Override
+    public void onHeightUpdated() {
+        int oldMaxHeight = mMaxTranslation;
+        updateExpectedHeight();
+
+        if (mMaxTranslation != oldMaxHeight) {
+            AllAppsContainerView parent = (AllAppsContainerView) getParent();
+            if (parent != null) {
+                parent.setupHeader();
+            }
+        }
     }
 
     @Override
     public void onPluginDisconnected(AllAppsRow plugin) {
-        View pluginRowView = mPluginRows.get(plugin);
-        removeView(pluginRowView);
+        PluginHeaderRow row = mPluginRows.get(plugin);
+        removeView(row.mView);
         mPluginRows.remove(plugin);
-        mPluginRowViews.remove(pluginRowView);
-        onPluginRowHeightUpdated();
+        recreateAllRowsArray();
+        onHeightUpdated();
     }
 
     public void setup(AllAppsContainerView.AdapterHolder[] mAH, boolean tabsHidden) {
+        for (FloatingHeaderRow row : mAllRows) {
+            row.setup(this, mAllRows, tabsHidden);
+        }
+        updateExpectedHeight();
+
         mTabsHidden = tabsHidden;
         mTabLayout.setVisibility(tabsHidden ? View.GONE : View.VISIBLE);
         mMainRV = setupRV(mMainRV, mAH[AllAppsContainerView.AdapterHolder.MAIN].recyclerView);
         mWorkRV = setupRV(mWorkRV, mAH[AllAppsContainerView.AdapterHolder.WORK].recyclerView);
         mParent = (ViewGroup) mMainRV.getParent();
         setMainActive(mMainRVActive || mWorkRV == null);
-        setupPluginRows();
         reset(false);
     }
 
-    private void setupPluginRows() {
-        for (Map.Entry<AllAppsRow, View> rowPluginEntry : mPluginRows.entrySet()) {
-            if (rowPluginEntry.getValue() == null) {
-                View pluginRow = rowPluginEntry.getKey().setup(this);
-                addView(pluginRow, indexOfChild(mTabLayout));
-                rowPluginEntry.setValue(pluginRow);
-                mPluginRowViews.add(pluginRow);
-            }
-        }
-        for (View plugin : mPluginRowViews) {
-            plugin.setVisibility(mHeaderCollapsed ? GONE : VISIBLE);
-        }
-    }
-
     private AllAppsRecyclerView setupRV(AllAppsRecyclerView old, AllAppsRecyclerView updated) {
         if (old != updated && updated != null ) {
             updated.addOnScrollListener(mOnScrollListener);
@@ -165,6 +214,16 @@
         return updated;
     }
 
+    private void updateExpectedHeight() {
+        mMaxTranslation = 0;
+        if (mCollapsed) {
+            return;
+        }
+        for (FloatingHeaderRow row : mAllRows) {
+            mMaxTranslation += row.getExpectedHeight();
+        }
+    }
+
     public void setMainActive(boolean active) {
         mCurrentRV = active ? mMainRV : mWorkRV;
         mMainRVActive = active;
@@ -208,12 +267,21 @@
         }
     }
 
-    protected void applyScroll(int uncappedY, int currentY) { }
-
-    protected void apply() {
+    protected void applyVerticalMove() {
         int uncappedTranslationY = mTranslationY;
         mTranslationY = Math.max(mTranslationY, -mMaxTranslation);
-        applyScroll(uncappedTranslationY, mTranslationY);
+
+        if (mCollapsed || uncappedTranslationY < mTranslationY - mHeaderTopPadding) {
+            // we hide it completely if already capped (for opening search anim)
+            for (FloatingHeaderRow row : mAllRows) {
+                row.setVerticalScroll(0, true /* isScrolledOut */);
+            }
+        } else {
+            for (FloatingHeaderRow row : mAllRows) {
+                row.setVerticalScroll(uncappedTranslationY, false /* isScrolledOut */);
+            }
+        }
+
         mTabLayout.setTranslationY(mTranslationY);
         mClip.top = mMaxTranslation + mTranslationY;
         // clipping on a draw might cause additional redraw
@@ -223,6 +291,16 @@
         }
     }
 
+    /**
+     * Hides all the floating rows
+     */
+    public void setCollapsed(boolean collapse) {
+        if (mCollapsed == collapse) return;
+
+        mCollapsed = collapse;
+        onHeightUpdated();
+    }
+
     public void reset(boolean animate) {
         if (mAnimator.isStarted()) {
             mAnimator.cancel();
@@ -234,7 +312,7 @@
             mAnimator.start();
         } else {
             mTranslationY = 0;
-            apply();
+            applyVerticalMove();
         }
         mHeaderCollapsed = false;
         mSnappedScrolledY = -mMaxTranslation;
@@ -248,7 +326,7 @@
     @Override
     public void onAnimationUpdate(ValueAnimator animation) {
         mTranslationY = (Integer) animation.getAnimatedValue();
-        apply();
+        applyVerticalMove();
     }
 
     @Override
@@ -287,8 +365,12 @@
 
     public void setContentVisibility(boolean hasHeader, boolean hasContent, PropertySetter setter,
             Interpolator fadeInterpolator) {
-        setter.setViewAlpha(this, hasContent ? 1 : 0, fadeInterpolator);
+        for (FloatingHeaderRow row : mAllRows) {
+            row.setContentVisibility(hasHeader, hasContent, setter, fadeInterpolator);
+        }
+
         allowTouchForwarding(hasContent);
+        setter.setFloat(mTabLayout, ALPHA, hasContent ? 1 : 0, fadeInterpolator);
     }
 
     protected void allowTouchForwarding(boolean allow) {
@@ -296,6 +378,11 @@
     }
 
     public boolean hasVisibleContent() {
+        for (FloatingHeaderRow row : mAllRows) {
+            if (row.hasVisibleContent()) {
+                return true;
+            }
+        }
         return false;
     }
 
@@ -303,6 +390,23 @@
     public boolean hasOverlappingRendering() {
         return false;
     }
+
+    @Override
+    public void setInsets(Rect insets) {
+        DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
+        for (FloatingHeaderRow row : mAllRows) {
+            row.setInsets(insets, grid);
+        }
+    }
+
+    public <T extends FloatingHeaderRow> T findFixedRowByType(Class<T> type) {
+        for (FloatingHeaderRow row : mAllRows) {
+            if (row.getTypeClass() == type) {
+                return (T) row;
+            }
+        }
+        return null;
+    }
 }
 
 
diff --git a/src/com/android/launcher3/allapps/PluginHeaderRow.java b/src/com/android/launcher3/allapps/PluginHeaderRow.java
new file mode 100644
index 0000000..b283ff4
--- /dev/null
+++ b/src/com/android/launcher3/allapps/PluginHeaderRow.java
@@ -0,0 +1,85 @@
+/*
+ * 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.allapps;
+
+import static android.view.View.ALPHA;
+import static android.view.View.INVISIBLE;
+import static android.view.View.VISIBLE;
+
+import android.graphics.Rect;
+import android.view.View;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.anim.PropertySetter;
+import com.android.systemui.plugins.AllAppsRow;
+
+/**
+ * Wrapper over an {@link AllAppsRow} plugin with {@link FloatingHeaderRow} interface so that
+ * it can be easily added in {@link FloatingHeaderView}.
+ */
+public class PluginHeaderRow implements FloatingHeaderRow {
+
+    private final AllAppsRow mPlugin;
+    final View mView;
+
+    PluginHeaderRow(AllAppsRow plugin, FloatingHeaderView parent) {
+        mPlugin = plugin;
+        mView = mPlugin.setup(parent);
+    }
+
+    @Override
+    public void setup(FloatingHeaderView parent, FloatingHeaderRow[] allRows,
+            boolean tabsHidden) { }
+
+    @Override
+    public void setInsets(Rect insets, DeviceProfile grid) { }
+
+    @Override
+    public int getExpectedHeight() {
+        return mPlugin.getExpectedHeight();
+    }
+
+    @Override
+    public boolean shouldDraw() {
+        return true;
+    }
+
+    @Override
+    public boolean hasVisibleContent() {
+        return true;
+    }
+
+    @Override
+    public void setContentVisibility(boolean hasHeaderExtra, boolean hasContent,
+            PropertySetter setter, Interpolator fadeInterpolator) {
+        // Don't use setViewAlpha as we want to control the visibility ourselves.
+        setter.setFloat(mView, ALPHA, hasContent ? 1 : 0, fadeInterpolator);
+    }
+
+    @Override
+    public void setVerticalScroll(int scroll, boolean isScrolledOut) {
+        mView.setVisibility(isScrolledOut ? INVISIBLE : VISIBLE);
+        if (!isScrolledOut) {
+            mView.setTranslationY(scroll);
+        }
+    }
+
+    @Override
+    public Class<PluginHeaderRow> getTypeClass() {
+        return PluginHeaderRow.class;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
index 51b90f7..cf9a088 100644
--- a/src/com/android/launcher3/allapps/SearchUiManager.java
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -15,6 +15,7 @@
  */
 package com.android.launcher3.allapps;
 
+import android.graphics.Rect;
 import android.view.KeyEvent;
 import android.view.animation.Interpolator;
 
@@ -42,6 +43,11 @@
     void preDispatchKeyEvent(KeyEvent keyEvent);
 
     /**
+     * Returns the vertical shift for the all-apps view, so that it aligns with the hotseat.
+     */
+    float getScrollRangeDelta(Rect insets);
+
+    /**
      * Called as part of state transition to update the content UI
      */
     void setContentVisibility(int visibleElements, PropertySetter setter,
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
index b1e23d4..1ff484b 100644
--- a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -208,13 +208,16 @@
         MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
         mlp.topMargin = Math.round(Math.max(-mFixedTranslationY, insets.top - mMarginTopAdjusting));
         requestLayout();
+    }
 
-        DeviceProfile dp = mLauncher.getDeviceProfile();
-        if (dp.isVerticalBarLayout()) {
-            mLauncher.getAllAppsController().setScrollRangeDelta(0);
+    @Override
+    public float getScrollRangeDelta(Rect insets) {
+        if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+            return 0;
         } else {
-            mLauncher.getAllAppsController().setScrollRangeDelta(
-                    insets.bottom + mlp.topMargin + mFixedTranslationY);
+            int topMargin = Math.round(Math.max(
+                    -mFixedTranslationY, insets.top - mMarginTopAdjusting));
+           return insets.bottom + topMargin + mFixedTranslationY;
         }
     }
 
diff --git a/src/com/android/launcher3/anim/AlphaUpdateListener.java b/src/com/android/launcher3/anim/AlphaUpdateListener.java
index a3d02d9..8ac9d66 100644
--- a/src/com/android/launcher3/anim/AlphaUpdateListener.java
+++ b/src/com/android/launcher3/anim/AlphaUpdateListener.java
@@ -20,6 +20,7 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.view.View;
+import android.view.ViewGroup;
 
 /**
  * A convenience class to update a view's visibility state after an alpha animation.
@@ -55,7 +56,15 @@
             view.setVisibility(View.INVISIBLE);
         } else if (view.getAlpha() > ALPHA_CUTOFF_THRESHOLD
                 && view.getVisibility() != View.VISIBLE) {
-            view.setVisibility(View.VISIBLE);
+            if (view instanceof ViewGroup) {
+                ViewGroup viewGroup = ((ViewGroup) view);
+                int oldFocusability = viewGroup.getDescendantFocusability();
+                viewGroup.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
+                viewGroup.setVisibility(View.VISIBLE);
+                viewGroup.setDescendantFocusability(oldFocusability);
+            } else {
+                view.setVisibility(View.VISIBLE);
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/anim/AnimatorPlaybackController.java b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
index 164728a..62f59e4 100644
--- a/src/com/android/launcher3/anim/AnimatorPlaybackController.java
+++ b/src/com/android/launcher3/anim/AnimatorPlaybackController.java
@@ -16,6 +16,7 @@
 package com.android.launcher3.anim;
 
 import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
 
 import android.animation.Animator;
 import android.animation.Animator.AnimatorListener;
@@ -23,10 +24,16 @@
 import android.animation.AnimatorSet;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
+import android.util.Log;
 
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
+
+import androidx.dynamicanimation.animation.DynamicAnimation;
+import androidx.dynamicanimation.animation.SpringAnimation;
 
 /**
  * Helper class to control the playback of an {@link AnimatorSet}, with custom interpolators
@@ -37,6 +44,9 @@
  */
 public abstract class AnimatorPlaybackController implements ValueAnimator.AnimatorUpdateListener {
 
+    private static final String TAG = "AnimatorPlaybackCtrler";
+    private static boolean DEBUG = false;
+
     public static AnimatorPlaybackController wrap(AnimatorSet anim, long duration) {
         return wrap(anim, duration, null);
     }
@@ -60,6 +70,7 @@
     private final long mDuration;
 
     protected final AnimatorSet mAnim;
+    private Set<SpringAnimation> mSprings;
 
     protected float mCurrentFraction;
     private Runnable mEndAction;
@@ -67,6 +78,9 @@
     protected boolean mTargetCancelled = false;
     protected Runnable mOnCancelRunnable;
 
+    private OnAnimationEndDispatcher mEndListener;
+    private DynamicAnimation.OnAnimationEndListener mSpringEndListener;
+
     protected AnimatorPlaybackController(AnimatorSet anim, long duration,
             Runnable onCancelRunnable) {
         mAnim = anim;
@@ -75,7 +89,8 @@
 
         mAnimationPlayer = ValueAnimator.ofFloat(0, 1);
         mAnimationPlayer.setInterpolator(LINEAR);
-        mAnimationPlayer.addListener(new OnAnimationEndDispatcher());
+        mEndListener = new OnAnimationEndDispatcher();
+        mAnimationPlayer.addListener(mEndListener);
         mAnimationPlayer.addUpdateListener(this);
 
         mAnim.addListener(new AnimatorListenerAdapter() {
@@ -99,6 +114,15 @@
                 mTargetCancelled = false;
             }
         });
+
+        mSprings = new HashSet<>();
+        mSpringEndListener = (animation, canceled, value, velocity1) -> {
+            if (canceled) {
+                mEndListener.onAnimationCancel(mAnimationPlayer);
+            } else {
+                mEndListener.onAnimationEnd(mAnimationPlayer);
+            }
+        };
     }
 
     public AnimatorSet getTarget() {
@@ -154,6 +178,10 @@
         return mCurrentFraction;
     }
 
+    public float getInterpolatedProgress() {
+        return getInterpolator().getInterpolation(mCurrentFraction);
+    }
+
     /**
      * Sets the action to be called when the animation is completed. Also clears any
      * previously set action.
@@ -176,6 +204,29 @@
         }
     }
 
+    /**
+     * Starts playback and sets the spring.
+     */
+    public void dispatchOnStartWithVelocity(float end, float velocity) {
+        if (!QUICKSTEP_SPRINGS.get()) {
+            dispatchOnStart();
+            return;
+        }
+
+        if (DEBUG) Log.d(TAG, "dispatchOnStartWithVelocity#end=" + end + ", velocity=" + velocity);
+
+        for (Animator a : mAnim.getChildAnimations()) {
+            if (a instanceof SpringObjectAnimator) {
+                if (DEBUG) Log.d(TAG, "Found springAnimator=" + a);
+                SpringObjectAnimator springAnimator = (SpringObjectAnimator) a;
+                mSprings.add(springAnimator.getSpring());
+                springAnimator.startSpring(end, velocity, mSpringEndListener);
+            }
+        }
+
+        dispatchOnStart();
+    }
+
     public void dispatchOnStart() {
         dispatchOnStartRecursively(mAnim);
     }
@@ -278,6 +329,18 @@
         }
     }
 
+    private boolean isAnySpringRunning() {
+        for (SpringAnimation spring : mSprings) {
+            if (spring.isRunning()) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Only dispatches the on end actions once the animator and all springs have completed running.
+     */
     private class OnAnimationEndDispatcher extends AnimationSuccessListener {
 
         @Override
@@ -287,9 +350,12 @@
 
         @Override
         public void onAnimationSuccess(Animator animator) {
-            dispatchOnEndRecursively(mAnim);
-            if (mEndAction != null) {
-                mEndAction.run();
+            // We wait for the spring (if any) to finish running before completing the end callback.
+            if (mSprings.isEmpty() || !isAnySpringRunning()) {
+                dispatchOnEndRecursively(mAnim);
+                if (mEndAction != null) {
+                    mEndAction.run();
+                }
             }
         }
 
diff --git a/src/com/android/launcher3/anim/SpringObjectAnimator.java b/src/com/android/launcher3/anim/SpringObjectAnimator.java
new file mode 100644
index 0000000..4ece909
--- /dev/null
+++ b/src/com/android/launcher3/anim/SpringObjectAnimator.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.anim;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.animation.ValueAnimator;
+import android.util.Log;
+import android.util.Property;
+
+import com.android.launcher3.ProgressInterface;
+
+import java.util.ArrayList;
+
+import androidx.dynamicanimation.animation.DynamicAnimation.OnAnimationEndListener;
+import androidx.dynamicanimation.animation.FloatPropertyCompat;
+import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
+
+import static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
+
+/**
+ * This animator allows for an object's property to be be controlled by an {@link ObjectAnimator} or
+ * a {@link SpringAnimation}. It extends ValueAnimator so it can be used in an AnimatorSet.
+ */
+public class SpringObjectAnimator<T extends ProgressInterface> extends ValueAnimator {
+
+    private static final String TAG = "SpringObjectAnimator";
+    private static boolean DEBUG = false;
+
+    private T mObject;
+    private ObjectAnimator mObjectAnimator;
+    private float[] mValues;
+
+    private SpringAnimation mSpring;
+    private SpringProperty<T> mProperty;
+
+    private ArrayList<AnimatorListener> mListeners;
+    private boolean mSpringEnded = false;
+    private boolean mAnimatorEnded = false;
+    private boolean mEnded = false;
+
+    private static final float SPRING_DAMPING_RATIO = 0.9f;
+    private static final float SPRING_STIFFNESS = 600f;
+
+    public SpringObjectAnimator(T object, FloatPropertyCompat<T> floatProperty,
+            String name, float minimumVisibleChange, float... values) {
+        mObject = object;
+        mSpring = new SpringAnimation(object, floatProperty);
+        mSpring.setMinimumVisibleChange(minimumVisibleChange);
+        mSpring.setSpring(new SpringForce(0)
+                .setDampingRatio(SPRING_DAMPING_RATIO)
+                .setStiffness(SPRING_STIFFNESS));
+        mSpring.setStartVelocity(0.01f);
+        mProperty = new SpringProperty<T>(name, mSpring);
+        mObjectAnimator = ObjectAnimator.ofFloat(object, mProperty, values);
+        mValues = values;
+        mListeners = new ArrayList<>();
+        setFloatValues(values);
+
+        mObjectAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mAnimatorEnded = false;
+                mEnded = false;
+                for (AnimatorListener l : mListeners) {
+                    l.onAnimationStart(animation);
+                }
+            }
+
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mAnimatorEnded = true;
+                tryEnding();
+            }
+
+            @Override
+            public void onAnimationCancel(Animator animation) {
+                for (AnimatorListener l : mListeners) {
+                    l.onAnimationCancel(animation);
+                }
+                mSpring.animateToFinalPosition(mObject.getProgress());
+            }
+        });
+
+        mSpring.addUpdateListener((animation, value, velocity) -> mSpringEnded = false);
+        mSpring.addEndListener((animation, canceled, value, velocity) -> {
+            mSpringEnded = true;
+            tryEnding();
+        });
+    }
+
+    private void tryEnding() {
+        if (DEBUG) {
+            Log.d(TAG, "tryEnding#mAnimatorEnded=" + mAnimatorEnded + ", mSpringEnded="
+                    + mSpringEnded + ", mEnded=" + mEnded);
+        }
+
+        // If springs are disabled, ignore value of mSpringEnded
+        if (mAnimatorEnded && (mSpringEnded || !QUICKSTEP_SPRINGS.get()) && !mEnded) {
+            for (AnimatorListener l : mListeners) {
+                l.onAnimationEnd(this);
+            }
+            mEnded = true;
+        }
+    }
+
+    public SpringAnimation getSpring() {
+        return mSpring;
+    }
+
+    /**
+     * Initializes and sets up the spring to take over controlling the object.
+     */
+    void startSpring(float end, float velocity, OnAnimationEndListener endListener) {
+        // Cancel the spring so we can set new start velocity and final position. We need to remove
+        // the listener since the spring is not actually ending.
+        mSpring.removeEndListener(endListener);
+        mSpring.cancel();
+        mSpring.addEndListener(endListener);
+
+        mProperty.switchToSpring();
+
+        mSpring.setStartVelocity(velocity);
+        mSpring.animateToFinalPosition(end == 0 ? mValues[0] : mValues[1]);
+    }
+
+    @Override
+    public void addListener(AnimatorListener listener) {
+        mListeners.add(listener);
+    }
+
+    @Override
+    public ArrayList<AnimatorListener> getListeners() {
+        return mListeners;
+    }
+
+    @Override
+    public void removeAllListeners() {
+        mListeners.clear();
+    }
+
+    @Override
+    public void removeListener(AnimatorListener listener) {
+        mListeners.remove(listener);
+    }
+
+    @Override
+    public void addPauseListener(AnimatorPauseListener listener) {
+        mObjectAnimator.addPauseListener(listener);
+    }
+
+    @Override
+    public void cancel() {
+        mSpring.animateToFinalPosition(mObject.getProgress());
+        mObjectAnimator.cancel();
+    }
+
+    @Override
+    public void end() {
+        mObjectAnimator.end();
+    }
+
+    @Override
+    public long getDuration() {
+        return mObjectAnimator.getDuration();
+    }
+
+    @Override
+    public TimeInterpolator getInterpolator() {
+        return mObjectAnimator.getInterpolator();
+    }
+
+    @Override
+    public long getStartDelay() {
+        return mObjectAnimator.getStartDelay();
+    }
+
+    @Override
+    public long getTotalDuration() {
+        return mObjectAnimator.getTotalDuration();
+    }
+
+    @Override
+    public boolean isPaused() {
+        return mObjectAnimator.isPaused();
+    }
+
+    @Override
+    public boolean isRunning() {
+        return mObjectAnimator.isRunning();
+    }
+
+    @Override
+    public boolean isStarted() {
+        return mObjectAnimator.isStarted();
+    }
+
+    @Override
+    public void pause() {
+        mObjectAnimator.pause();
+    }
+
+    @Override
+    public void removePauseListener(AnimatorPauseListener listener) {
+        mObjectAnimator.removePauseListener(listener);
+    }
+
+    @Override
+    public void resume() {
+        mObjectAnimator.resume();
+    }
+
+    @Override
+    public ValueAnimator setDuration(long duration) {
+        return mObjectAnimator.setDuration(duration);
+    }
+
+    @Override
+    public void setInterpolator(TimeInterpolator value) {
+        mObjectAnimator.setInterpolator(value);
+    }
+
+    @Override
+    public void setStartDelay(long startDelay) {
+        mObjectAnimator.setStartDelay(startDelay);
+    }
+
+    @Override
+    public void setTarget(Object target) {
+        mObjectAnimator.setTarget(target);
+    }
+
+    @Override
+    public void start() {
+        mObjectAnimator.start();
+    }
+
+    @Override
+    public void setCurrentFraction(float fraction) {
+        mObjectAnimator.setCurrentFraction(fraction);
+    }
+
+    @Override
+    public void setCurrentPlayTime(long playTime) {
+        mObjectAnimator.setCurrentPlayTime(playTime);
+    }
+
+    public static class SpringProperty<T extends ProgressInterface> extends Property<T, Float> {
+
+        boolean useSpring = false;
+        final SpringAnimation mSpring;
+
+        public SpringProperty(String name, SpringAnimation spring) {
+            super(Float.class, name);
+            mSpring = spring;
+        }
+
+        public void switchToSpring() {
+            useSpring = true;
+        }
+
+        @Override
+        public Float get(T object) {
+            return object.getProgress();
+        }
+
+        @Override
+        public void set(T object, Float progress) {
+            if (useSpring) {
+                mSpring.animateToFinalPosition(progress);
+            } else {
+                object.setProgress(progress);
+            }
+        }
+    }
+}
diff --git a/src/com/android/launcher3/badge/BadgeRenderer.java b/src/com/android/launcher3/badge/BadgeRenderer.java
deleted file mode 100644
index 5d38aad..0000000
--- a/src/com/android/launcher3/badge/BadgeRenderer.java
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.badge;
-
-import static android.graphics.Paint.ANTI_ALIAS_FLAG;
-import static android.graphics.Paint.FILTER_BITMAP_FLAG;
-
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.util.Log;
-
-import com.android.launcher3.icons.ShadowGenerator;
-
-/**
- * Contains parameters necessary to draw a badge for an icon (e.g. the size of the badge).
- * @see BadgeInfo for the data to draw
- */
-public class BadgeRenderer {
-
-    private static final String TAG = "BadgeRenderer";
-
-    // The badge sizes are defined as percentages of the app icon size.
-    private static final float SIZE_PERCENTAGE = 0.38f;
-
-    // Extra scale down of the dot
-    private static final float DOT_SCALE = 0.6f;
-
-    // Used to expand the width of the badge for each additional digit.
-    private static final float OFFSET_PERCENTAGE = 0.02f;
-
-    private final float mDotCenterOffset;
-    private final int mOffset;
-    private final float mCircleRadius;
-    private final Paint mCirclePaint = new Paint(ANTI_ALIAS_FLAG | FILTER_BITMAP_FLAG);
-
-    private final Bitmap mBackgroundWithShadow;
-    private final float mBitmapOffset;
-
-    public BadgeRenderer(int iconSizePx) {
-        mDotCenterOffset = SIZE_PERCENTAGE * iconSizePx;
-        mOffset = (int) (OFFSET_PERCENTAGE * iconSizePx);
-
-        int size = (int) (DOT_SCALE * mDotCenterOffset);
-        ShadowGenerator.Builder builder = new ShadowGenerator.Builder(Color.TRANSPARENT);
-        builder.ambientShadowAlpha = 88;
-        mBackgroundWithShadow = builder.setupBlurForSize(size).createPill(size, size);
-        mCircleRadius = builder.radius;
-
-        mBitmapOffset = -mBackgroundWithShadow.getHeight() * 0.5f; // Same as width.
-    }
-
-    /**
-     * Draw a circle in the top right corner of the given bounds, and draw
-     * {@link BadgeInfo#getNotificationCount()} on top of the circle.
-     * @param color The color (based on the icon) to use for the badge.
-     * @param iconBounds The bounds of the icon being badged.
-     * @param badgeScale The progress of the animation, from 0 to 1.
-     * @param spaceForOffset How much space is available to offset the badge up and to the right.
-     */
-    public void draw(
-            Canvas canvas, int color, Rect iconBounds, float badgeScale, Point spaceForOffset) {
-        if (iconBounds == null || spaceForOffset == null) {
-            Log.e(TAG, "Invalid null argument(s) passed in call to draw.");
-            return;
-        }
-        canvas.save();
-        // We draw the badge relative to its center.
-        float badgeCenterX = iconBounds.right - mDotCenterOffset / 2;
-        float badgeCenterY = iconBounds.top + mDotCenterOffset / 2;
-
-        int offsetX = Math.min(mOffset, spaceForOffset.x);
-        int offsetY = Math.min(mOffset, spaceForOffset.y);
-        canvas.translate(badgeCenterX + offsetX, badgeCenterY - offsetY);
-        canvas.scale(badgeScale, badgeScale);
-
-        mCirclePaint.setColor(Color.BLACK);
-        canvas.drawBitmap(mBackgroundWithShadow, mBitmapOffset, mBitmapOffset, mCirclePaint);
-        mCirclePaint.setColor(color);
-        canvas.drawCircle(0, 0, mCircleRadius, mCirclePaint);
-        canvas.restore();
-    }
-}
diff --git a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
index 84e82e3..a7c0a47 100644
--- a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
+++ b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
@@ -12,6 +12,8 @@
 import java.lang.reflect.Method;
 import java.util.Locale;
 
+import androidx.annotation.NonNull;
+
 public class AlphabeticIndexCompat {
     private static final String TAG = "AlphabeticIndexCompat";
 
@@ -53,7 +55,7 @@
     /**
      * Computes the section name for an given string {@param s}.
      */
-    public String computeSectionName(CharSequence cs) {
+    public String computeSectionName(@NonNull CharSequence cs) {
         String s = Utilities.trim(cs);
         String sectionName = mBaseIndex.getBucketLabel(mBaseIndex.getBucketIndex(s));
         if (Utilities.trim(sectionName).isEmpty() && s.length() > 0) {
@@ -89,7 +91,7 @@
         /**
          * Returns the index of the bucket in which the given string should appear.
          */
-        protected int getBucketIndex(String s) {
+        protected int getBucketIndex(@NonNull String s) {
             if (s.isEmpty()) {
                 return UNKNOWN_BUCKET_INDEX;
             }
diff --git a/src/com/android/launcher3/compat/UserManagerCompat.java b/src/com/android/launcher3/compat/UserManagerCompat.java
index ad51477..e13d2a6 100644
--- a/src/com/android/launcher3/compat/UserManagerCompat.java
+++ b/src/com/android/launcher3/compat/UserManagerCompat.java
@@ -57,7 +57,6 @@
     public abstract List<UserHandle> getUserProfiles();
     public abstract long getSerialNumberForUser(UserHandle user);
     public abstract UserHandle getUserForSerialNumber(long serialNumber);
-    public abstract CharSequence getBadgedLabelForUser(CharSequence label, UserHandle user);
     public abstract boolean isQuietModeEnabled(UserHandle user);
     public abstract boolean isUserUnlocked(UserHandle user);
 
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index ef72842..4688052 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -17,7 +17,6 @@
 package com.android.launcher3.compat;
 
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.util.ArrayMap;
@@ -30,7 +29,6 @@
 public class UserManagerCompatVL extends UserManagerCompat {
 
     protected final UserManager mUserManager;
-    private final PackageManager mPm;
 
     protected LongSparseArray<UserHandle> mUsers;
     // Create a separate reverse map as LongSparseArray.indexOfValue checks if objects are same
@@ -39,7 +37,6 @@
 
     UserManagerCompatVL(Context context) {
         mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        mPm = context.getPackageManager();
     }
 
     @Override
@@ -125,13 +122,5 @@
         }
         return getUserProfiles().size() > 1;
     }
-
-    @Override
-    public CharSequence getBadgedLabelForUser(CharSequence label, UserHandle user) {
-        if (user == null) {
-            return label;
-        }
-        return mPm.getUserBadgedLabel(label, user);
-    }
 }
 
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
index e5a8a01..fa93081 100644
--- a/src/com/android/launcher3/config/BaseFlags.java
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -17,11 +17,13 @@
 package com.android.launcher3.config;
 
 import static androidx.core.util.Preconditions.checkNotNull;
-
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.provider.Settings;
-
+import androidx.annotation.GuardedBy;
+import androidx.annotation.Keep;
+import androidx.annotation.VisibleForTesting;
 import com.android.launcher3.Utilities;
 
 import java.util.ArrayList;
@@ -29,9 +31,6 @@
 import java.util.SortedMap;
 import java.util.TreeMap;
 
-import androidx.annotation.GuardedBy;
-import androidx.annotation.Keep;
-
 /**
  * Defines a set of flags used to control various launcher behaviors.
  *
@@ -59,7 +58,6 @@
     }
 
     public static final boolean IS_DOGFOOD_BUILD = false;
-    public static final String AUTHORITY = "com.android.launcher3.settings".intern();
 
     // When enabled the promise icon is visible in all apps while installation an app.
     public static final boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = false;
@@ -87,29 +85,36 @@
     // trying to make them fit the orientation the device is in.
     public static final boolean OVERVIEW_USE_SCREENSHOT_ORIENTATION = true;
 
-    public static final TogglableFlag QUICK_SWITCH = new TogglableFlag("QUICK_SWITCH", false,
+    public static final ToggleableGlobalSettingsFlag QUICK_SWITCH
+            = new ToggleableGlobalSettingsFlag("QUICK_SWITCH", false,
             "Swiping right on the nav bar while in an app switches to the previous app");
 
     /**
      * Feature flag to handle define config changes dynamically instead of killing the process.
      */
     public static final TogglableFlag APPLY_CONFIG_AT_RUNTIME = new TogglableFlag(
-            "APPLY_CONFIG_AT_RUNTIME", false, "Apply display changes dynamically");
+            "APPLY_CONFIG_AT_RUNTIME", true, "Apply display changes dynamically");
+
+    public static final ToggleableGlobalSettingsFlag ENABLE_TASK_STABILIZER
+            = new ToggleableGlobalSettingsFlag("ENABLE_TASK_STABILIZER", false,
+            "Stable task list across fast task switches");
+
+    public static final TogglableFlag QUICKSTEP_SPRINGS = new TogglableFlag("QUICKSTEP_SPRINGS",
+            false, "Enable springs for quickstep animations");
+
+    public static final TogglableFlag ENABLE_QUICKSTEP_LIVE_TILE = new TogglableFlag(
+            "ENABLE_QUICKSTEP_LIVE_TILE", false, "Enable live tile in Quickstep overview");
+
+    public static final ToggleableGlobalSettingsFlag SWIPE_HOME
+            = new ToggleableGlobalSettingsFlag("SWIPE_HOME", false,
+            "[WIP] Swiping up on the nav bar goes home. Swipe and hold goes to recent apps.");
 
     public static void initialize(Context context) {
         // Avoid the disk read for user builds
         if (Utilities.IS_DEBUG_DEVICE) {
-            SharedPreferences sharedPreferences =
-                    context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE);
             synchronized (sLock) {
                 for (TogglableFlag flag : sFlags) {
-                    flag.currentValue = sharedPreferences.getBoolean(flag.key, flag.defaultValue);
-                }
-            }
-        } else {
-            synchronized (sLock) {
-                for (TogglableFlag flag : sFlags) {
-                    flag.currentValue = flag.defaultValue;
+                    flag.initialize(context);
                 }
             }
         }
@@ -130,7 +135,7 @@
         return new ArrayList<>(flagsByKey.values());
     }
 
-    public static final class TogglableFlag {
+    public static class TogglableFlag {
         private final String key;
         private final boolean defaultValue;
         private final String description;
@@ -141,16 +146,41 @@
                 boolean defaultValue,
                 String description) {
             this.key = checkNotNull(key);
-            this.defaultValue = defaultValue;
+            this.currentValue = this.defaultValue = defaultValue;
             this.description = checkNotNull(description);
             synchronized (sLock) {
                 sFlags.add(this);
             }
         }
 
-        String getKey() {
+        /** Set the value of this flag. This should only be used in tests. */
+        @VisibleForTesting
+        void setForTests(boolean value) {
+            currentValue = value;
+        }
+
+        @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
+        public String getKey() {
             return key;
         }
+        void initialize(Context context) {
+            currentValue = getFromStorage(context, defaultValue);
+        }
+
+        void updateStorage(Context context, boolean value) {
+            SharedPreferences.Editor editor = context.getSharedPreferences(FLAGS_PREF_NAME,
+                    Context.MODE_PRIVATE).edit();
+            if (value == defaultValue) {
+                editor.remove(key).apply();
+            } else {
+                editor.putBoolean(key, value).apply();
+            }
+        }
+
+        boolean getFromStorage(Context context, boolean defaultValue) {
+            return context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE)
+                    .getBoolean(key, defaultValue);
+        }
 
         boolean getDefaultValue() {
             return defaultValue;
@@ -200,4 +230,37 @@
             return h$;
         }
     }
+
+    /**
+     * Stores the FeatureFlag's value in Settings.Global instead of our SharedPrefs.
+     * This is useful if we want to be able to control this flag from another process.
+     */
+    public static final class ToggleableGlobalSettingsFlag extends TogglableFlag {
+        private ContentResolver contentResolver;
+
+        ToggleableGlobalSettingsFlag(String key, boolean defaultValue, String description) {
+            super(key, defaultValue, description);
+        }
+
+        @Override
+        public void initialize(Context context) {
+            contentResolver = context.getContentResolver();
+            super.initialize(context);
+        }
+
+        @Override
+        void updateStorage(Context context, boolean value) {
+            Settings.Global.putInt(contentResolver, getKey(), value ? 1 : 0);
+        }
+
+        @Override
+        boolean getFromStorage(Context context, boolean defaultValue) {
+            return Settings.Global.getInt(contentResolver, getKey(), defaultValue ? 1 : 0) == 1;
+        }
+
+        @Override
+        public boolean get() {
+            return getFromStorage(null, getDefaultValue());
+        }
+    }
 }
diff --git a/src/com/android/launcher3/config/FlagTogglerPrefUi.java b/src/com/android/launcher3/config/FlagTogglerPrefUi.java
index d3be51d..5ecb186 100644
--- a/src/com/android/launcher3/config/FlagTogglerPrefUi.java
+++ b/src/com/android/launcher3/config/FlagTogglerPrefUi.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.os.Process;
+import android.text.Html;
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -49,19 +50,24 @@
         public void putBoolean(String key, boolean value) {
             for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
                 if (flag.getKey().equals(key)) {
-                    if (value == flag.getDefaultValue()) {
-                        mSharedPreferences.edit().remove(key).apply();
-                    } else {
-                        mSharedPreferences.edit().putBoolean(key, value).apply();
-                    }
+                    boolean prevValue = flag.get();
+                    flag.updateStorage(mContext, value);
                     updateMenu();
+                    if (flag.get() != prevValue) {
+                        Toast.makeText(mContext, "Flag applied", Toast.LENGTH_SHORT).show();
+                    }
                 }
             }
         }
 
         @Override
-        public boolean getBoolean(String key, boolean defValue) {
-            return mSharedPreferences.getBoolean(key, defValue);
+        public boolean getBoolean(String key, boolean defaultValue) {
+            for (TogglableFlag flag : FeatureFlags.getTogglableFlags()) {
+                if (flag.getKey().equals(key)) {
+                    return flag.getFromStorage(mContext, defaultValue);
+                }
+            }
+            return defaultValue;
         }
     };
 
@@ -83,14 +89,23 @@
             switchPreference.setDefaultValue(flag.getDefaultValue());
             switchPreference.setChecked(getFlagStateFromSharedPrefs(flag));
             switchPreference.setTitle(flag.getKey());
-            switchPreference.setSummaryOn(flag.getDefaultValue() ? "" : "overridden");
-            switchPreference.setSummaryOff(flag.getDefaultValue() ? "overridden" : "");
+            updateSummary(switchPreference, flag);
             switchPreference.setPreferenceDataStore(mDataStore);
             parent.addPreference(switchPreference);
         }
         updateMenu();
     }
 
+    /**
+     * Updates the summary to show the description and whether the flag overrides the default value.
+     */
+    private void updateSummary(SwitchPreference switchPreference, TogglableFlag flag) {
+        String onWarning = flag.getDefaultValue() ? "" : "<b>OVERRIDDEN</b><br>";
+        String offWarning = flag.getDefaultValue() ? "<b>OVERRIDDEN</b><br>" : "";
+        switchPreference.setSummaryOn(Html.fromHtml(onWarning + flag.getDescription()));
+        switchPreference.setSummaryOff(Html.fromHtml(offWarning + flag.getDescription()));
+    }
+
     private void updateMenu() {
         mFragment.setHasOptionsMenu(anyChanged());
         mFragment.getActivity().invalidateOptionsMenu();
diff --git a/src/com/android/launcher3/badge/BadgeInfo.java b/src/com/android/launcher3/dot/DotInfo.java
similarity index 72%
rename from src/com/android/launcher3/badge/BadgeInfo.java
rename to src/com/android/launcher3/dot/DotInfo.java
index f03544f..15b2a3b0 100644
--- a/src/com/android/launcher3/badge/BadgeInfo.java
+++ b/src/com/android/launcher3/dot/DotInfo.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.launcher3.badge;
+package com.android.launcher3.dot;
 
 import com.android.launcher3.notification.NotificationInfo;
 import com.android.launcher3.notification.NotificationKeyData;
@@ -24,17 +24,17 @@
 import java.util.List;
 
 /**
- * Contains data to be used in an icon badge.
+ * Contains data to be used for a notification dot.
  */
-public class BadgeInfo {
+public class DotInfo {
 
     public static final int MAX_COUNT = 999;
 
-    /** Used to link this BadgeInfo to icons on the workspace and all apps */
+    /** Used to link this DotInfo to icons on the workspace and all apps */
     private PackageUserKey mPackageUserKey;
 
     /**
-     * The keys of the notifications that this badge represents. These keys can later be
+     * The keys of the notifications that this dot represents. These keys can later be
      * used to retrieve {@link NotificationInfo}'s.
      */
     private List<NotificationKeyData> mNotificationKeys;
@@ -45,7 +45,7 @@
      */
     private int mTotalCount;
 
-    public BadgeInfo(PackageUserKey packageUserKey) {
+    public DotInfo(PackageUserKey packageUserKey) {
         mPackageUserKey = packageUserKey;
         mNotificationKeys = new ArrayList<>();
     }
@@ -92,17 +92,4 @@
     public int getNotificationCount() {
         return Math.min(mTotalCount, MAX_COUNT);
     }
-
-    /**
-     * Whether newBadge represents the same PackageUserKey as this badge, and icons with
-     * this badge should be invalidated. So, for instance, if a badge has 3 notifications
-     * and one of those notifications is updated, this method should return false because
-     * the badge still says "3" and the contents of those notifications are only retrieved
-     * upon long-click. This method always returns true when adding or removing notifications,
-     * or if the badge has a notification icon to show.
-     */
-    public boolean shouldBeInvalidated(BadgeInfo newBadge) {
-        return mPackageUserKey.equals(newBadge.mPackageUserKey)
-                && (getNotificationCount() != newBadge.getNotificationCount());
-    }
 }
diff --git a/src/com/android/launcher3/badge/FolderBadgeInfo.java b/src/com/android/launcher3/dot/FolderDotInfo.java
similarity index 61%
rename from src/com/android/launcher3/badge/FolderBadgeInfo.java
rename to src/com/android/launcher3/dot/FolderDotInfo.java
index fa5e8a4..b5eb8cd 100644
--- a/src/com/android/launcher3/badge/FolderBadgeInfo.java
+++ b/src/com/android/launcher3/dot/FolderDotInfo.java
@@ -14,52 +14,51 @@
  * limitations under the License.
  */
 
-package com.android.launcher3.badge;
+package com.android.launcher3.dot;
 
 import android.view.ViewDebug;
 
 import com.android.launcher3.Utilities;
 
 /**
- * Subclass of BadgeInfo that only contains the badge count, which is
+ * Subclass of DotInfo that only contains the dot count, which is
  * the sum of all the Folder's items' notifications (each counts as 1).
  */
-public class FolderBadgeInfo extends BadgeInfo {
+public class FolderDotInfo extends DotInfo {
 
     private static final int MIN_COUNT = 0;
 
     private int mNumNotifications;
 
-    public FolderBadgeInfo() {
+    public FolderDotInfo() {
         super(null);
     }
 
-    public void addBadgeInfo(BadgeInfo badgeToAdd) {
-        if (badgeToAdd == null) {
+    public void addDotInfo(DotInfo dotToAdd) {
+        if (dotToAdd == null) {
             return;
         }
-        mNumNotifications += badgeToAdd.getNotificationKeys().size();
+        mNumNotifications += dotToAdd.getNotificationKeys().size();
         mNumNotifications = Utilities.boundToRange(
-                mNumNotifications, MIN_COUNT, BadgeInfo.MAX_COUNT);
+                mNumNotifications, MIN_COUNT, DotInfo.MAX_COUNT);
     }
 
-    public void subtractBadgeInfo(BadgeInfo badgeToSubtract) {
-        if (badgeToSubtract == null) {
+    public void subtractDotInfo(DotInfo dotToSubtract) {
+        if (dotToSubtract == null) {
             return;
         }
-        mNumNotifications -= badgeToSubtract.getNotificationKeys().size();
+        mNumNotifications -= dotToSubtract.getNotificationKeys().size();
         mNumNotifications = Utilities.boundToRange(
-                mNumNotifications, MIN_COUNT, BadgeInfo.MAX_COUNT);
+                mNumNotifications, MIN_COUNT, DotInfo.MAX_COUNT);
     }
 
     @Override
     public int getNotificationCount() {
-        // This forces the folder badge to always show up as a dot.
-        return 0;
+        return mNumNotifications;
     }
 
     @ViewDebug.ExportedProperty(category = "launcher")
-    public boolean hasBadge() {
+    public boolean hasDot() {
         return mNumNotifications > 0;
     }
 }
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index daf7dc6..79819cc 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -58,6 +58,7 @@
 import com.android.launcher3.util.InstantAppResolver;
 import com.android.launcher3.util.LooperExecutor;
 import com.android.launcher3.util.Provider;
+import com.android.launcher3.views.BaseDragLayer;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
 import com.android.launcher3.widget.WidgetHostViewLoader;
@@ -314,6 +315,11 @@
                 .getInt(STATE_EXTRA_WIDGET_ID, mPendingBindWidgetId);
     }
 
+    @Override
+    public BaseDragLayer getDragLayer() {
+        throw new UnsupportedOperationException();
+    }
+
     private void logCommand(int command) {
         getUserEventDispatcher().dispatchUserEvent(newLauncherEvent(
                 newCommandAction(command),
diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
index 9f0d678..794ab4e 100644
--- a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
+++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
@@ -36,7 +36,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.folder.PreviewBackground;
-import com.android.launcher3.graphics.BitmapRenderer;
+import com.android.launcher3.icons.BitmapRenderer;
 import com.android.launcher3.util.Preconditions;
 
 /**
@@ -102,7 +102,7 @@
         c.setBitmap(badgeBitmap);
         bg.drawShadow(c);
         bg.drawBackgroundStroke(c);
-        icon.drawBadge(c);
+        icon.drawDot(c);
 
         // Initialize preview
         final float sizeScaleFactor = 1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction();
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 94c8d45..51c2998 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -645,8 +645,8 @@
                 mFolderIcon.mBackground.fadeInBackgroundShadow();
                 mFolderIcon.mBackground.animateBackgroundStroke();
                 mFolderIcon.onFolderClose(mContent.getCurrentPage());
-                if (mFolderIcon.hasBadge()) {
-                    mFolderIcon.animateBadgeScale(0f, 1f);
+                if (mFolderIcon.hasDot()) {
+                    mFolderIcon.animateDotScale(0f, 1f);
                 }
                 mFolderIcon.requestFocus();
             }
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index fa890b9..2461e28 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -20,6 +20,7 @@
 import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
 import static com.android.launcher3.folder.FolderShape.getShape;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -46,8 +47,6 @@
 
 import java.util.List;
 
-import androidx.core.graphics.ColorUtils;
-
 /**
  * Manages the opening and closing animations for a {@link Folder}.
  *
@@ -153,8 +152,8 @@
 
         // Set up the Folder background.
         final int finalColor = Themes.getAttrColor(mContext, android.R.attr.colorPrimary);
-        final int initialColor =
-                ColorUtils.setAlphaComponent(finalColor, mPreviewBackground.getBackgroundAlpha());
+        final int initialColor = setColorAlphaBound(
+                finalColor, mPreviewBackground.getBackgroundAlpha());
         mFolderBackground.mutate();
         mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);
 
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 429d44f..30dbe69 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -24,7 +24,6 @@
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.graphics.Canvas;
-import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
@@ -57,11 +56,11 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.anim.Interpolators;
-import com.android.launcher3.badge.BadgeRenderer;
-import com.android.launcher3.badge.FolderBadgeInfo;
+import com.android.launcher3.dot.FolderDotInfo;
 import com.android.launcher3.dragndrop.BaseItemDragListener;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.dragndrop.DragView;
+import com.android.launcher3.icons.DotRenderer;
 import com.android.launcher3.touch.ItemClickHandler;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
@@ -110,23 +109,23 @@
     private Alarm mOpenAlarm = new Alarm();
 
     @ViewDebug.ExportedProperty(category = "launcher", deepExport = true)
-    private FolderBadgeInfo mBadgeInfo = new FolderBadgeInfo();
-    private BadgeRenderer mBadgeRenderer;
-    @ViewDebug.ExportedProperty(category = "launcher")
-    private float mBadgeScale;
-    private Animator mBadgeScaleAnim;
-    private Point mTempSpaceForBadgeOffset = new Point();
+    private FolderDotInfo mDotInfo = new FolderDotInfo();
+    private DotRenderer mDotRenderer;
+    @ViewDebug.ExportedProperty(category = "launcher", deepExport = true)
+    private DotRenderer.DrawParams mDotParams;
+    private float mDotScale;
+    private Animator mDotScaleAnim;
 
-    private static final Property<FolderIcon, Float> BADGE_SCALE_PROPERTY
-            = new Property<FolderIcon, Float>(Float.TYPE, "badgeScale") {
+    private static final Property<FolderIcon, Float> DOT_SCALE_PROPERTY
+            = new Property<FolderIcon, Float>(Float.TYPE, "dotScale") {
         @Override
         public Float get(FolderIcon folderIcon) {
-            return folderIcon.mBadgeScale;
+            return folderIcon.mDotScale;
         }
 
         @Override
         public void set(FolderIcon folderIcon, Float value) {
-            folderIcon.mBadgeScale = value;
+            folderIcon.mDotScale = value;
             folderIcon.invalidate();
         }
     };
@@ -147,6 +146,7 @@
         mPreviewLayoutRule = new ClippedFolderIconLayoutRule();
         mSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
         mPreviewItemManager = new PreviewItemManager(this);
+        mDotParams = new DotRenderer.DrawParams();
     }
 
     public static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group,
@@ -174,7 +174,7 @@
         icon.setOnClickListener(ItemClickHandler.INSTANCE);
         icon.mInfo = folderInfo;
         icon.mLauncher = launcher;
-        icon.mBadgeRenderer = launcher.getDeviceProfile().mBadgeRenderer;
+        icon.mDotRenderer = launcher.getDeviceProfile().mDotRenderer;
         icon.setContentDescription(launcher.getString(R.string.folder_name_format, folderInfo.title));
         Folder folder = Folder.fromXml(launcher);
         folder.setDragController(launcher.getDragController());
@@ -382,9 +382,9 @@
                 itemReturnedOnFailedDrop);
     }
 
-    public void setBadgeInfo(FolderBadgeInfo badgeInfo) {
-        updateBadgeScale(mBadgeInfo.hasBadge(), badgeInfo.hasBadge());
-        mBadgeInfo = badgeInfo;
+    public void setDotInfo(FolderDotInfo dotInfo) {
+        updateDotScale(mDotInfo.hasDot(), dotInfo.hasDot());
+        mDotInfo = dotInfo;
     }
 
     public ClippedFolderIconLayoutRule getLayoutRule() {
@@ -392,41 +392,41 @@
     }
 
     /**
-     * Sets mBadgeScale to 1 or 0, animating if wasBadged or isBadged is false
-     * (the badge is being added or removed).
+     * Sets mDotScale to 1 or 0, animating if wasDotted or isDotted is false
+     * (the dot is being added or removed).
      */
-    private void updateBadgeScale(boolean wasBadged, boolean isBadged) {
-        float newBadgeScale = isBadged ? 1f : 0f;
-        // Animate when a badge is first added or when it is removed.
-        if ((wasBadged ^ isBadged) && isShown()) {
-            animateBadgeScale(newBadgeScale);
+    private void updateDotScale(boolean wasDotted, boolean isDotted) {
+        float newDotScale = isDotted ? 1f : 0f;
+        // Animate when a dot is first added or when it is removed.
+        if ((wasDotted ^ isDotted) && isShown()) {
+            animateDotScale(newDotScale);
         } else {
-            cancelBadgeScaleAnim();
-            mBadgeScale = newBadgeScale;
+            cancelDotScaleAnim();
+            mDotScale = newDotScale;
             invalidate();
         }
     }
 
-    private void cancelBadgeScaleAnim() {
-        if (mBadgeScaleAnim != null) {
-            mBadgeScaleAnim.cancel();
+    private void cancelDotScaleAnim() {
+        if (mDotScaleAnim != null) {
+            mDotScaleAnim.cancel();
         }
     }
 
-    public void animateBadgeScale(float... badgeScales) {
-        cancelBadgeScaleAnim();
-        mBadgeScaleAnim = ObjectAnimator.ofFloat(this, BADGE_SCALE_PROPERTY, badgeScales);
-        mBadgeScaleAnim.addListener(new AnimatorListenerAdapter() {
+    public void animateDotScale(float... dotScales) {
+        cancelDotScaleAnim();
+        mDotScaleAnim = ObjectAnimator.ofFloat(this, DOT_SCALE_PROPERTY, dotScales);
+        mDotScaleAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                mBadgeScaleAnim = null;
+                mDotScaleAnim = null;
             }
         });
-        mBadgeScaleAnim.start();
+        mDotScaleAnim.start();
     }
 
-    public boolean hasBadge() {
-        return mBadgeInfo != null && mBadgeInfo.hasBadge();
+    public boolean hasDot() {
+        return mDotInfo != null && mDotInfo.hasDot();
     }
 
     private float getLocalCenterForIndex(int index, int curNumItems, int[] center) {
@@ -487,18 +487,19 @@
             mBackground.drawBackgroundStroke(canvas);
         }
 
-        drawBadge(canvas);
+        drawDot(canvas);
     }
 
-    public void drawBadge(Canvas canvas) {
-        if ((mBadgeInfo != null && mBadgeInfo.hasBadge()) || mBadgeScale > 0) {
-            BubbleTextView.getIconBounds(this, mTempBounds, mLauncher.getDeviceProfile().iconSizePx);
+    public void drawDot(Canvas canvas) {
+        if ((mDotInfo != null && mDotInfo.hasDot()) || mDotScale > 0) {
+            Rect iconBounds = mDotParams.iconBounds;
+            BubbleTextView.getIconBounds(this, iconBounds, mLauncher.getDeviceProfile().iconSizePx);
 
-            // If we are animating to the accepting state, animate the badge out.
-            float badgeScale = Math.max(0, mBadgeScale - mBackground.getScaleProgress());
-            mTempSpaceForBadgeOffset.set(getWidth() - mTempBounds.right, mTempBounds.top);
-            mBadgeRenderer.draw(canvas, mBackground.getBadgeColor(), mTempBounds,
-                    badgeScale, mTempSpaceForBadgeOffset);
+            // If we are animating to the accepting state, animate the dot out.
+            mDotParams.scale = Math.max(0, mDotScale - mBackground.getScaleProgress());
+            mDotParams.spaceForOffset.set(getWidth() - iconBounds.right, iconBounds.top);
+            mDotParams.color = mBackground.getDotColor();
+            mDotRenderer.draw(canvas, mDotParams);
         }
     }
 
@@ -566,20 +567,20 @@
 
     @Override
     public void onAdd(ShortcutInfo item, int rank) {
-        boolean wasBadged = mBadgeInfo.hasBadge();
-        mBadgeInfo.addBadgeInfo(mLauncher.getBadgeInfoForItem(item));
-        boolean isBadged = mBadgeInfo.hasBadge();
-        updateBadgeScale(wasBadged, isBadged);
+        boolean wasDotted = mDotInfo.hasDot();
+        mDotInfo.addDotInfo(mLauncher.getDotInfoForItem(item));
+        boolean isDotted = mDotInfo.hasDot();
+        updateDotScale(wasDotted, isDotted);
         invalidate();
         requestLayout();
     }
 
     @Override
     public void onRemove(ShortcutInfo item) {
-        boolean wasBadged = mBadgeInfo.hasBadge();
-        mBadgeInfo.subtractBadgeInfo(mLauncher.getBadgeInfoForItem(item));
-        boolean isBadged = mBadgeInfo.hasBadge();
-        updateBadgeScale(wasBadged, isBadged);
+        boolean wasDotted = mDotInfo.hasDot();
+        mDotInfo.subtractDotInfo(mLauncher.getDotInfoForItem(item));
+        boolean isDotted = mDotInfo.hasDot();
+        updateDotScale(wasDotted, isDotted);
         invalidate();
         requestLayout();
     }
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index 8439e79..06eaf38 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -225,8 +225,7 @@
         CellLayout.LayoutParams lp = (CellLayout.LayoutParams) view.getLayoutParams();
         lp.cellX = item.cellX;
         lp.cellY = item.cellY;
-        getPageAt(pageNo).addViewToCellLayout(
-                view, -1, mFolder.mLauncher.getViewIdForItem(item), lp, true);
+        getPageAt(pageNo).addViewToCellLayout(view, -1, item.getViewId(), lp, true);
     }
 
     @SuppressLint("InflateParams")
@@ -351,8 +350,7 @@
                 }
                 lp.cellX = info.cellX;
                 lp.cellY = info.cellY;
-                currentPage.addViewToCellLayout(
-                        v, -1, mFolder.mLauncher.getViewIdForItem(info), lp, true);
+                currentPage.addViewToCellLayout(v, -1, info.getViewId(), lp, true);
 
                 if (verifier.isItemInPreview(rank) && v instanceof BubbleTextView) {
                     ((BubbleTextView) v).verifyHighRes();
diff --git a/src/com/android/launcher3/folder/FolderShape.java b/src/com/android/launcher3/folder/FolderShape.java
index ae279cb..4b06dda 100644
--- a/src/com/android/launcher3/folder/FolderShape.java
+++ b/src/com/android/launcher3/folder/FolderShape.java
@@ -23,6 +23,9 @@
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
@@ -34,13 +37,29 @@
 import android.graphics.drawable.AdaptiveIconDrawable;
 import android.graphics.drawable.ColorDrawable;
 import android.os.Build;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.util.Xml;
 import android.view.ViewOutlineProvider;
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
+import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.Themes;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import androidx.annotation.Nullable;
 
 /**
  * Abstract representation of the shape of a folder icon
@@ -53,15 +72,7 @@
         return sInstance;
     }
 
-    private static FolderShape[] getAllShapes() {
-        return new FolderShape[] {
-                new Circle(),
-                new RoundedSquare(8f / 50),  // Ratios based on path defined in config_icon_mask
-                new RoundedSquare(30f / 50),
-                new Square(),
-                new TearDrop(),
-                new Squircle()};
-    }
+    private SparseArray<TypedValue> mAttrs;
 
     public abstract void drawShape(Canvas canvas, float offsetX, float offsetY, float radius,
             Paint paint);
@@ -71,6 +82,11 @@
     public abstract Animator createRevealAnimator(Folder target, Rect startRect, Rect endRect,
             float endRadius, boolean isReversed);
 
+    @Nullable
+    public TypedValue getAttrValue(int attr) {
+        return mAttrs == null ? null : mAttrs.get(attr);
+    }
+
     /**
      * Abstract shape where the reveal animation is a derivative of a round rect animation
      */
@@ -163,44 +179,22 @@
         }
     }
 
-    public static class Square extends SimpleRectShape {
-
-        @Override
-        public void drawShape(Canvas canvas, float offsetX, float offsetY, float radius,  Paint p) {
-            float cx = radius + offsetX;
-            float cy = radius + offsetY;
-            canvas.drawRect(cx - radius, cy - radius, cx + radius, cy + radius, p);
-        }
-
-        @Override
-        public void addShape(Path path, float offsetX, float offsetY, float radius) {
-            float cx = radius + offsetX;
-            float cy = radius + offsetY;
-            path.addRect(cx - radius, cy - radius, cx + radius, cy + radius, Path.Direction.CW);
-        }
-
-        @Override
-        protected float getStartRadius(Rect startRect) {
-            return 0;
-        }
-    }
-
     public static class RoundedSquare extends SimpleRectShape {
 
         /**
-         * Ratio of corner radius to half size. Based on the
+         * Ratio of corner radius to half size.
          */
-        private final float mRadiusFactor;
+        private final float mRadiusRatio;
 
-        public RoundedSquare(float radiusFactor) {
-            mRadiusFactor = radiusFactor;
+        public RoundedSquare(float radiusRatio) {
+            mRadiusRatio = radiusRatio;
         }
 
         @Override
         public void drawShape(Canvas canvas, float offsetX, float offsetY, float radius, Paint p) {
             float cx = radius + offsetX;
             float cy = radius + offsetY;
-            float cr = radius * mRadiusFactor;
+            float cr = radius * mRadiusRatio;
             canvas.drawRoundRect(cx - radius, cy - radius, cx + radius, cy + radius, cr, cr, p);
         }
 
@@ -208,14 +202,14 @@
         public void addShape(Path path, float offsetX, float offsetY, float radius) {
             float cx = radius + offsetX;
             float cy = radius + offsetY;
-            float cr = radius * mRadiusFactor;
+            float cr = radius * mRadiusRatio;
             path.addRoundRect(cx - radius, cy - radius, cx + radius, cy + radius, cr, cr,
                     Path.Direction.CW);
         }
 
         @Override
         protected float getStartRadius(Rect startRect) {
-            return (startRect.width() / 2f) * mRadiusFactor;
+            return (startRect.width() / 2f) * mRadiusRatio;
         }
     }
 
@@ -224,13 +218,16 @@
         /**
          * Radio of short radius to large radius, based on the shape options defined in the config.
          */
-        private static final float RADIUS_RATIO = 15f / 50;
-
+        private final float mRadiusRatio;
         private final float[] mTempRadii = new float[8];
 
+        public TearDrop(float radiusRatio) {
+            mRadiusRatio = radiusRatio;
+        }
+
         @Override
         public void addShape(Path p, float offsetX, float offsetY, float r1) {
-            float r2 = r1 * RADIUS_RATIO;
+            float r2 = r1 * mRadiusRatio;
             float cx = r1 + offsetX;
             float cy = r1 + offsetY;
 
@@ -249,7 +246,7 @@
         protected AnimatorUpdateListener newUpdateListener(Rect startRect, Rect endRect,
                 float endRadius, Path outPath) {
             float r1 = startRect.width() / 2f;
-            float r2 = r1 * RADIUS_RATIO;
+            float r2 = r1 * mRadiusRatio;
 
             float[] startValues = new float[] {
                     startRect.left, startRect.top, startRect.right, startRect.bottom, r1, r2};
@@ -273,13 +270,17 @@
         /**
          * Radio of radius to circle radius, based on the shape options defined in the config.
          */
-        private static final float RADIUS_RATIO = 10f / 50;
+        private final float mRadiusRatio;
+
+        public Squircle(float radiusRatio) {
+            mRadiusRatio = radiusRatio;
+        }
 
         @Override
         public void addShape(Path p, float offsetX, float offsetY, float r) {
             float cx = r + offsetX;
             float cy = r + offsetY;
-            float control = r - r * RADIUS_RATIO;
+            float control = r - r * mRadiusRatio;
 
             p.moveTo(cx, cy - r);
             addLeftCurve(cx, cy, r, control, p);
@@ -310,7 +311,7 @@
             float startCX = startRect.exactCenterX();
             float startCY = startRect.exactCenterY();
             float startR = startRect.width() / 2f;
-            float startControl = startR - startR * RADIUS_RATIO;
+            float startControl = startR - startR * mRadiusRatio;
             float startHShift = 0;
             float startVShift = 0;
 
@@ -351,17 +352,65 @@
     }
 
     /**
-     * Initializes the shape which is closest to closest to the {@link AdaptiveIconDrawable}
+     * Initializes the shape which is closest to the {@link AdaptiveIconDrawable}
      */
-    public static void init() {
+    public static void init(Context context) {
         if (!Utilities.ATLEAST_OREO) {
             return;
         }
-        new MainThreadExecutor().execute(FolderShape::pickShapeInBackground);
+        new MainThreadExecutor().execute(() -> pickShapeInBackground(context));
+    }
+
+    private static FolderShape getShapeDefinition(String type, float radius) {
+        switch (type) {
+            case "Circle":
+                return new Circle();
+            case "RoundedSquare":
+                return new RoundedSquare(radius);
+            case "TearDrop":
+                return new TearDrop(radius);
+            case "Squircle":
+                return new Squircle(radius);
+            default:
+                throw new IllegalArgumentException("Invalid shape type: " + type);
+        }
+    }
+
+    private static List<FolderShape> getAllShapes(Context context) {
+        ArrayList<FolderShape> result = new ArrayList<>();
+        try (XmlResourceParser parser = context.getResources().getXml(R.xml.folder_shapes)) {
+
+            // Find the root tag
+            int type;
+            while ((type = parser.next()) != XmlPullParser.END_TAG
+                    && type != XmlPullParser.END_DOCUMENT
+                    && !"shapes".equals(parser.getName()));
+
+            final int depth = parser.getDepth();
+            int[] radiusAttr = new int[] {R.attr.folderIconRadius};
+            IntArray keysToIgnore = new IntArray(0);
+
+            while (((type = parser.next()) != XmlPullParser.END_TAG ||
+                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+
+                if (type == XmlPullParser.START_TAG) {
+                    AttributeSet attrs = Xml.asAttributeSet(parser);
+                    TypedArray a = context.obtainStyledAttributes(attrs, radiusAttr);
+                    FolderShape shape = getShapeDefinition(parser.getName(), a.getFloat(0, 1));
+                    a.recycle();
+
+                    shape.mAttrs = Themes.createValueMap(context, attrs, keysToIgnore);
+                    result.add(shape);
+                }
+            }
+        } catch (IOException | XmlPullParserException e) {
+            throw new RuntimeException(e);
+        }
+        return result;
     }
 
     @TargetApi(Build.VERSION_CODES.O)
-    protected static void pickShapeInBackground() {
+    protected static void pickShapeInBackground(Context context) {
         // Pick any large size
         int size = 200;
 
@@ -379,7 +428,7 @@
         // Find the shape with minimum area of divergent region.
         int minArea = Integer.MAX_VALUE;
         FolderShape closestShape = null;
-        for (FolderShape shape : getAllShapes()) {
+        for (FolderShape shape : getAllShapes(context)) {
             shapePath.reset();
             shape.addShape(shapePath, 0, 0, size / 2f);
             shapeR.setPath(shapePath, full);
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index 8443953..60f0eee 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -17,11 +17,13 @@
 package com.android.launcher3.folder;
 
 import static com.android.launcher3.folder.FolderShape.getShape;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
+import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Matrix;
@@ -37,11 +39,9 @@
 
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.util.Themes;
-
-import androidx.core.graphics.ColorUtils;
+import com.android.launcher3.views.ActivityContext;
 
 /**
  * This object represents a FolderIcon preview background. It stores drawing / measurement
@@ -63,7 +63,7 @@
     float mScale = 1f;
     private float mColorMultiplier = 1f;
     private int mBgColor;
-    private int mBadgeColor;
+    private int mDotColor;
     private float mStrokeWidth;
     private int mStrokeAlpha = MAX_BG_OPACITY;
     private int mShadowAlpha = 255;
@@ -122,20 +122,20 @@
                 }
             };
 
-    public void setup(Launcher launcher, View invalidateDelegate,
+    public void setup(Context context, ActivityContext activity, View invalidateDelegate,
                       int availableSpaceX, int topPadding) {
         mInvalidateDelegate = invalidateDelegate;
-        mBgColor = Themes.getAttrColor(launcher, android.R.attr.colorPrimary);
-        mBadgeColor = Themes.getAttrColor(launcher, R.attr.folderBadgeColor);
+        mBgColor = Themes.getAttrColor(context, android.R.attr.colorPrimary);
+        mDotColor = Themes.getAttrColor(context, R.attr.folderDotColor);
 
-        DeviceProfile grid = launcher.getDeviceProfile();
+        DeviceProfile grid = activity.getDeviceProfile();
         previewSize = grid.folderIconSizePx;
 
         basePreviewOffsetX = (availableSpaceX - previewSize) / 2;
         basePreviewOffsetY = topPadding + grid.folderIconOffsetYPx;
 
         // Stroke width is 1dp
-        mStrokeWidth = launcher.getResources().getDisplayMetrics().density;
+        mStrokeWidth = context.getResources().getDisplayMetrics().density;
 
         float radius = getScaledRadius();
         float shadowRadius = radius + mStrokeWidth;
@@ -189,11 +189,11 @@
 
     public int getBgColor() {
         int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
-        return ColorUtils.setAlphaComponent(mBgColor, alpha);
+        return setColorAlphaBound(mBgColor, alpha);
     }
 
-    public int getBadgeColor() {
-        return mBadgeColor;
+    public int getDotColor() {
+        return mDotColor;
     }
 
     public void drawBackground(Canvas canvas) {
@@ -275,7 +275,7 @@
     }
 
     public void drawBackgroundStroke(Canvas canvas) {
-        mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, mStrokeAlpha));
+        mPaint.setColor(setColorAlphaBound(mBgColor, mStrokeAlpha));
         mPaint.setStyle(Paint.Style.STROKE);
         mPaint.setStrokeWidth(mStrokeWidth);
 
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index 0004e1e..af98680 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -107,7 +107,8 @@
             mTotalWidth = totalSize;
             mPrevTopPadding = mIcon.getPaddingTop();
 
-            mIcon.mBackground.setup(mIcon.mLauncher, mIcon, mTotalWidth, mIcon.getPaddingTop());
+            mIcon.mBackground.setup(mIcon.mLauncher, mIcon.mLauncher, mIcon, mTotalWidth,
+                    mIcon.getPaddingTop());
             mIcon.mPreviewLayoutRule.init(mIcon.mBackground.previewSize, mIntrinsicIconSize,
                     Utilities.isRtl(mIcon.getResources()));
 
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index 5094280..7eb4015 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -33,8 +33,10 @@
 import com.android.launcher3.R;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.icons.BitmapRenderer;
 import com.android.launcher3.util.UiThreadHelper;
 import com.android.launcher3.widget.LauncherAppWidgetHostView;
+import com.android.launcher3.widget.PendingAppWidgetHostView;
 
 import java.nio.ByteBuffer;
 
@@ -130,9 +132,15 @@
             width = (int) (mView.getWidth() * scale);
             height = (int) (mView.getHeight() * scale);
 
-            // Use software renderer for widgets as we know that they already work
-            return BitmapRenderer.createSoftwareBitmap(width + blurSizeOutline,
-                    height + blurSizeOutline, (c) -> drawDragView(c, scale));
+            if (mView instanceof PendingAppWidgetHostView) {
+                // Use hardware renderer as the icon for the pending app widget may be a hw bitmap
+                return BitmapRenderer.createHardwareBitmap(width + blurSizeOutline,
+                        height + blurSizeOutline, (c) -> drawDragView(c, scale));
+            } else {
+                // Use software renderer for widgets as we know that they already work
+                return BitmapRenderer.createSoftwareBitmap(width + blurSizeOutline,
+                        height + blurSizeOutline, (c) -> drawDragView(c, scale));
+            }
         }
 
         return BitmapRenderer.createHardwareBitmap(width + blurSizeOutline,
diff --git a/src/com/android/launcher3/graphics/FragmentWithPreview.java b/src/com/android/launcher3/graphics/FragmentWithPreview.java
new file mode 100644
index 0000000..250eca2
--- /dev/null
+++ b/src/com/android/launcher3/graphics/FragmentWithPreview.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.graphics;
+
+import android.app.Fragment;
+import android.content.Context;
+import android.os.Bundle;
+
+/**
+ * Extension of fragment, with support for preview mode.
+ */
+public class FragmentWithPreview extends Fragment {
+
+    private Context mPreviewContext;
+
+    public final void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        onInit(savedInstanceState);
+    }
+
+    public void onInit(Bundle savedInstanceState) { }
+
+
+    public Context getContext() {
+        return mPreviewContext != null ? mPreviewContext : getActivity();
+    }
+
+    void enterPreviewMode(Context context) {
+        mPreviewContext = context;
+    }
+
+    public boolean isInPreviewMode() {
+        return mPreviewContext != null;
+    }
+}
diff --git a/src/com/android/launcher3/graphics/GridOptionsProvider.java b/src/com/android/launcher3/graphics/GridOptionsProvider.java
new file mode 100644
index 0000000..efd39ee
--- /dev/null
+++ b/src/com/android/launcher3/graphics/GridOptionsProvider.java
@@ -0,0 +1,191 @@
+package com.android.launcher3.graphics;
+
+import android.content.ContentProvider;
+import android.content.ContentValues;
+import android.content.res.XmlResourceParser;
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
+import android.os.ParcelFileDescriptor.AutoCloseOutputStream;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Xml;
+
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.InvariantDeviceProfile.GridOption;
+import com.android.launcher3.R;
+import com.android.launcher3.util.LooperExecutor;
+import com.android.launcher3.util.UiThreadHelper;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.Future;
+
+/**
+ * Exposes various launcher grid options and allows the caller to change them.
+ * APIs:
+ *      /list_options: List the various available grip options, has following columns
+ *          name: name of the grid
+ *          rows: number of rows in the grid
+ *          cols: number of columns in the grid
+ *          preview_count: number of previews available for this grid option. The preview uri
+ *                         looks like /preview/<grid-name>/<preview index starting with 0>
+ *          is_default: true if this grid is currently active
+ *
+ *     /preview: Opens a file stream for the grid preview
+ *
+ *     /default_grid: Call update to set the current grid, with values
+ *          name: name of the grid to apply
+ */
+public class GridOptionsProvider extends ContentProvider {
+
+    private static final String TAG = "GridOptionsProvider";
+
+    private static final String KEY_NAME = "name";
+    private static final String KEY_ROWS = "rows";
+    private static final String KEY_COLS = "cols";
+    private static final String KEY_PREVIEW_COUNT = "preview_count";
+    private static final String KEY_IS_DEFAULT = "is_default";
+
+    private static final String KEY_LIST_OPTIONS = "/list_options";
+    private static final String KEY_DEFAULT_GRID = "/default_grid";
+
+    private static final String KEY_PREVIEW = "preview";
+    private static final String MIME_TYPE_PNG = "image/png";
+
+    public static final PipeDataWriter<Future<Bitmap>> BITMAP_WRITER =
+            new PipeDataWriter<Future<Bitmap>>() {
+                @Override
+                public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String s,
+                        Bundle bundle, Future<Bitmap> bitmap) {
+                    try (AutoCloseOutputStream os = new AutoCloseOutputStream(output)) {
+                        bitmap.get().compress(Bitmap.CompressFormat.PNG, 100, os);
+                    } catch (Exception e) {
+                        Log.w(TAG, "fail to write to pipe", e);
+                    }
+                }
+            };
+
+    @Override
+    public boolean onCreate() {
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection,
+            String[] selectionArgs, String sortOrder) {
+        if (!KEY_LIST_OPTIONS.equals(uri.getPath())) {
+            return null;
+        }
+        MatrixCursor cursor = new MatrixCursor(new String[] {
+                KEY_NAME, KEY_ROWS, KEY_COLS, KEY_PREVIEW_COUNT, KEY_IS_DEFAULT});
+        InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(getContext());
+        for (GridOption gridOption : parseAllGridOptions()) {
+            cursor.newRow()
+                    .add(KEY_NAME, gridOption.name)
+                    .add(KEY_ROWS, gridOption.numRows)
+                    .add(KEY_COLS, gridOption.numColumns)
+                    .add(KEY_PREVIEW_COUNT, 1)
+                    .add(KEY_IS_DEFAULT, idp.numColumns == gridOption.numColumns
+                            && idp.numRows == gridOption.numRows);
+        }
+        return cursor;
+    }
+
+    private List<GridOption> parseAllGridOptions() {
+        List<GridOption> result = new ArrayList<>();
+        try (XmlResourceParser parser = getContext().getResources().getXml(R.xml.device_profiles)) {
+            final int depth = parser.getDepth();
+            int type;
+            while (((type = parser.next()) != XmlPullParser.END_TAG ||
+                    parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
+                if ((type == XmlPullParser.START_TAG)
+                        && GridOption.TAG_NAME.equals(parser.getName())) {
+                    result.add(new GridOption(getContext(), Xml.asAttributeSet(parser)));
+                }
+            }
+        } catch (IOException | XmlPullParserException e) {
+            Log.e(TAG, "Error parsing device profile", e);
+            return Collections.emptyList();
+        }
+        return result;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        List<String> segments = uri.getPathSegments();
+        if (segments.size() > 0 && KEY_PREVIEW.equals(segments.get(0))) {
+            return MIME_TYPE_PNG;
+        }
+        return "vnd.android.cursor.dir/launcher_grid";
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues initialValues) {
+        return null;
+    }
+
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        if (!KEY_DEFAULT_GRID.equals(uri.getPath())) {
+            return 0;
+        }
+
+        String gridName = values.getAsString(KEY_NAME);
+        // Verify that this is a valid grid option
+        GridOption match = null;
+        for (GridOption option : parseAllGridOptions()) {
+            if (option.name.equals(gridName)) {
+                match = option;
+                break;
+            }
+        }
+        if (match == null) {
+            return 0;
+        }
+
+        InvariantDeviceProfile.INSTANCE.get(getContext()).setCurrentGrid(getContext(), gridName);
+        return 1;
+    }
+
+    @Override
+    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
+        List<String> segments = uri.getPathSegments();
+        if (segments.size() < 2 || !KEY_PREVIEW.equals(segments.get(0))) {
+            throw new FileNotFoundException("Invalid preview url");
+        }
+        String profileName = segments.get(1);
+        if (TextUtils.isEmpty(profileName)) {
+            throw new FileNotFoundException("Invalid preview url");
+        }
+
+        InvariantDeviceProfile idp;
+        try {
+            idp = new InvariantDeviceProfile(getContext(), profileName);
+        } catch (Exception e) {
+            throw new FileNotFoundException(e.getMessage());
+        }
+
+        LooperExecutor executor = new LooperExecutor(UiThreadHelper.getBackgroundLooper());
+        try {
+            return openPipeHelper(uri, MIME_TYPE_PNG, null,
+                    executor.submit(new LauncherPreviewRenderer(getContext(), idp)), BITMAP_WRITER);
+        } catch (Exception e) {
+            throw new FileNotFoundException(e.getMessage());
+        }
+    }
+}
diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java
index cda07c3..3d4a100 100644
--- a/src/com/android/launcher3/graphics/IconPalette.java
+++ b/src/com/android/launcher3/graphics/IconPalette.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.graphics;
 
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
 import android.app.Notification;
 import android.content.Context;
 import android.graphics.Color;
@@ -147,7 +149,7 @@
     }
 
     public static int getMutedColor(int color, float whiteScrimAlpha) {
-        int whiteScrim = ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * whiteScrimAlpha));
+        int whiteScrim = setColorAlphaBound(Color.WHITE, (int) (255 * whiteScrimAlpha));
         return ColorUtils.compositeColors(whiteScrim, color);
     }
 }
diff --git a/src/com/android/launcher3/graphics/IconShapeOverride.java b/src/com/android/launcher3/graphics/IconShapeOverride.java
deleted file mode 100644
index b636c6d..0000000
--- a/src/com/android/launcher3/graphics/IconShapeOverride.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.graphics;
-
-import static com.android.launcher3.Utilities.getDevicePrefs;
-
-import android.annotation.TargetApi;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.ProgressDialog;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.Build;
-import android.os.SystemClock;
-import android.provider.Settings;
-import android.text.TextUtils;
-import android.util.Log;
-
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.util.LooperExecutor;
-
-import java.lang.reflect.Field;
-
-import androidx.annotation.NonNull;
-import androidx.preference.ListPreference;
-import androidx.preference.Preference;
-import androidx.preference.Preference.OnPreferenceChangeListener;
-
-/**
- * Utility class to override shape of {@link android.graphics.drawable.AdaptiveIconDrawable}.
- */
-@TargetApi(Build.VERSION_CODES.O)
-public class IconShapeOverride {
-
-    private static final String TAG = "IconShapeOverride";
-
-    public static final String KEY_PREFERENCE = "pref_override_icon_shape";
-
-    // Time to wait before killing the process this ensures that the progress bar is visible for
-    // sufficient time so that there is no flicker.
-    private static final long PROCESS_KILL_DELAY_MS = 1000;
-
-    private static final int RESTART_REQUEST_CODE = 42; // the answer to everything
-
-    public static boolean isSupported(Context context) {
-        if (!Utilities.ATLEAST_OREO) {
-            return false;
-        }
-        // Only supported when developer settings is enabled
-        if (Settings.Global.getInt(context.getContentResolver(),
-                Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 1) {
-            return false;
-        }
-
-        try {
-            if (getSystemResField().get(null) != Resources.getSystem()) {
-                // Our assumption that mSystem is the system resource is not true.
-                return false;
-            }
-        } catch (Exception e) {
-            // Ignore, not supported
-            return false;
-        }
-
-        return getConfigResId() != 0;
-    }
-
-    public static void apply(Context context) {
-        if (!Utilities.ATLEAST_OREO) {
-            return;
-        }
-        String path = getAppliedValue(context);
-        if (TextUtils.isEmpty(path)) {
-            return;
-        }
-        if (!isSupported(context)) {
-            return;
-        }
-
-        // magic
-        try {
-            Resources override =
-                    new ResourcesOverride(Resources.getSystem(), getConfigResId(), path);
-            getSystemResField().set(null, override);
-        } catch (Exception e) {
-            Log.e(TAG, "Unable to override icon shape", e);
-            // revert value.
-            getDevicePrefs(context).edit().remove(KEY_PREFERENCE).apply();
-        }
-    }
-
-    private static Field getSystemResField() throws Exception {
-        Field staticField = Resources.class.getDeclaredField("mSystem");
-        staticField.setAccessible(true);
-        return staticField;
-    }
-
-    private static int getConfigResId() {
-        return Resources.getSystem().getIdentifier("config_icon_mask", "string", "android");
-    }
-
-    private static String getAppliedValue(Context context) {
-        return getDevicePrefs(context).getString(KEY_PREFERENCE, "");
-    }
-
-    public static void handlePreferenceUi(ListPreference preference) {
-        Context context = preference.getContext();
-        preference.setValue(getAppliedValue(context));
-        preference.setOnPreferenceChangeListener(new PreferenceChangeHandler(context));
-    }
-
-    private static class ResourcesOverride extends Resources {
-
-        private final int mOverrideId;
-        private final String mOverrideValue;
-
-        @SuppressWarnings("deprecation")
-        public ResourcesOverride(Resources parent, int overrideId, String overrideValue) {
-            super(parent.getAssets(), parent.getDisplayMetrics(), parent.getConfiguration());
-            mOverrideId = overrideId;
-            mOverrideValue = overrideValue;
-        }
-
-        @NonNull
-        @Override
-        public String getString(int id) throws NotFoundException {
-            if (id == mOverrideId) {
-                return mOverrideValue;
-            }
-            return super.getString(id);
-        }
-    }
-
-    private static class PreferenceChangeHandler implements OnPreferenceChangeListener {
-
-        private final Context mContext;
-
-        private PreferenceChangeHandler(Context context) {
-            mContext = context;
-        }
-
-        @Override
-        public boolean onPreferenceChange(Preference preference, Object o) {
-            String newValue = (String) o;
-            if (!getAppliedValue(mContext).equals(newValue)) {
-                // Value has changed
-                ProgressDialog.show(mContext,
-                        null /* title */,
-                        mContext.getString(R.string.icon_shape_override_progress),
-                        true /* indeterminate */,
-                        false /* cancelable */);
-                new LooperExecutor(LauncherModel.getWorkerLooper()).execute(
-                        new OverrideApplyHandler(mContext, newValue));
-            }
-            return false;
-        }
-    }
-
-    private static class OverrideApplyHandler implements Runnable {
-
-        private final Context mContext;
-        private final String mValue;
-
-        private OverrideApplyHandler(Context context, String value) {
-            mContext = context;
-            mValue = value;
-        }
-
-        @Override
-        public void run() {
-            // Synchronously write the preference.
-            getDevicePrefs(mContext).edit().putString(KEY_PREFERENCE, mValue).commit();
-            // Clear the icon cache.
-            LauncherAppState.getInstance(mContext).getIconCache().clear();
-
-            // Wait for it
-            try {
-                Thread.sleep(PROCESS_KILL_DELAY_MS);
-            } catch (Exception e) {
-                Log.e(TAG, "Error waiting", e);
-            }
-
-            // Schedule an alarm before we kill ourself.
-            Intent homeIntent = new Intent(Intent.ACTION_MAIN)
-                    .addCategory(Intent.CATEGORY_HOME)
-                    .setPackage(mContext.getPackageName())
-                    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            PendingIntent pi = PendingIntent.getActivity(mContext, RESTART_REQUEST_CODE,
-                    homeIntent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT);
-            mContext.getSystemService(AlarmManager.class).setExact(
-                    AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 50, pi);
-
-            // Kill process
-            android.os.Process.killProcess(android.os.Process.myPid());
-        }
-    }
-}
diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
new file mode 100644
index 0000000..837749d
--- /dev/null
+++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java
@@ -0,0 +1,295 @@
+/*
+ * 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.graphics;
+
+import static android.view.View.MeasureSpec.EXACTLY;
+import static android.view.View.MeasureSpec.makeMeasureSpec;
+import static android.view.View.VISIBLE;
+
+import android.annotation.TargetApi;
+import android.app.Fragment;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Process;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextClock;
+
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.CellLayout;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.Hotseat;
+import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.R;
+import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.WorkspaceLayoutManager;
+import com.android.launcher3.allapps.SearchUiManager;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.icons.BaseIconFactory;
+import com.android.launcher3.icons.BitmapInfo;
+import com.android.launcher3.icons.BitmapRenderer;
+import com.android.launcher3.views.ActivityContext;
+import com.android.launcher3.views.BaseDragLayer;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * Utility class for generating the preview of Launcher for a given InvariantDeviceProfile.
+ * Steps:
+ *   1) Create a dummy icon info with just white icon
+ *   2) Inflate a strip down layout definition for Launcher
+ *   3) Place appropriate elements like icons and first-page qsb
+ *   4) Measure and draw the view on a canvas
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public class LauncherPreviewRenderer implements Callable<Bitmap> {
+
+    private static final String TAG = "LauncherPreviewRenderer";
+
+    private final Handler mUiHandler;
+    private final Context mContext;
+    private final InvariantDeviceProfile mIdp;
+    private final DeviceProfile mDp;
+    private final Rect mInsets;
+
+    private final ShortcutInfo mShortcutInfo;
+
+    public LauncherPreviewRenderer(Context context, InvariantDeviceProfile idp) {
+        mUiHandler = new Handler(Looper.getMainLooper());
+        mContext = context;
+        mIdp = idp;
+        mDp = idp.portraitProfile.copy(context);
+
+        // TODO: get correct insets once display cutout API is available.
+        mInsets = new Rect();
+        mInsets.left = mInsets.right = (mDp.widthPx - mDp.availableWidthPx) / 2;
+        mInsets.top = mInsets.bottom = (mDp.heightPx - mDp.availableHeightPx) / 2;
+        mDp.updateInsets(mInsets);
+
+        BaseIconFactory iconFactory =
+                new BaseIconFactory(context, mIdp.fillResIconDpi, mIdp.iconBitmapSize) { };
+        BitmapInfo iconInfo = iconFactory.createBadgedIconBitmap(new AdaptiveIconDrawable(
+                        new ColorDrawable(Color.WHITE), new ColorDrawable(Color.WHITE)),
+                Process.myUserHandle(),
+                Build.VERSION.SDK_INT);
+
+        mShortcutInfo = new ShortcutInfo();
+        mShortcutInfo.applyFrom(iconInfo);
+        mShortcutInfo.intent = new Intent();
+        mShortcutInfo.contentDescription = mShortcutInfo.title =
+                context.getString(R.string.label_application);
+    }
+
+    @Override
+    public Bitmap call() {
+        return BitmapRenderer.createHardwareBitmap(mDp.widthPx, mDp.heightPx, c -> {
+
+            if (Looper.myLooper() == Looper.getMainLooper()) {
+                new MainThreadRenderer(mContext).renderScreenShot(c);
+            } else {
+                CountDownLatch latch = new CountDownLatch(1);
+                Utilities.postAsyncCallback(mUiHandler, () -> {
+                    new MainThreadRenderer(mContext).renderScreenShot(c);
+                    latch.countDown();
+                });
+
+                try {
+                    latch.await();
+                } catch (Exception e) {
+                    Log.e(TAG, "Error drawing on main thread", e);
+                }
+            }
+        });
+    }
+
+    private class MainThreadRenderer extends ContextThemeWrapper
+            implements ActivityContext, WorkspaceLayoutManager, LayoutInflater.Factory2 {
+
+        private final LayoutInflater mHomeElementInflater;
+        private final InsettableFrameLayout mRootView;
+
+        private final Hotseat mHotseat;
+        private final CellLayout mWorkspace;
+
+        MainThreadRenderer(Context context) {
+            super(context, R.style.AppTheme);
+
+            mHomeElementInflater = LayoutInflater.from(
+                    new ContextThemeWrapper(this, R.style.HomeScreenElementTheme));
+            mHomeElementInflater.setFactory2(this);
+
+            mRootView = (InsettableFrameLayout) mHomeElementInflater.inflate(
+                    R.layout.launcher_preview_layout, null, false);
+            mRootView.setInsets(mInsets);
+            measureView(mRootView, mDp.widthPx, mDp.heightPx);
+
+            mHotseat = mRootView.findViewById(R.id.hotseat);
+            mHotseat.resetLayout(false);
+
+            mWorkspace = mRootView.findViewById(R.id.workspace);
+            mWorkspace.setPadding(mDp.workspacePadding.left + mDp.cellLayoutPaddingLeftRightPx,
+                    mDp.workspacePadding.top,
+                    mDp.workspacePadding.right + mDp.cellLayoutPaddingLeftRightPx,
+                    mDp.workspacePadding.bottom);
+        }
+
+        @Override
+        public View onCreateView(View parent, String name, Context context, AttributeSet attrs) {
+            if ("TextClock".equals(name)) {
+                // Workaround for TextClock accessing handler for unregistering ticker.
+                return new TextClock(context, attrs) {
+
+                    @Override
+                    public Handler getHandler() {
+                        return mUiHandler;
+                    }
+                };
+            } else if (!"fragment".equals(name)) {
+                return null;
+            }
+
+            TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.PreviewFragment);
+            FragmentWithPreview f = (FragmentWithPreview) Fragment.instantiate(
+                    context, ta.getString(R.styleable.PreviewFragment_android_name));
+            f.enterPreviewMode(context);
+            f.onInit(null);
+
+            View view = f.onCreateView(LayoutInflater.from(context), (ViewGroup) parent, null);
+            view.setId(ta.getInt(R.styleable.PreviewFragment_android_id, View.NO_ID));
+            return view;
+        }
+
+        @Override
+        public View onCreateView(String name, Context context, AttributeSet attrs) {
+            return onCreateView(null, name, context, attrs);
+        }
+
+        @Override
+        public BaseDragLayer getDragLayer() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public DeviceProfile getDeviceProfile() {
+            return mDp;
+        }
+
+        @Override
+        public Hotseat getHotseat() {
+            return mHotseat;
+        }
+
+        @Override
+        public CellLayout getScreenWithId(int screenId) {
+            return mWorkspace;
+        }
+
+        private void inflateAndAddIcon(ShortcutInfo info) {
+            BubbleTextView icon = (BubbleTextView) mHomeElementInflater.inflate(
+                    R.layout.app_icon, mWorkspace, false);
+            icon.applyFromShortcutInfo(info);
+            addInScreenFromBind(icon, info);
+        }
+
+        private void dispatchVisibilityAggregated(View view, boolean isVisible) {
+            // Similar to View.dispatchVisibilityAggregated implementation.
+            final boolean thisVisible = view.getVisibility() == VISIBLE;
+            if (thisVisible || !isVisible) {
+                view.onVisibilityAggregated(isVisible);
+            }
+
+            if (view instanceof ViewGroup) {
+                isVisible = thisVisible && isVisible;
+                ViewGroup vg = (ViewGroup) view;
+                int count = vg.getChildCount();
+
+                for (int i = 0; i < count; i++) {
+                    dispatchVisibilityAggregated(vg.getChildAt(i), isVisible);
+                }
+            }
+        }
+
+        private void renderScreenShot(Canvas canvas) {
+            // Add hotseat icons
+            for (int i = 0; i < mIdp.numHotseatIcons; i++) {
+                ShortcutInfo info = new ShortcutInfo(mShortcutInfo);
+                info.container = Favorites.CONTAINER_HOTSEAT;
+                info.screenId = i;
+                inflateAndAddIcon(info);
+            }
+
+            // Add workspace icons
+            for (int i = 0; i < mIdp.numColumns; i++) {
+                ShortcutInfo info = new ShortcutInfo(mShortcutInfo);
+                info.container = Favorites.CONTAINER_DESKTOP;
+                info.screenId = 0;
+                info.cellX = i;
+                info.cellY = mIdp.numRows - 1;
+                inflateAndAddIcon(info);
+            }
+
+            // Add first page QSB
+            if (FeatureFlags.QSB_ON_FIRST_SCREEN.get()) {
+                View qsb = mHomeElementInflater.inflate(
+                        R.layout.search_container_workspace, mWorkspace, false);
+                CellLayout.LayoutParams lp =
+                        new CellLayout.LayoutParams(0, 0, mWorkspace.getCountX(), 1);
+                lp.canReorder = false;
+                mWorkspace.addViewToCellLayout(qsb, 0, R.id.search_container_workspace, lp, true);
+            }
+
+            // Setup search view
+            SearchUiManager searchUiManager =
+                    mRootView.findViewById(R.id.search_container_all_apps);
+            mRootView.findViewById(R.id.apps_view).setTranslationY(
+                    mDp.heightPx - searchUiManager.getScrollRangeDelta(mInsets));
+
+            measureView(mRootView, mDp.widthPx, mDp.heightPx);
+            dispatchVisibilityAggregated(mRootView, true);
+            measureView(mRootView, mDp.widthPx, mDp.heightPx);
+            // Additional measure for views which use auto text size API
+            measureView(mRootView, mDp.widthPx, mDp.heightPx);
+
+            mRootView.draw(canvas);
+            dispatchVisibilityAggregated(mRootView, false);
+        }
+    }
+
+    private static void measureView(View view, int width, int height) {
+        view.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY));
+        view.layout(0, 0, width, height);
+    }
+}
diff --git a/src/com/android/launcher3/graphics/ShadowDrawable.java b/src/com/android/launcher3/graphics/ShadowDrawable.java
index 19e2768..f10b972 100644
--- a/src/com/android/launcher3/graphics/ShadowDrawable.java
+++ b/src/com/android/launcher3/graphics/ShadowDrawable.java
@@ -32,6 +32,7 @@
 import android.util.AttributeSet;
 
 import com.android.launcher3.R;
+import com.android.launcher3.icons.BitmapRenderer;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
diff --git a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
index 23d647b..6fac31e2 100644
--- a/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
+++ b/src/com/android/launcher3/graphics/WorkspaceAndHotseatScrim.java
@@ -16,14 +16,9 @@
 
 package com.android.launcher3.graphics;
 
-import static android.content.Intent.ACTION_SCREEN_OFF;
-import static android.content.Intent.ACTION_USER_PRESENT;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
 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;
@@ -94,20 +89,6 @@
                 }
             };
 
-    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;
@@ -174,7 +155,7 @@
                 canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE);
             }
 
-            canvas.drawColor(ColorUtils.setAlphaComponent(mFullScrimColor, mScrimAlpha));
+            canvas.drawColor(setColorAlphaBound(mFullScrimColor, mScrimAlpha));
             canvas.restore();
         }
 
@@ -223,20 +204,11 @@
     public void onViewAttachedToWindow(View view) {
         mWallpaperColorInfo.addOnChangeListener(this);
         onExtractedColorsChanged(mWallpaperColorInfo);
-
-        if (mTopScrim != null) {
-            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 (mTopScrim != null) {
-            mRoot.getContext().unregisterReceiver(mReceiver);
-        }
     }
 
     @Override
@@ -303,7 +275,7 @@
         LinearGradient lg = new LinearGradient(0, 0, 0, gradientHeight,
                 new int[]{
                         0x00FFFFFF,
-                        ColorUtils.setAlphaComponent(Color.WHITE, (int) (0xFF * 0.95)),
+                        setColorAlphaBound(Color.WHITE, (int) (0xFF * 0.95)),
                         0xFFFFFFFF},
                 new float[]{0f, 0.8f, 1f},
                 Shader.TileMode.CLAMP);
diff --git a/src/com/android/launcher3/icons/CachingLogic.java b/src/com/android/launcher3/icons/CachingLogic.java
deleted file mode 100644
index 24186ef..0000000
--- a/src/com/android/launcher3/icons/CachingLogic.java
+++ /dev/null
@@ -1,87 +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.icons;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.LauncherActivityInfo;
-import android.content.pm.PackageManager;
-import android.os.UserHandle;
-
-public interface CachingLogic<T> {
-
-    ComponentName getComponent(T object);
-
-    UserHandle getUser(T object);
-
-    CharSequence getLabel(T object, PackageManager pm);
-
-    void loadIcon(Context context, BaseIconCache cache, T object, BitmapInfo target);
-
-    CachingLogic<LauncherActivityInfo> LAUNCHER_ACTIVITY_INFO =
-            new CachingLogic<LauncherActivityInfo>() {
-
-        @Override
-        public ComponentName getComponent(LauncherActivityInfo object) {
-            return object.getComponentName();
-        }
-
-        @Override
-        public UserHandle getUser(LauncherActivityInfo object) {
-            return object.getUser();
-        }
-
-        @Override
-        public CharSequence getLabel(LauncherActivityInfo object, PackageManager pm) {
-            return object.getLabel();
-        }
-
-        @Override
-        public void loadIcon(Context context, BaseIconCache cache, LauncherActivityInfo object,
-                BitmapInfo target) {
-            LauncherIcons li = LauncherIcons.obtain(context);
-            li.createBadgedIconBitmap(cache.getFullResIcon(object), object.getUser(),
-                    object.getApplicationInfo().targetSdkVersion).applyTo(target);
-            li.recycle();
-        }
-    };
-
-    CachingLogic<ComponentWithLabel> COMPONENT_WITH_LABEL =
-            new CachingLogic<ComponentWithLabel>() {
-
-        @Override
-        public ComponentName getComponent(ComponentWithLabel object) {
-            return object.getComponent();
-        }
-
-        @Override
-        public UserHandle getUser(ComponentWithLabel object) {
-            return object.getUser();
-        }
-
-        @Override
-        public CharSequence getLabel(ComponentWithLabel object, PackageManager pm) {
-            return object.getLabel(pm);
-        }
-
-        @Override
-        public void loadIcon(Context context, BaseIconCache cache,
-                ComponentWithLabel object, BitmapInfo target) {
-            // Do not load icon.
-            target.icon = BitmapInfo.LOW_RES_ICON;
-        }
-    };
-}
diff --git a/src/com/android/launcher3/icons/ComponentWithLabel.java b/src/com/android/launcher3/icons/ComponentWithLabel.java
index 2badb4c..46b5002 100644
--- a/src/com/android/launcher3/icons/ComponentWithLabel.java
+++ b/src/com/android/launcher3/icons/ComponentWithLabel.java
@@ -16,9 +16,12 @@
 package com.android.launcher3.icons;
 
 import android.content.ComponentName;
+import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.UserHandle;
 
+import com.android.launcher3.icons.cache.CachingLogic;
+
 public interface ComponentWithLabel {
 
     ComponentName getComponent();
@@ -26,4 +29,36 @@
     UserHandle getUser();
 
     CharSequence getLabel(PackageManager pm);
+
+
+    class ComponentCachingLogic implements CachingLogic<ComponentWithLabel> {
+
+        private final PackageManager mPackageManager;
+
+        public ComponentCachingLogic(Context context) {
+            mPackageManager = context.getPackageManager();
+        }
+
+        @Override
+        public ComponentName getComponent(ComponentWithLabel object) {
+            return object.getComponent();
+        }
+
+        @Override
+        public UserHandle getUser(ComponentWithLabel object) {
+            return object.getUser();
+        }
+
+        @Override
+        public CharSequence getLabel(ComponentWithLabel object) {
+            return object.getLabel(mPackageManager);
+        }
+
+        @Override
+        public void loadIcon(Context context,
+                ComponentWithLabel object, BitmapInfo target) {
+            // Do not load icon.
+            target.icon = BitmapInfo.LOW_RES_ICON;
+        }
+    }
 }
diff --git a/src/com/android/launcher3/icons/IconCache.java b/src/com/android/launcher3/icons/IconCache.java
index 6e2ca28..4b54bc3 100644
--- a/src/com/android/launcher3/icons/IconCache.java
+++ b/src/com/android/launcher3/icons/IconCache.java
@@ -16,27 +16,36 @@
 
 package com.android.launcher3.icons;
 
-import static com.android.launcher3.icons.CachingLogic.COMPONENT_WITH_LABEL;
-import static com.android.launcher3.icons.CachingLogic.LAUNCHER_ACTIVITY_INFO;
-
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Process;
 import android.os.UserHandle;
 import android.util.Log;
 
 import com.android.launcher3.AppInfo;
+import com.android.launcher3.IconProvider;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.ItemInfoWithIcon;
+import com.android.launcher3.LauncherFiles;
 import com.android.launcher3.LauncherModel;
+import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
+import com.android.launcher3.icons.cache.BaseIconCache;
+import com.android.launcher3.icons.cache.CachingLogic;
+import com.android.launcher3.icons.cache.HandlerRunnable;
 import com.android.launcher3.model.PackageItemInfo;
+import com.android.launcher3.util.InstantAppResolver;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Provider;
 
@@ -49,10 +58,42 @@
 
     private static final String TAG = "Launcher.IconCache";
 
+    private final MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
+
+    private final CachingLogic<ComponentWithLabel> mComponentWithLabelCachingLogic;
+    private final CachingLogic<LauncherActivityInfo> mLauncherActivityInfoCachingLogic;
+
+    private final LauncherAppsCompat mLauncherApps;
+    private final UserManagerCompat mUserManager;
+    private final InstantAppResolver mInstantAppResolver;
+    private final IconProvider mIconProvider;
+
     private int mPendingIconRequestCount = 0;
 
     public IconCache(Context context, InvariantDeviceProfile inv) {
-        super(context, inv.fillResIconDpi, inv.iconBitmapSize);
+        super(context, LauncherFiles.APP_ICONS_DB, LauncherModel.getWorkerLooper(),
+                inv.fillResIconDpi, inv.iconBitmapSize, true /* inMemoryCache */);
+        mComponentWithLabelCachingLogic = new ComponentCachingLogic(context);
+        mLauncherActivityInfoCachingLogic = new LauncherActivtiyCachingLogic(this);
+        mLauncherApps = LauncherAppsCompat.getInstance(mContext);
+        mUserManager = UserManagerCompat.getInstance(mContext);
+        mInstantAppResolver = InstantAppResolver.newInstance(mContext);
+        mIconProvider = IconProvider.newInstance(context);
+    }
+
+    @Override
+    protected long getSerialNumberForUser(UserHandle user) {
+        return mUserManager.getSerialNumberForUser(user);
+    }
+
+    @Override
+    protected boolean isInstantApp(ApplicationInfo info) {
+        return mInstantAppResolver.isInstantApp(info);
+    }
+
+    @Override
+    protected BaseIconFactory getIconFactory() {
+        return LauncherIcons.obtain(mContext);
     }
 
     /**
@@ -65,7 +106,7 @@
                     PackageManager.GET_UNINSTALLED_PACKAGES);
             long userSerial = mUserManager.getSerialNumberForUser(user);
             for (LauncherActivityInfo app : mLauncherApps.getActivityList(packageName, user)) {
-                addIconToDBAndMemCache(app, LAUNCHER_ACTIVITY_INFO, info, userSerial,
+                addIconToDBAndMemCache(app, mLauncherActivityInfoCachingLogic, info, userSerial,
                         false /*replace existing*/);
             }
         } catch (NameNotFoundException e) {
@@ -115,7 +156,7 @@
      */
     public synchronized void updateTitleAndIcon(AppInfo application) {
         CacheEntry entry = cacheLocked(application.componentName,
-                application.user, Provider.of(null), LAUNCHER_ACTIVITY_INFO,
+                application.user, Provider.of(null), mLauncherActivityInfoCachingLogic,
                 false, application.usingLowResIcon());
         if (entry.icon != null && !isDefaultIcon(entry.icon, application.user)) {
             applyCacheEntry(entry, application);
@@ -151,8 +192,8 @@
 
     public synchronized String getTitleNoCache(ComponentWithLabel info) {
         CacheEntry entry = cacheLocked(info.getComponent(), info.getUser(), Provider.of(info),
-                COMPONENT_WITH_LABEL, false /* usePackageIcon */, true /* useLowResIcon */,
-                false /* addToMemCache */);
+                mComponentWithLabelCachingLogic, false /* usePackageIcon */,
+                true /* useLowResIcon */, false /* addToMemCache */);
         return Utilities.trim(entry.title);
     }
 
@@ -164,11 +205,40 @@
             @NonNull Provider<LauncherActivityInfo> activityInfoProvider,
             boolean usePkgIcon, boolean useLowResIcon) {
         CacheEntry entry = cacheLocked(infoInOut.getTargetComponent(), infoInOut.user,
-                activityInfoProvider,
-                LAUNCHER_ACTIVITY_INFO, usePkgIcon, useLowResIcon);
+                activityInfoProvider, mLauncherActivityInfoCachingLogic, usePkgIcon, useLowResIcon);
         applyCacheEntry(entry, infoInOut);
     }
 
+
+    /**
+     * Fill in {@param infoInOut} with the corresponding icon and label.
+     */
+    public synchronized void getTitleAndIconForApp(
+            PackageItemInfo infoInOut, boolean useLowResIcon) {
+        CacheEntry entry = getEntryForPackageLocked(
+                infoInOut.packageName, infoInOut.user, useLowResIcon);
+        applyCacheEntry(entry, infoInOut);
+    }
+
+    protected void applyCacheEntry(CacheEntry entry, ItemInfoWithIcon info) {
+        info.title = Utilities.trim(entry.title);
+        info.contentDescription = entry.contentDescription;
+        info.applyFrom((entry.icon == null) ? getDefaultIcon(info.user) : entry);
+    }
+
+    public Drawable getFullResIcon(LauncherActivityInfo info) {
+        return getFullResIcon(info, true);
+    }
+
+    public Drawable getFullResIcon(LauncherActivityInfo info, boolean flattenDrawable) {
+        return mIconProvider.getIcon(info, mIconDpi, flattenDrawable);
+    }
+
+    @Override
+    protected String getIconSystemState(String packageName) {
+        return mIconProvider.getSystemStateForPackage(mSystemState, packageName);
+    }
+
     public static abstract class IconLoadRequest extends HandlerRunnable {
         IconLoadRequest(Handler handler, Runnable endRunnable) {
             super(handler, endRunnable);
diff --git a/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java b/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java
new file mode 100644
index 0000000..7c99633
--- /dev/null
+++ b/src/com/android/launcher3/icons/LauncherActivtiyCachingLogic.java
@@ -0,0 +1,56 @@
+/*
+ * 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.icons;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.LauncherActivityInfo;
+import android.os.UserHandle;
+
+import com.android.launcher3.icons.cache.CachingLogic;
+
+public class LauncherActivtiyCachingLogic implements CachingLogic<LauncherActivityInfo> {
+
+    private final IconCache mCache;
+
+    public LauncherActivtiyCachingLogic(IconCache cache) {
+        mCache = cache;
+    }
+
+    @Override
+    public ComponentName getComponent(LauncherActivityInfo object) {
+        return object.getComponentName();
+    }
+
+    @Override
+    public UserHandle getUser(LauncherActivityInfo object) {
+        return object.getUser();
+    }
+
+    @Override
+    public CharSequence getLabel(LauncherActivityInfo object) {
+        return object.getLabel();
+    }
+
+    @Override
+    public void loadIcon(Context context, LauncherActivityInfo object,
+            BitmapInfo target) {
+        LauncherIcons li = LauncherIcons.obtain(context);
+        li.createBadgedIconBitmap(mCache.getFullResIcon(object),
+                object.getUser(), object.getApplicationInfo().targetSdkVersion).applyTo(target);
+        li.recycle();
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/icons/LauncherIcons.java b/src/com/android/launcher3/icons/LauncherIcons.java
index c96d35d..f0a63ba 100644
--- a/src/com/android/launcher3/icons/LauncherIcons.java
+++ b/src/com/android/launcher3/icons/LauncherIcons.java
@@ -21,17 +21,13 @@
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
-import android.os.Build;
 import android.os.Process;
-import android.os.UserHandle;
 
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.FastBitmapDrawable;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.ItemInfoWithIcon;
 import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.Utilities;
-import com.android.launcher3.graphics.BitmapRenderer;
 import com.android.launcher3.model.PackageItemInfo;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
@@ -77,18 +73,12 @@
         }
     }
 
-    private final Context mContext;
-    private final int mFillResIconDpi;
-    private final int mIconBitmapSize;
     private final int mPoolId;
 
     private LauncherIcons next;
 
     private LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize, int poolId) {
         super(context, fillResIconDpi, iconBitmapSize);
-        mContext = context.getApplicationContext();
-        mFillResIconDpi = fillResIconDpi;
-        mIconBitmapSize = iconBitmapSize;
         mPoolId = poolId;
     }
 
@@ -113,29 +103,6 @@
         recycle();
     }
 
-    public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
-            int iconAppTargetSdk) {
-        return createBadgedIconBitmap(icon, user, iconAppTargetSdk, false);
-    }
-
-    public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
-            int iconAppTargetSdk, boolean isInstantApp) {
-        return createBadgedIconBitmap(icon, user, iconAppTargetSdk, isInstantApp, null);
-    }
-
-    public BitmapInfo createBadgedIconBitmap(Drawable icon, UserHandle user,
-            int iconAppTargetSdk, boolean isInstantApp, float[] scale) {
-        boolean shrinkNonAdaptiveIcons = Utilities.ATLEAST_P ||
-                (Utilities.ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O);
-        return createBadgedIconBitmap(icon, user, shrinkNonAdaptiveIcons, isInstantApp, scale);
-    }
-
-    public Bitmap createScaledBitmapWithoutShadow(Drawable icon, int iconAppTargetSdk) {
-        boolean shrinkNonAdaptiveIcons = Utilities.ATLEAST_P ||
-                (Utilities.ATLEAST_OREO && iconAppTargetSdk >= Build.VERSION_CODES.O);
-        return  createScaledBitmapWithoutShadow(icon, shrinkNonAdaptiveIcons);
-    }
-
     // below methods should also migrate to BaseIconFactory
 
     public BitmapInfo createShortcutIcon(ShortcutInfoCompat shortcutInfo) {
@@ -147,7 +114,7 @@
     }
 
     public BitmapInfo createShortcutIcon(ShortcutInfoCompat shortcutInfo,
-            boolean badged, @Nullable Provider<Bitmap> fallbackIconProvider) {
+            boolean badged, @Nullable Provider<ItemInfoWithIcon> fallbackIconProvider) {
         Drawable unbadgedDrawable = DeepShortcutManager.getInstance(mContext)
                 .getShortcutIconDrawable(shortcutInfo, mFillResIconDpi);
         IconCache cache = LauncherAppState.getInstance(mContext).getIconCache();
@@ -158,9 +125,12 @@
         } else {
             if (fallbackIconProvider != null) {
                 // Fallback icons are already badged and with appropriate shadow
-                Bitmap fullIcon = fallbackIconProvider.get();
-                if (fullIcon != null) {
-                    return createIconBitmap(fullIcon);
+                ItemInfoWithIcon fullIcon = fallbackIconProvider.get();
+                if (fullIcon != null && fullIcon.iconBitmap != null) {
+                    BitmapInfo result = new BitmapInfo();
+                    result.icon = fullIcon.iconBitmap;
+                    result.color = fullIcon.iconColor;
+                    return result;
                 }
             }
             unbadgedBitmap = cache.getDefaultIcon(Process.myUserHandle()).icon;
diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java
index d332dc5..9b9543e 100644
--- a/src/com/android/launcher3/logging/StatsLogManager.java
+++ b/src/com/android/launcher3/logging/StatsLogManager.java
@@ -26,10 +26,8 @@
 
 /**
  * Handles the user event logging in Q.
- * Since the AOSP Launcher3 doesn't take part in the StatsLog logging, the class
- * itself is abstract.
  */
-public abstract class StatsLogManager implements ResourceBasedOverride {
+public class StatsLogManager implements ResourceBasedOverride {
 
     protected LogStateProvider mStateProvider;
     public static StatsLogManager newInstance(Context context, LogStateProvider stateProvider) {
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 756d44e..0d55301 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -15,11 +15,11 @@
  */
 package com.android.launcher3.model;
 
-import android.content.Context;
 import android.content.Intent;
 import android.os.UserHandle;
 import android.util.LongSparseArray;
 import android.util.Pair;
+
 import com.android.launcher3.AllAppsList;
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.FolderInfo;
@@ -27,7 +27,6 @@
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetInfo;
-import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherModel.CallbackTask;
 import com.android.launcher3.LauncherModel.Callbacks;
 import com.android.launcher3.LauncherSettings;
@@ -58,16 +57,12 @@
         if (mItemList.isEmpty()) {
             return;
         }
-        Context context = app.getContext();
 
         final ArrayList<ItemInfo> addedItemsFinal = new ArrayList<>();
         final IntArray addedWorkspaceScreensFinal = new IntArray();
 
-        // Get the list of workspace screens.  We need to append to this list and
-        // can not use sBgWorkspaceScreens because loadWorkspace() may not have been
-        // called.
-        IntArray workspaceScreens = LauncherModel.loadWorkspaceScreensDb(context);
         synchronized(dataModel) {
+            IntArray workspaceScreens = dataModel.collectWorkspaceScreens();
 
             List<ItemInfo> filteredItems = new ArrayList<>();
             for (Pair<ItemInfo, Object> entry : mItemList) {
@@ -116,9 +111,6 @@
             }
         }
 
-        // Update the workspace screens
-        updateScreens(context, workspaceScreens);
-
         if (!addedItemsFinal.isEmpty()) {
             scheduleCallbackTask(new CallbackTask() {
                 @Override
@@ -143,10 +135,6 @@
         }
     }
 
-    protected void updateScreens(Context context, IntArray workspaceScreens) {
-        LauncherModel.updateWorkspaceScreenOrder(context, workspaceScreens);
-    }
-
     /**
      * Returns true if the shortcuts already exists on the workspace. This must be called after
      * the workspace has been loaded. We identify a shortcut by its intent.
diff --git a/src/com/android/launcher3/model/LoaderResults.java b/src/com/android/launcher3/model/BaseLoaderResults.java
similarity index 65%
rename from src/com/android/launcher3/model/LoaderResults.java
rename to src/com/android/launcher3/model/BaseLoaderResults.java
index 1d18e76..23c6faf 100644
--- a/src/com/android/launcher3/model/LoaderResults.java
+++ b/src/com/android/launcher3/model/BaseLoaderResults.java
@@ -25,60 +25,56 @@
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetInfo;
+import com.android.launcher3.LauncherModel.CallbackTask;
 import com.android.launcher3.LauncherModel.Callbacks;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.PagedView;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.LooperIdleLock;
 import com.android.launcher3.util.ViewOnDrawExecutor;
-import com.android.launcher3.widget.WidgetListRowEntry;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.concurrent.Executor;
 
 /**
- * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
+ * Base Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
  */
-public class LoaderResults {
+public abstract class BaseLoaderResults {
 
-    private static final String TAG = "LoaderResults";
-    private static final int INVALID_SCREEN_ID = -1;
+    protected static final String TAG = "LoaderResults";
+    protected static final int INVALID_SCREEN_ID = -1;
     private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons
 
-    private final Executor mUiExecutor;
+    protected final Executor mUiExecutor;
 
-    private final LauncherAppState mApp;
-    private final BgDataModel mBgDataModel;
+    protected final LauncherAppState mApp;
+    protected final BgDataModel mBgDataModel;
     private final AllAppsList mBgAllAppsList;
-    private final int mPageToBindFirst;
+    protected final int mPageToBindFirst;
 
-    private final WeakReference<Callbacks> mCallbacks;
+    protected final WeakReference<Callbacks> mCallbacks;
 
-    public LoaderResults(LauncherAppState app, BgDataModel dataModel,
+    public BaseLoaderResults(LauncherAppState app, BgDataModel dataModel,
             AllAppsList allAppsList, int pageToBindFirst, WeakReference<Callbacks> callbacks) {
         mUiExecutor = new MainThreadExecutor();
         mApp = app;
         mBgDataModel = dataModel;
         mBgAllAppsList = allAppsList;
         mPageToBindFirst = pageToBindFirst;
-        mCallbacks = callbacks == null ? new WeakReference<Callbacks>(null) : callbacks;
+        mCallbacks = callbacks == null ? new WeakReference<>(null) : callbacks;
     }
 
     /**
      * Binds all loaded data to actual views on the main thread.
      */
     public void bindWorkspace() {
-        Runnable r;
-
         Callbacks callbacks = mCallbacks.get();
         // Don't use these two variables in any of the callback runnables.
         // Otherwise we hold a reference to them.
@@ -96,7 +92,7 @@
         synchronized (mBgDataModel) {
             workspaceItems.addAll(mBgDataModel.workspaceItems);
             appWidgets.addAll(mBgDataModel.appWidgets);
-            orderedScreenIds.addAll(mBgDataModel.workspaceScreens);
+            orderedScreenIds.addAll(mBgDataModel.collectWorkspaceScreens());
             mBgDataModel.lastBindId++;
         }
 
@@ -128,32 +124,18 @@
         sortWorkspaceItemsSpatially(otherWorkspaceItems);
 
         // Tell the workspace that we're about to start binding items
-        r = new Runnable() {
-            public void run() {
-                Callbacks callbacks = mCallbacks.get();
-                if (callbacks != null) {
-                    callbacks.clearPendingBinds();
-                    callbacks.startBinding();
-                }
-            }
-        };
-        mUiExecutor.execute(r);
+        executeCallbacksTask(c -> {
+            c.clearPendingBinds();
+            c.startBinding();
+        }, mUiExecutor);
 
         // Bind workspace screens
-        mUiExecutor.execute(new Runnable() {
-            @Override
-            public void run() {
-                Callbacks callbacks = mCallbacks.get();
-                if (callbacks != null) {
-                    callbacks.bindScreens(orderedScreenIds);
-                }
-            }
-        });
+        executeCallbacksTask(c -> c.bindScreens(orderedScreenIds), mUiExecutor);
 
         Executor mainExecutor = mUiExecutor;
         // Load items on the current page.
-        bindWorkspaceItems(currentWorkspaceItems, currentAppWidgets, mainExecutor);
-
+        bindWorkspaceItems(currentWorkspaceItems, mainExecutor);
+        bindAppWidgets(currentAppWidgets, mainExecutor);
         // In case of validFirstPage, only bind the first screen, and defer binding the
         // remaining screens after first onDraw (and an optional the fade animation whichever
         // happens later).
@@ -162,46 +144,25 @@
         final Executor deferredExecutor =
                 validFirstPage ? new ViewOnDrawExecutor() : mainExecutor;
 
-        mainExecutor.execute(new Runnable() {
-            @Override
-            public void run() {
-                Callbacks callbacks = mCallbacks.get();
-                if (callbacks != null) {
-                    callbacks.finishFirstPageBind(
-                            validFirstPage ? (ViewOnDrawExecutor) deferredExecutor : null);
-                }
-            }
-        });
+        executeCallbacksTask(c -> c.finishFirstPageBind(
+                validFirstPage ? (ViewOnDrawExecutor) deferredExecutor : null), mainExecutor);
 
-        bindWorkspaceItems(otherWorkspaceItems, otherAppWidgets, deferredExecutor);
-
+        bindWorkspaceItems(otherWorkspaceItems, deferredExecutor);
+        bindAppWidgets(otherAppWidgets, deferredExecutor);
         // Tell the workspace that we're done binding items
-        r = new Runnable() {
-            public void run() {
-                Callbacks callbacks = mCallbacks.get();
-                if (callbacks != null) {
-                    callbacks.finishBindingItems(currentScreen);
-                }
-            }
-        };
-        deferredExecutor.execute(r);
+        executeCallbacksTask(c -> c.finishBindingItems(mPageToBindFirst), deferredExecutor);
 
         if (validFirstPage) {
-            r = new Runnable() {
-                public void run() {
-                    Callbacks callbacks = mCallbacks.get();
-                    if (callbacks != null) {
-                        // We are loading synchronously, which means, some of the pages will be
-                        // bound after first draw. Inform the callbacks that page binding is
-                        // not complete, and schedule the remaining pages.
-                        if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {
-                            callbacks.onPageBoundSynchronously(currentScreen);
-                        }
-                        callbacks.executeOnNextDraw((ViewOnDrawExecutor) deferredExecutor);
-                    }
+            executeCallbacksTask(c -> {
+                // We are loading synchronously, which means, some of the pages will be
+                // bound after first draw. Inform the callbacks that page binding is
+                // not complete, and schedule the remaining pages.
+                if (currentScreen != PagedView.INVALID_RESTORE_PAGE) {
+                    c.onPageBoundSynchronously(currentScreen);
                 }
-            };
-            mUiExecutor.execute(r);
+                c.executeOnNextDraw((ViewOnDrawExecutor) deferredExecutor);
+
+            }, mUiExecutor);
         }
     }
 
@@ -252,7 +213,7 @@
 
     /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to
      * right) */
-    private void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) {
+    protected void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) {
         final InvariantDeviceProfile profile = mApp.getInvariantDeviceProfile();
         final int screenCols = profile.numColumns;
         final int screenCellCount = profile.numColumns * profile.numRows;
@@ -261,7 +222,7 @@
             public int compare(ItemInfo lhs, ItemInfo rhs) {
                 if (lhs.container == rhs.container) {
                     // Within containers, order by their spatial position in that container
-                    switch ((int) lhs.container) {
+                    switch (lhs.container) {
                         case LauncherSettings.Favorites.CONTAINER_DESKTOP: {
                             int lr = (lhs.screenId * screenCellCount +
                                     lhs.cellY * screenCols + lhs.cellX);
@@ -288,89 +249,52 @@
         });
     }
 
-    private void bindWorkspaceItems(final ArrayList<ItemInfo> workspaceItems,
-            final ArrayList<LauncherAppWidgetInfo> appWidgets,
+    protected void bindWorkspaceItems(final ArrayList<ItemInfo> workspaceItems,
             final Executor executor) {
 
         if (com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS
                 && com.android.launcher3.Utilities.IS_DEBUG_DEVICE) {
-            android.util.Log.d("b/117332845",
-                    android.util.Log.getStackTraceString(new Throwable()));
+            Log.d("b/117332845", Log.getStackTraceString(new Throwable()));
         }
         // Bind the workspace items
         int N = workspaceItems.size();
         for (int i = 0; i < N; i += ITEMS_CHUNK) {
             final int start = i;
             final int chunkSize = (i+ITEMS_CHUNK <= N) ? ITEMS_CHUNK : (N-i);
-            final Runnable r = new Runnable() {
-                @Override
-                public void run() {
-                    Callbacks callbacks = mCallbacks.get();
-                    if (callbacks != null) {
-                        callbacks.bindItems(workspaceItems.subList(start, start+chunkSize), false);
-                    }
-                }
-            };
-            executor.execute(r);
+            executeCallbacksTask(
+                    c -> c.bindItems(workspaceItems.subList(start, start + chunkSize), false),
+                    executor);
         }
+    }
 
-        // Bind the widgets, one at a time
+    private void bindAppWidgets(ArrayList<LauncherAppWidgetInfo> appWidgets, Executor executor) {
+        int N;// Bind the widgets, one at a time
         N = appWidgets.size();
         for (int i = 0; i < N; i++) {
             final ItemInfo widget = appWidgets.get(i);
-            final Runnable r = new Runnable() {
-                public void run() {
-                    Callbacks callbacks = mCallbacks.get();
-                    if (callbacks != null) {
-                        callbacks.bindItems(Collections.singletonList(widget), false);
-                    }
-                }
-            };
-            executor.execute(r);
+            executeCallbacksTask(
+                    c -> c.bindItems(Collections.singletonList(widget), false), executor);
         }
     }
 
-    public void bindDeepShortcuts() {
-        final HashMap<ComponentKey, Integer> shortcutMapCopy;
-        synchronized (mBgDataModel) {
-            shortcutMapCopy = new HashMap<>(mBgDataModel.deepShortcutMap);
-        }
-        mUiExecutor.execute(() -> {
-            Callbacks callbacks = mCallbacks.get();
-            if (callbacks != null) {
-                callbacks.bindDeepShortcutMap(shortcutMapCopy);
-            }
-        });
-    }
+    public abstract void bindDeepShortcuts();
 
     public void bindAllApps() {
         // shallow copy
         @SuppressWarnings("unchecked")
-        final ArrayList<AppInfo> list = (ArrayList<AppInfo>) mBgAllAppsList.data.clone();
-
-        Runnable r = new Runnable() {
-            public void run() {
-                Callbacks callbacks = mCallbacks.get();
-                if (callbacks != null) {
-                    callbacks.bindAllApplications(list);
-                }
-            }
-        };
-        mUiExecutor.execute(r);
+        ArrayList<AppInfo> list = (ArrayList<AppInfo>) mBgAllAppsList.data.clone();
+        executeCallbacksTask(c -> c.bindAllApplications(list), mUiExecutor);
     }
 
-    public void bindWidgets() {
-        final ArrayList<WidgetListRowEntry> widgets =
-                mBgDataModel.widgetsModel.getWidgetsList(mApp.getContext());
-        Runnable r = new Runnable() {
-            public void run() {
-                Callbacks callbacks = mCallbacks.get();
-                if (callbacks != null) {
-                    callbacks.bindAllWidgets(widgets);
-                }
+    public abstract void bindWidgets();
+
+    protected void executeCallbacksTask(CallbackTask task, Executor executor) {
+        executor.execute(() -> {
+            Callbacks callbacks = mCallbacks.get();
+            if (callbacks != null) {
+                task.execute(callbacks);
             }
-        };
-        mUiExecutor.execute(r);
+        });
     }
 
     public LooperIdleLock newIdleLock(Object lock) {
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 151d6f4..b338fff 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -27,6 +27,7 @@
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.Workspace;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.DumpTargetWrapper;
 import com.android.launcher3.model.nano.LauncherDumpProto;
@@ -37,6 +38,7 @@
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.IntArray;
+import com.android.launcher3.util.IntSet;
 import com.android.launcher3.util.IntSparseArrayMap;
 import com.google.protobuf.nano.MessageNano;
 
@@ -81,11 +83,6 @@
     public final IntSparseArrayMap<FolderInfo> folders = new IntSparseArrayMap<>();
 
     /**
-     * Ordered list of workspace screens ids.
-     */
-    public final IntArray workspaceScreens = new IntArray();
-
-    /**
      * Map of ShortcutKey to the number of times it is pinned.
      */
     public final Map<ShortcutKey, MutableInt> pinnedShortcutCounts = new HashMap<>();
@@ -118,11 +115,26 @@
         appWidgets.clear();
         folders.clear();
         itemsIdMap.clear();
-        workspaceScreens.clear();
         pinnedShortcutCounts.clear();
         deepShortcutMap.clear();
     }
 
+    /**
+     * Creates an array of valid workspace screens based on current items in the model.
+     */
+    public synchronized IntArray collectWorkspaceScreens() {
+        IntSet screenSet = new IntSet();
+        for (ItemInfo item: itemsIdMap) {
+            if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+                screenSet.add(item.screenId);
+            }
+        }
+        if (FeatureFlags.QSB_ON_FIRST_SCREEN.get() || screenSet.isEmpty()) {
+            screenSet.add(Workspace.FIRST_SCREEN_ID);
+        }
+        return screenSet.getArray();
+    }
+
     public synchronized void dump(String prefix, FileDescriptor fd, PrintWriter writer,
             String[] args) {
         if (Arrays.asList(args).contains("--proto")) {
@@ -130,11 +142,6 @@
             return;
         }
         writer.println(prefix + "Data Model:");
-        writer.print(prefix + " ---- workspace screens: ");
-        for (int i = 0; i < workspaceScreens.size(); i++) {
-            writer.print(" " + workspaceScreens.get(i));
-        }
-        writer.println();
         writer.println(prefix + " ---- workspace items ");
         for (int i = 0; i < workspaceItems.size(); i++) {
             writer.println(prefix + '\t' + workspaceItems.get(i).toString());
@@ -167,6 +174,7 @@
         // Add top parent nodes. (L1)
         DumpTargetWrapper hotseat = new DumpTargetWrapper(ContainerType.HOTSEAT, 0);
         IntSparseArrayMap<DumpTargetWrapper> workspaces = new IntSparseArrayMap<>();
+        IntArray workspaceScreens = collectWorkspaceScreens();
         for (int i = 0; i < workspaceScreens.size(); i++) {
             workspaces.put(workspaceScreens.get(i),
                     new DumpTargetWrapper(ContainerType.WORKSPACE, i));
diff --git a/src/com/android/launcher3/model/DbDowngradeHelper.java b/src/com/android/launcher3/model/DbDowngradeHelper.java
index cd86b72..e5c44d1 100644
--- a/src/com/android/launcher3/model/DbDowngradeHelper.java
+++ b/src/com/android/launcher3/model/DbDowngradeHelper.java
@@ -21,6 +21,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 
+import com.android.launcher3.R;
 import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
 import com.android.launcher3.util.IOUtils;
 
@@ -87,8 +88,7 @@
         return helper;
     }
 
-    public static void updateSchemaFile(File schemaFile, int expectedVersion,
-            Context context, int schemaResId) {
+    public static void updateSchemaFile(File schemaFile, int expectedVersion, Context context) {
         try {
             if (DbDowngradeHelper.parse(schemaFile).version >= expectedVersion) {
                 return;
@@ -99,7 +99,7 @@
 
         // Write the updated schema
         try (FileOutputStream fos = new FileOutputStream(schemaFile);
-            InputStream in = context.getResources().openRawResource(schemaResId)) {
+            InputStream in = context.getResources().openRawResource(R.raw.downgrade_schema)) {
             IOUtils.copy(in, fos);
         } catch (IOException e) {
             Log.e(TAG, "Error writing schema file", e);
diff --git a/src/com/android/launcher3/model/GridBackupTable.java b/src/com/android/launcher3/model/GridBackupTable.java
new file mode 100644
index 0000000..804a040
--- /dev/null
+++ b/src/com/android/launcher3/model/GridBackupTable.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.model;
+
+import static com.android.launcher3.LauncherSettings.Favorites.BACKUP_TABLE_NAME;
+import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
+import static com.android.launcher3.provider.LauncherDbUtils.tableExists;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.graphics.Point;
+import android.os.Process;
+import android.util.Log;
+
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.Settings;
+import com.android.launcher3.compat.UserManagerCompat;
+
+/**
+ * Helper class to backup and restore Favorites table into a separate table
+ * within the same data base.
+ */
+public class GridBackupTable {
+    private static final String TAG = "GridBackupTable";
+
+    private static final int ID_PROPERTY = -1;
+
+    private static final String KEY_HOTSEAT_SIZE = Favorites.SCREEN;
+    private static final String KEY_GRID_X_SIZE = Favorites.SPANX;
+    private static final String KEY_GRID_Y_SIZE = Favorites.SPANY;
+    private static final String KEY_DB_VERSION = Favorites.RANK;
+
+    private final Context mContext;
+    private final SQLiteDatabase mDb;
+
+    private final int mOldHotseatSize;
+    private final int mOldGridX;
+    private final int mOldGridY;
+
+    private int mRestoredHotseatSize;
+    private int mRestoredGridX;
+    private int mRestoredGridY;
+
+    public GridBackupTable(Context context, SQLiteDatabase db,
+            int hotseatSize, int gridX, int gridY) {
+        mContext = context;
+        mDb = db;
+
+        mOldHotseatSize = hotseatSize;
+        mOldGridX = gridX;
+        mOldGridY = gridY;
+    }
+
+    public boolean backupOrRestoreAsNeeded() {
+        // Check if backup table exists
+        if (!tableExists(mDb, BACKUP_TABLE_NAME)) {
+            if (Settings.call(mContext.getContentResolver(), Settings.METHOD_WAS_EMPTY_DB_CREATED)
+                    .getBoolean(Settings.EXTRA_VALUE, false)) {
+                // No need to copy if empty DB was created.
+                return false;
+            }
+
+            copyTable(Favorites.TABLE_NAME, BACKUP_TABLE_NAME);
+            encodeDBProperties();
+            return false;
+        }
+
+        if (!loadDbProperties()) {
+            return false;
+        }
+        copyTable(BACKUP_TABLE_NAME, Favorites.TABLE_NAME);
+        Log.d(TAG, "Backup table found");
+        return true;
+    }
+
+    public int getRestoreHotseatAndGridSize(Point outGridSize) {
+        outGridSize.set(mRestoredGridX, mRestoredGridY);
+        return mRestoredHotseatSize;
+    }
+
+    private void copyTable(String from, String to) {
+        long userSerial = UserManagerCompat.getInstance(mContext).getSerialNumberForUser(
+                Process.myUserHandle());
+        dropTable(mDb, to);
+        Favorites.addTableToDb(mDb, userSerial, false, to);
+        mDb.execSQL("INSERT INTO " + to + " SELECT * FROM " + from + " where _id > " + ID_PROPERTY);
+    }
+
+    private void encodeDBProperties() {
+        ContentValues values = new ContentValues();
+        values.put(Favorites._ID, ID_PROPERTY);
+        values.put(KEY_DB_VERSION, mDb.getVersion());
+        values.put(KEY_GRID_X_SIZE, mOldGridX);
+        values.put(KEY_GRID_Y_SIZE, mOldGridY);
+        values.put(KEY_HOTSEAT_SIZE, mOldHotseatSize);
+        mDb.insert(BACKUP_TABLE_NAME, null, values);
+    }
+
+    private boolean loadDbProperties() {
+        try (Cursor c = mDb.query(BACKUP_TABLE_NAME, new String[] {
+                        KEY_DB_VERSION,     // 0
+                        KEY_GRID_X_SIZE,    // 1
+                        KEY_GRID_Y_SIZE,    // 2
+                        KEY_HOTSEAT_SIZE},  // 3
+                "_id=" + ID_PROPERTY, null, null, null, null)) {
+            if (!c.moveToNext()) {
+                Log.e(TAG, "Meta data not found in backup table");
+                return false;
+            }
+            if (mDb.getVersion() != c.getInt(0)) {
+                return false;
+            }
+
+            mRestoredGridX = c.getInt(1);
+            mRestoredGridY = c.getInt(2);
+            mRestoredHotseatSize = c.getInt(3);
+            return true;
+        }
+    }
+}
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
index 2c1aa74..1c7bffa 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTask.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -1,7 +1,10 @@
 package com.android.launcher3.model;
 
+import static com.android.launcher3.LauncherSettings.Settings.EXTRA_VALUE;
+import static com.android.launcher3.Utilities.getPointString;
+import static com.android.launcher3.Utilities.parsePoint;
+
 import android.content.ComponentName;
-import android.content.ContentProviderOperation;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -9,23 +12,25 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Point;
-import android.net.Uri;
 import android.util.Log;
+import android.util.SparseArray;
 
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.Settings;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.provider.LauncherDbUtils;
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
 import com.android.launcher3.util.GridOccupancy;
 import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.IntSparseArrayMap;
@@ -33,7 +38,8 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.Locale;
+
+import androidx.annotation.VisibleForTesting;
 
 /**
  * This class takes care of shrinking the workspace (by maximum of one row and one column), as a
@@ -57,13 +63,13 @@
     private static final float WT_WIDGET_FACTOR = 0.6f;
     private static final float WT_FOLDER_FACTOR = 0.5f;
 
-    private final Context mContext;
-    private final InvariantDeviceProfile mIdp;
+    protected final SQLiteDatabase mDb;
+    protected final Context mContext;
 
-    private final ContentValues mTempValues = new ContentValues();
     protected final IntArray mEntryToRemove = new IntArray();
-    private final ArrayList<ContentProviderOperation> mUpdateOperations = new ArrayList<>();
     protected final ArrayList<DbEntry> mCarryOver = new ArrayList<>();
+
+    private final SparseArray<ContentValues> mUpdateOperations = new SparseArray<>();
     private final HashSet<String> mValidPackages;
 
     private final int mSrcX, mSrcY;
@@ -73,11 +79,11 @@
     private final int mSrcHotseatSize;
     private final int mDestHotseatSize;
 
-    protected GridSizeMigrationTask(Context context, InvariantDeviceProfile idp,
+    protected GridSizeMigrationTask(Context context, SQLiteDatabase db,
             HashSet<String> validPackages, Point sourceSize, Point targetSize) {
         mContext = context;
+        mDb = db;
         mValidPackages = validPackages;
-        mIdp = idp;
 
         mSrcX = sourceSize.x;
         mSrcY = sourceSize.y;
@@ -92,11 +98,10 @@
         mSrcHotseatSize = mDestHotseatSize = -1;
     }
 
-    protected GridSizeMigrationTask(Context context,
-            InvariantDeviceProfile idp, HashSet<String> validPackages,
-            int srcHotseatSize, int destHotseatSize) {
+    protected GridSizeMigrationTask(Context context, SQLiteDatabase db,
+            HashSet<String> validPackages, int srcHotseatSize, int destHotseatSize) {
         mContext = context;
-        mIdp = idp;
+        mDb = db;
         mValidPackages = validPackages;
 
         mSrcHotseatSize = srcHotseatSize;
@@ -115,20 +120,21 @@
      */
     private boolean applyOperations() throws Exception {
         // Update items
-        if (!mUpdateOperations.isEmpty()) {
-            mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY, mUpdateOperations);
+        int updateCount = mUpdateOperations.size();
+        for (int i = 0; i < updateCount; i++) {
+            mDb.update(Favorites.TABLE_NAME, mUpdateOperations.valueAt(i),
+                    "_id=" + mUpdateOperations.keyAt(i), null);
         }
 
         if (!mEntryToRemove.isEmpty()) {
             if (DEBUG) {
                 Log.d(TAG, "Removing items: " + mEntryToRemove.toConcatString());
             }
-            mContext.getContentResolver().delete(LauncherSettings.Favorites.CONTENT_URI,
-                    Utilities.createDbSelectionQuery(
-                            LauncherSettings.Favorites._ID, mEntryToRemove), null);
+            mDb.delete(Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
+                    Favorites._ID, mEntryToRemove), null);
         }
 
-        return !mUpdateOperations.isEmpty() || !mEntryToRemove.isEmpty();
+        return updateCount > 0 || !mEntryToRemove.isEmpty();
     }
 
     /**
@@ -177,11 +183,18 @@
         return applyOperations();
     }
 
+    @VisibleForTesting
+    static IntArray getWorkspaceScreenIds(SQLiteDatabase db) {
+        return LauncherDbUtils.queryIntArray(db, Favorites.TABLE_NAME, Favorites.SCREEN,
+                Favorites.CONTAINER + " = " + Favorites.CONTAINER_DESKTOP,
+                Favorites.SCREEN, Favorites.SCREEN);
+    }
+
     /**
      * @return true if any DB change was made
      */
     protected boolean migrateWorkspace() throws Exception {
-        IntArray allScreens = LauncherModel.loadWorkspaceScreensDb(mContext);
+        IntArray allScreens = getWorkspaceScreenIds(mDb);
         if (allScreens.isEmpty()) {
             throw new Exception("Unable to get workspace screens");
         }
@@ -213,9 +226,7 @@
                     int newScreenId = LauncherSettings.Settings.call(
                             mContext.getContentResolver(),
                             LauncherSettings.Settings.METHOD_NEW_SCREEN_ID)
-                            .getInt(LauncherSettings.Settings.EXTRA_VALUE);
-
-                    allScreens.add(newScreenId);
+                            .getInt(EXTRA_VALUE);
                     for (DbEntry item : placement.finalPlacedItems) {
                         if (!mCarryOver.remove(itemMap.get(item.id))) {
                             throw new Exception("Unable to find matching items");
@@ -228,19 +239,6 @@
                 }
 
             } while (!mCarryOver.isEmpty());
-
-            // Update screens
-            final Uri uri = LauncherSettings.WorkspaceScreens.CONTENT_URI;
-            mUpdateOperations.add(ContentProviderOperation.newDelete(uri).build());
-            int count = allScreens.size();
-            for (int i = 0; i < count; i++) {
-                ContentValues v = new ContentValues();
-                int screenId = allScreens.get(i);
-                v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
-                v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
-                mUpdateOperations.add(ContentProviderOperation.newInsert(uri).withValues(
-                        v).build());
-            }
         }
         return applyOperations();
     }
@@ -359,11 +357,9 @@
      * Updates an item in the DB.
      */
     protected void update(DbEntry item) {
-        mTempValues.clear();
-        item.addToContentValues(mTempValues);
-        mUpdateOperations.add(ContentProviderOperation
-                .newUpdate(LauncherSettings.Favorites.getContentUri(item.id))
-                .withValues(mTempValues).build());
+        ContentValues values = new ContentValues();
+        item.addToContentValues(values);
+        mUpdateOperations.put(item.id, values);
     }
 
     /**
@@ -609,13 +605,13 @@
     }
 
     private ArrayList<DbEntry> loadHotseatEntries() {
-        Cursor c =  mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
+        Cursor c =  queryWorkspace(
                 new String[]{
                         Favorites._ID,                  // 0
                         Favorites.ITEM_TYPE,            // 1
                         Favorites.INTENT,               // 2
                         Favorites.SCREEN},              // 3
-                Favorites.CONTAINER + " = " + Favorites.CONTAINER_HOTSEAT, null, null, null);
+                Favorites.CONTAINER + " = " + Favorites.CONTAINER_HOTSEAT);
 
         final int indexId = c.getColumnIndexOrThrow(Favorites._ID);
         final int indexItemType = c.getColumnIndexOrThrow(Favorites.ITEM_TYPE);
@@ -793,8 +789,7 @@
     }
 
     protected Cursor queryWorkspace(String[] columns, String where) {
-        return mContext.getContentResolver().query(LauncherSettings.Favorites.CONTENT_URI,
-                columns, where, null, null, null);
+        return mDb.query(Favorites.TABLE_NAME, columns, where, null, null, null, null);
     }
 
     /**
@@ -861,11 +856,11 @@
         }
 
         public void addToContentValues(ContentValues values) {
-            values.put(LauncherSettings.Favorites.SCREEN, screenId);
-            values.put(LauncherSettings.Favorites.CELLX, cellX);
-            values.put(LauncherSettings.Favorites.CELLY, cellY);
-            values.put(LauncherSettings.Favorites.SPANX, spanX);
-            values.put(LauncherSettings.Favorites.SPANY, spanY);
+            values.put(Favorites.SCREEN, screenId);
+            values.put(Favorites.CELLX, cellX);
+            values.put(Favorites.CELLY, cellY);
+            values.put(Favorites.SPANX, spanX);
+            values.put(Favorites.SPANY, spanY);
         }
     }
 
@@ -877,15 +872,6 @@
         return dup;
     }
 
-    private static Point parsePoint(String point) {
-        String[] split = point.split(",");
-        return new Point(Integer.parseInt(split[0]), Integer.parseInt(split[1]));
-    }
-
-    private static String getPointString(int x, int y) {
-        return String.format(Locale.ENGLISH, "%d,%d", x, y);
-    }
-
     public static void markForMigration(
             Context context, int gridX, int gridY, int hotseatSize) {
         Utilities.getPrefs(context).edit()
@@ -913,34 +899,43 @@
         }
 
         long migrationStartTime = System.currentTimeMillis();
-        try {
+        try (SQLiteTransaction transaction = (SQLiteTransaction) Settings.call(
+                context.getContentResolver(), Settings.METHOD_NEW_TRANSACTION)
+                .getBinder(Settings.EXTRA_VALUE)) {
+
+            int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT,
+                    idp.numHotseatIcons);
+            Point sourceSize = parsePoint(prefs.getString(
+                    KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString));
+
             boolean dbChanged = false;
 
+            GridBackupTable backupTable = new GridBackupTable(context, transaction.getDb(),
+                    srcHotseatCount, sourceSize.x, sourceSize.y);
+            if (backupTable.backupOrRestoreAsNeeded()) {
+                dbChanged = true;
+                srcHotseatCount = backupTable.getRestoreHotseatAndGridSize(sourceSize);
+            }
+
             HashSet<String> validPackages = getValidPackages(context);
             // Hotseat
-            int srcHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT,
-                    idp.numHotseatIcons);
             if (srcHotseatCount != idp.numHotseatIcons) {
                 // Migrate hotseat.
-
-                dbChanged = new GridSizeMigrationTask(context, LauncherAppState.getIDP(context),
+                dbChanged = new GridSizeMigrationTask(context, transaction.getDb(),
                         validPackages, srcHotseatCount, idp.numHotseatIcons).migrateHotseat();
             }
 
             // Grid size
             Point targetSize = new Point(idp.numColumns, idp.numRows);
-            Point sourceSize = parsePoint(prefs.getString(
-                    KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString));
-
-            if (new MultiStepMigrationTask(validPackages, context).migrate(sourceSize,
-                    targetSize)) {
+            if (new MultiStepMigrationTask(validPackages, context, transaction.getDb())
+                    .migrate(sourceSize, targetSize)) {
                 dbChanged = true;
             }
 
             if (dbChanged) {
                 // Make sure we haven't removed everything.
                 final Cursor c = context.getContentResolver().query(
-                        LauncherSettings.Favorites.CONTENT_URI, null, null, null, null);
+                        Favorites.CONTENT_URI, null, null, null, null);
                 boolean hasData = c.moveToNext();
                 c.close();
                 if (!hasData) {
@@ -948,6 +943,8 @@
                 }
             }
 
+            transaction.commit();
+            Settings.call(context.getContentResolver(), Settings.METHOD_REFRESH_BACKUP_TABLE);
             return true;
         } catch (Exception e) {
             Log.e(TAG, "Error during grid migration", e);
@@ -988,19 +985,24 @@
      */
     public static IntSparseArrayMap<Object> removeBrokenHotseatItems(Context context)
             throws Exception {
-        GridSizeMigrationTask task = new GridSizeMigrationTask(
-                context, LauncherAppState.getIDP(context), getValidPackages(context),
-                Integer.MAX_VALUE, Integer.MAX_VALUE);
+        try (SQLiteTransaction transaction = (SQLiteTransaction) Settings.call(
+                context.getContentResolver(), Settings.METHOD_NEW_TRANSACTION)
+                .getBinder(Settings.EXTRA_VALUE)) {
+            GridSizeMigrationTask task = new GridSizeMigrationTask(
+                    context, transaction.getDb(), getValidPackages(context),
+                    Integer.MAX_VALUE, Integer.MAX_VALUE);
 
-        // Load all the valid entries
-        ArrayList<DbEntry> items = task.loadHotseatEntries();
-        // Delete any entry marked for deletion by above load.
-        task.applyOperations();
-        IntSparseArrayMap<Object> positions = new IntSparseArrayMap<>();
-        for (DbEntry item : items) {
-            positions.put(item.screenId, item);
+            // Load all the valid entries
+            ArrayList<DbEntry> items = task.loadHotseatEntries();
+            // Delete any entry marked for deletion by above load.
+            task.applyOperations();
+            IntSparseArrayMap<Object> positions = new IntSparseArrayMap<>();
+            for (DbEntry item : items) {
+                positions.put(item.screenId, item);
+            }
+            transaction.commit();
+            return positions;
         }
-        return positions;
     }
 
     /**
@@ -1009,10 +1011,13 @@
     protected static class MultiStepMigrationTask {
         private final HashSet<String> mValidPackages;
         private final Context mContext;
+        private final SQLiteDatabase mDb;
 
-        public MultiStepMigrationTask(HashSet<String> validPackages, Context context) {
+        public MultiStepMigrationTask(HashSet<String> validPackages, Context context,
+                SQLiteDatabase db) {
             mValidPackages = validPackages;
             mContext = context;
+            mDb = db;
         }
 
         public boolean migrate(Point sourceSize, Point targetSize) throws Exception {
@@ -1048,7 +1053,7 @@
         }
 
         protected boolean runStepTask(Point sourceSize, Point nextSize) throws Exception {
-            return new GridSizeMigrationTask(mContext, LauncherAppState.getIDP(mContext),
+            return new GridSizeMigrationTask(mContext, mDb,
                     mValidPackages, sourceSize, nextSize).migrateWorkspace();
         }
     }
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index ea4d32b..d104a8b 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.content.Intent.ShortcutIconResource;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.database.CursorWrapper;
 import android.graphics.BitmapFactory;
@@ -41,7 +42,6 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.icons.BitmapInfo;
 import com.android.launcher3.icons.LauncherIcons;
@@ -64,7 +64,7 @@
     public final LongSparseArray<UserHandle> allUsers = new LongSparseArray<>();
 
     private final Context mContext;
-    private final UserManagerCompat mUserManager;
+    private final PackageManager mPM;
     private final IconCache mIconCache;
     private final InvariantDeviceProfile mIDP;
 
@@ -100,7 +100,7 @@
         mContext = app.getContext();
         mIconCache = app.getIconCache();
         mIDP = app.getInvariantDeviceProfile();
-        mUserManager = UserManagerCompat.getInstance(mContext);
+        mPM = mContext.getPackageManager();
 
         // Init column indices
         iconIndex = getColumnIndexOrThrow(LauncherSettings.Favorites.ICON);
@@ -165,6 +165,15 @@
      * Loads the icon from the cursor and updates the {@param info} if the icon is an app resource.
      */
     protected boolean loadIcon(ShortcutInfo info) {
+        try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
+            return loadIcon(info, li);
+        }
+    }
+
+    /**
+     * Loads the icon from the cursor and updates the {@param info} if the icon is an app resource.
+     */
+    protected boolean loadIcon(ShortcutInfo info, LauncherIcons li) {
         if (itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
             String packageName = getString(iconPackageIndex);
             String resourceName = getString(iconResourceIndex);
@@ -172,9 +181,7 @@
                 info.iconResource = new ShortcutIconResource();
                 info.iconResource.packageName = packageName;
                 info.iconResource.resourceName = resourceName;
-                LauncherIcons li = LauncherIcons.obtain(mContext);
                 BitmapInfo iconInfo = li.createIconBitmap(info.iconResource);
-                li.recycle();
                 if (iconInfo != null) {
                     info.applyFrom(iconInfo);
                     return true;
@@ -184,11 +191,11 @@
 
         // Failed to load from resource, try loading from DB.
         byte[] data = getBlob(iconIndex);
-        try (LauncherIcons li = LauncherIcons.obtain(mContext)) {
+        try {
             info.applyFrom(li.createIconBitmap(BitmapFactory.decodeByteArray(data, 0, data.length)));
             return true;
         } catch (Exception e) {
-            Log.e(TAG, "Failed to load icon for info " + info, e);
+            Log.e(TAG, "Failed to decode byte array for info " + info, e);
             return false;
         }
     }
@@ -228,7 +235,7 @@
             throw new InvalidParameterException("Invalid restoreType " + restoreFlag);
         }
 
-        info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user);
+        info.contentDescription = mPM.getUserBadgedLabel(info.title, info.user);
         info.itemType = itemType;
         info.status = restoreFlag;
         return info;
@@ -284,7 +291,7 @@
             info.title = componentName.getClassName();
         }
 
-        info.contentDescription = mUserManager.getBadgedLabelForUser(info.title, info.user);
+        info.contentDescription = mPM.getUserBadgedLabel(info.title, info.user);
         return info;
     }
 
@@ -373,7 +380,7 @@
      * otherwise marks it for deletion.
      */
     public void checkAndAddItem(ItemInfo info, BgDataModel dataModel) {
-        if (checkItemPlacement(info, dataModel.workspaceScreens)) {
+        if (checkItemPlacement(info)) {
             dataModel.addItem(mContext, info, false);
         } else {
             markDeleted("Item position overlap");
@@ -383,7 +390,7 @@
     /**
      * check & update map of what's occupied; used to discard overlapping/invalid items
      */
-    protected boolean checkItemPlacement(ItemInfo item, IntArray workspaceScreens) {
+    protected boolean checkItemPlacement(ItemInfo item) {
         int containerIndex = item.screenId;
         if (item.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
             final GridOccupancy hotseatOccupancy =
@@ -413,12 +420,7 @@
                 occupied.put(LauncherSettings.Favorites.CONTAINER_HOTSEAT, occupancy);
                 return true;
             }
-        } else if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-            if (!workspaceScreens.contains(item.screenId)) {
-                // The item has an invalid screen id.
-                return false;
-            }
-        } else {
+        } else if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP) {
             // Skip further checking if it is not the hotseat or workspace container
             return true;
         }
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 8b3e2c9..cfabc10 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -20,8 +20,6 @@
 import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE;
 import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED;
 import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.MAX_NUM_ITEMS_IN_PREVIEW;
-import static com.android.launcher3.icons.CachingLogic.COMPONENT_WITH_LABEL;
-import static com.android.launcher3.icons.CachingLogic.LAUNCHER_ACTIVITY_INFO;
 import static com.android.launcher3.model.LoaderResults.filterCurrentWorkspaceItems;
 
 import android.appwidget.AppWidgetProviderInfo;
@@ -33,7 +31,6 @@
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionInfo;
-import android.graphics.Bitmap;
 import android.os.Handler;
 import android.os.Process;
 import android.os.UserHandle;
@@ -45,17 +42,17 @@
 import com.android.launcher3.AllAppsList;
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.FolderInfo;
-import com.android.launcher3.icons.ComponentWithLabel;
-import com.android.launcher3.icons.IconCacheUpdateHandler;
-import com.android.launcher3.icons.IconCache;
 import com.android.launcher3.InstallShortcutReceiver;
 import com.android.launcher3.ItemInfo;
+import com.android.launcher3.ItemInfoWithIcon;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.Workspace;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.PackageInstallerCompat;
@@ -63,14 +60,18 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderIconPreviewVerifier;
+import com.android.launcher3.icons.ComponentWithLabel;
+import com.android.launcher3.icons.ComponentWithLabel.ComponentCachingLogic;
+import com.android.launcher3.icons.IconCache;
+import com.android.launcher3.icons.LauncherActivtiyCachingLogic;
 import com.android.launcher3.icons.LauncherIcons;
+import com.android.launcher3.icons.cache.IconCacheUpdateHandler;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.provider.ImportDataTask;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.util.ComponentKey;
-import com.android.launcher3.util.IntArray;
 import com.android.launcher3.util.LooperIdleLock;
 import com.android.launcher3.util.MultiHashMap;
 import com.android.launcher3.util.PackageManagerHelper;
@@ -156,9 +157,9 @@
             allItems.addAll(mBgDataModel.workspaceItems);
             allItems.addAll(mBgDataModel.appWidgets);
         }
-        int firstScreen = mBgDataModel.workspaceScreens.isEmpty()
-                ? -1 // In this case, we can still look at the items in the hotseat.
-                : mBgDataModel.workspaceScreens.get(0);
+        // Screen set is never empty
+        final int firstScreen = mBgDataModel.collectWorkspaceScreens().get(0);
+
         filterCurrentWorkspaceItems(firstScreen, allItems, firstScreenItems,
                 new ArrayList<>() /* otherScreenItems are ignored */);
         mFirstScreenBroadcast.sendBroadcasts(mApp.getContext(), firstScreenItems);
@@ -202,7 +203,8 @@
             TraceHelper.partitionSection(TAG, "step 2.3: Update icon cache");
             IconCacheUpdateHandler updateHandler = mIconCache.getUpdateHandler();
             setIgnorePackages(updateHandler);
-            updateHandler.updateIcons(allActivityList, LAUNCHER_ACTIVITY_INFO,
+            updateHandler.updateIcons(allActivityList,
+                    new LauncherActivtiyCachingLogic(mApp.getIconCache()),
                     mApp.getModel()::onPackageIconsUpdated);
 
             // Take a break
@@ -233,7 +235,7 @@
 
             verifyNotStopped();
             TraceHelper.partitionSection(TAG, "step 4.3: Update icon cache");
-            updateHandler.updateIcons(allWidgetsList, COMPONENT_WITH_LABEL,
+            updateHandler.updateIcons(allWidgetsList, new ComponentCachingLogic(mApp.getContext()),
                     mApp.getModel()::onWidgetLabelsUpdated);
 
             verifyNotStopped();
@@ -291,7 +293,6 @@
             final HashMap<String, SessionInfo> installingPkgs =
                     mPackageInstaller.updateAndGetActiveSessionCache();
             mFirstScreenBroadcast = new FirstScreenBroadcast(installingPkgs);
-            mBgDataModel.workspaceScreens.addAll(LauncherModel.loadWorkspaceScreensDb(context));
 
             Map<ShortcutKey, ShortcutInfoCompat> shortcutKeyToPinnedShortcuts = new HashMap<>();
             final LoaderCursor c = new LoaderCursor(contentResolver.query(
@@ -492,12 +493,12 @@
                                     }
                                     info = new ShortcutInfo(pinnedShortcut, context);
                                     final ShortcutInfo finalInfo = info;
-                                    // If the pinned deep shortcut is no longer published,
-                                    // use the last saved icon instead of the default.
-                                    Provider<Bitmap> fallbackIconProvider = () ->
-                                            c.loadIcon(finalInfo) ? finalInfo.iconBitmap : null;
 
                                     LauncherIcons li = LauncherIcons.obtain(context);
+                                    // If the pinned deep shortcut is no longer published,
+                                    // use the last saved icon instead of the default.
+                                    Provider<ItemInfoWithIcon> fallbackIconProvider = () ->
+                                            c.loadIcon(finalInfo, li) ? finalInfo : null;
                                     info.applyFrom(li.createShortcutIcon(pinnedShortcut,
                                             true /* badged */, fallbackIconProvider));
                                     li.recycle();
@@ -670,6 +671,11 @@
                                 appWidgetInfo.spanY = c.getInt(spanYIndex);
                                 appWidgetInfo.user = c.user;
 
+                                if (appWidgetInfo.spanX <= 0 || appWidgetInfo.spanY <= 0) {
+                                    c.markDeleted("Widget has invalid size: "
+                                            + appWidgetInfo.spanX + "x" + appWidgetInfo.spanY);
+                                    continue;
+                                }
                                 if (!c.isOnWorkspaceOrHotseat()) {
                                     c.markDeleted("Widget found where container != " +
                                             "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!");
@@ -777,22 +783,6 @@
                         null,
                         new Handler(LauncherModel.getWorkerLooper()));
             }
-
-            // Remove any empty screens
-            IntArray unusedScreens = mBgDataModel.workspaceScreens.clone();
-            for (ItemInfo item: mBgDataModel.itemsIdMap) {
-                int screenId = item.screenId;
-                if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                        unusedScreens.contains(screenId)) {
-                    unusedScreens.removeValue(screenId);
-                }
-            }
-
-            // If there are any empty screens remove them, and update.
-            if (unusedScreens.size() != 0) {
-                mBgDataModel.workspaceScreens.removeAllValues(unusedScreens);
-                LauncherModel.updateWorkspaceScreenOrder(context, mBgDataModel.workspaceScreens);
-            }
         }
     }
 
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index f7961d5d..d8d9930 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -333,7 +333,7 @@
      * {@link #commitDelete()} is called (or abandoned if {@link #abortDelete()} is called).
      * Otherwise, we run the Runnable immediately.
      */
-    public void enqueueDeleteRunnable(Runnable r) {
+    private void enqueueDeleteRunnable(Runnable r) {
         if (mPreparingToUndo) {
             mDeleteRunnables.add(r);
         } else {
@@ -349,12 +349,12 @@
         mDeleteRunnables.clear();
     }
 
-    public void abortDelete() {
+    public void abortDelete(int pageToBindFirst) {
         mPreparingToUndo = false;
         mDeleteRunnables.clear();
         // We do a full reload here instead of just a rebind because Folders change their internal
         // state when dragging an item out, which clobbers the rebind unless we load from the DB.
-        mModel.forceReload();
+        mModel.forceReload(pageToBindFirst);
     }
 
     private class UpdateItemRunnable extends UpdateItemBaseRunnable {
diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java
index e99fed9..4e699f7 100644
--- a/src/com/android/launcher3/model/ShortcutsChangedTask.java
+++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java
@@ -97,7 +97,7 @@
                     // keep the current icon instead of reverting to the default icon.
                     LauncherIcons li = LauncherIcons.obtain(context);
                     shortcutInfo.applyFrom(li.createShortcutIcon(fullDetails, true,
-                            Provider.of(shortcutInfo.iconBitmap)));
+                            Provider.of(shortcutInfo)));
                     li.recycle();
                     updatedShortcutInfos.add(shortcutInfo);
                 }
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index 8e7557a..59f4284 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -95,7 +95,7 @@
                     // If the shortcut is pinned but no longer has an icon in the system,
                     // keep the current icon instead of reverting to the default icon.
                     LauncherIcons li = LauncherIcons.obtain(context);
-                    si.applyFrom(li.createShortcutIcon(shortcut, true, Provider.of(si.iconBitmap)));
+                    si.applyFrom(li.createShortcutIcon(shortcut, true, Provider.of(si)));
                     li.recycle();
                 } else {
                     si.runtimeStatusFlags |= FLAG_DISABLED_LOCKED_USER;
diff --git a/src/com/android/launcher3/notification/NotificationInfo.java b/src/com/android/launcher3/notification/NotificationInfo.java
index 6918935..e5525b2 100644
--- a/src/com/android/launcher3/notification/NotificationInfo.java
+++ b/src/com/android/launcher3/notification/NotificationInfo.java
@@ -30,13 +30,14 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.dot.DotInfo;
 import com.android.launcher3.graphics.IconPalette;
 import com.android.launcher3.util.PackageUserKey;
 
 /**
  * An object that contains relevant information from a {@link StatusBarNotification}. This should
  * only be created when we need to show the notification contents on the UI; until then, a
- * {@link com.android.launcher3.badge.BadgeInfo} with only the notification key should
+ * {@link DotInfo} with only the notification key should
  * be passed around, and then this can be constructed using the StatusBarNotification from
  * {@link NotificationListener#getNotificationsForKeys(java.util.List)}.
  */
@@ -50,7 +51,6 @@
     public final boolean autoCancel;
     public final boolean dismissable;
 
-    private int mBadgeIcon;
     private Drawable mIconDrawable;
     private int mIconColor;
     private boolean mIsIconLarge;
@@ -65,10 +65,10 @@
         title = notification.extras.getCharSequence(Notification.EXTRA_TITLE);
         text = notification.extras.getCharSequence(Notification.EXTRA_TEXT);
 
-        mBadgeIcon = notification.getBadgeIconType();
+        int iconType = notification.getBadgeIconType();
         // Load the icon. Since it is backed by ashmem, we won't copy the entire bitmap
         // into our process as long as we don't touch it and it exists in systemui.
-        Icon icon = mBadgeIcon == Notification.BADGE_ICON_SMALL ? null : notification.getLargeIcon();
+        Icon icon = iconType == Notification.BADGE_ICON_SMALL ? null : notification.getLargeIcon();
         if (icon == null) {
             // Use the small icon.
             icon = notification.getSmallIcon();
@@ -84,7 +84,6 @@
             mIconDrawable = new BitmapDrawable(context.getResources(), LauncherAppState
                     .getInstance(context).getIconCache()
                     .getDefaultIcon(statusBarNotification.getUser()).icon);
-            mBadgeIcon = Notification.BADGE_ICON_NONE;
         }
         intent = notification.contentIntent;
         autoCancel = (notification.flags & Notification.FLAG_AUTO_CANCEL) != 0;
@@ -125,15 +124,4 @@
         icon.setTint(mIconColor);
         return icon;
     }
-
-    public boolean isIconLarge() {
-        return mIsIconLarge;
-    }
-
-    public boolean shouldShowIconInBadge() {
-        // If the icon we're using for this notification matches what the Notification
-        // specified should show in the badge, then return true.
-        return mIsIconLarge && mBadgeIcon == Notification.BADGE_ICON_LARGE
-                || !mIsIconLarge && mBadgeIcon == Notification.BADGE_ICON_SMALL;
-    }
 }
diff --git a/src/com/android/launcher3/notification/NotificationKeyData.java b/src/com/android/launcher3/notification/NotificationKeyData.java
index 508cf87..5050457 100644
--- a/src/com/android/launcher3/notification/NotificationKeyData.java
+++ b/src/com/android/launcher3/notification/NotificationKeyData.java
@@ -26,7 +26,7 @@
 
 /**
  * The key data associated with the notification, used to determine what to include
- * in badges and dummy popup views before they are populated.
+ * in dots and dummy popup views before they are populated.
  *
  * @see NotificationInfo for the full data used when populating the dummy views.
  */
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index f27b728..e57a051 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -77,7 +77,7 @@
     /** The last notification key that was dismissed from launcher UI */
     private String mLastKeyDismissedByLauncher;
 
-    private SecureSettingsObserver mNotificationBadgingObserver;
+    private SecureSettingsObserver mNotificationDotsObserver;
 
     private final Handler.Callback mWorkerCallback = new Handler.Callback() {
         @Override
@@ -169,7 +169,7 @@
         if (notificationListener != null) {
             notificationListener.onNotificationFullRefresh();
         } else if (!sIsCreated && sNotificationsChangedListener != null) {
-            // User turned off badging globally, so we unbound this service;
+            // User turned off dots globally, so we unbound this service;
             // tell the listener that there are no notifications to remove dots.
             sNotificationsChangedListener.onNotificationFullRefresh(
                     Collections.<StatusBarNotification>emptyList());
@@ -194,16 +194,16 @@
         super.onListenerConnected();
         sIsConnected = true;
 
-        mNotificationBadgingObserver =
-                newNotificationSettingsObserver(this, this::onNotificationBadgingChanged);
-        mNotificationBadgingObserver.register();
-        mNotificationBadgingObserver.dispatchOnChange();
+        mNotificationDotsObserver =
+                newNotificationSettingsObserver(this, this::onNotificationSettingsChanged);
+        mNotificationDotsObserver.register();
+        mNotificationDotsObserver.dispatchOnChange();
 
         onNotificationFullRefresh();
     }
 
-    private void onNotificationBadgingChanged(boolean isNotificationBadgingEnabled) {
-        if (!isNotificationBadgingEnabled && sIsConnected) {
+    private void onNotificationSettingsChanged(boolean areNotificationDotsEnabled) {
+        if (!areNotificationDotsEnabled && sIsConnected) {
             requestUnbind();
         }
     }
@@ -216,7 +216,7 @@
     public void onListenerDisconnected() {
         super.onListenerDisconnected();
         sIsConnected = false;
-        mNotificationBadgingObserver.unregister();
+        mNotificationDotsObserver.unregister();
     }
 
     @Override
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 0bb5e2a..ccc15f1 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -126,6 +126,12 @@
         return (T) view;
     }
 
+    public <T extends View> T inflateAndAdd(int resId, ViewGroup container, int index) {
+        View view = mInflater.inflate(resId, container, false);
+        container.addView(view, index);
+        return (T) view;
+    }
+
     /**
      * Called when all view inflation and reordering in complete.
      */
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 12319f7..0c098da 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -53,7 +53,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
-import com.android.launcher3.badge.BadgeInfo;
+import com.android.launcher3.dot.DotInfo;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.dragndrop.DragView;
@@ -279,7 +279,7 @@
         }
 
         mLauncher.getDragController().addDragListener(this);
-        mOriginalIcon.forceHideBadge(true);
+        mOriginalIcon.forceHideDot(true);
 
         // All views are added. Animate layout from now on.
         setLayoutTransition(new LayoutTransition());
@@ -391,7 +391,8 @@
     }
 
     private void initializeSystemShortcut(int resId, ViewGroup container, SystemShortcut info) {
-        View view = inflateAndAdd(resId, container);
+        View view = inflateAndAdd(
+                resId, container, getInsertIndexForSystemShortcut(container, info));
         if (view instanceof DeepShortcutView) {
             // Expanded system shortcut, with both icon and text shown on white background.
             final DeepShortcutView shortcutView = (DeepShortcutView) view;
@@ -406,6 +407,17 @@
     }
 
     /**
+     * Returns an index for inserting a shortcut into a container.
+     */
+    private int getInsertIndexForSystemShortcut(ViewGroup container, SystemShortcut shortcut) {
+        final View separator = container.findViewById(R.id.separator);
+
+        return separator != null && shortcut.isLeftGroup() ?
+                container.indexOfChild(separator) :
+                container.getChildCount();
+    }
+
+    /**
      * Determines when the deferred drag should be started.
      *
      * Current behavior:
@@ -450,32 +462,32 @@
     }
 
     /**
-     * Updates the notification header if the original icon's badge updated.
+     * Updates the notification header if the original icon's dot updated.
      */
-    public void updateNotificationHeader(Set<PackageUserKey> updatedBadges) {
+    public void updateNotificationHeader(Set<PackageUserKey> updatedDots) {
         ItemInfo itemInfo = (ItemInfo) mOriginalIcon.getTag();
         PackageUserKey packageUser = PackageUserKey.fromItemInfo(itemInfo);
-        if (updatedBadges.contains(packageUser)) {
+        if (updatedDots.contains(packageUser)) {
             updateNotificationHeader();
         }
     }
 
     private void updateNotificationHeader() {
         ItemInfoWithIcon itemInfo = (ItemInfoWithIcon) mOriginalIcon.getTag();
-        BadgeInfo badgeInfo = mLauncher.getBadgeInfoForItem(itemInfo);
-        if (mNotificationItemView != null && badgeInfo != null) {
+        DotInfo dotInfo = mLauncher.getDotInfoForItem(itemInfo);
+        if (mNotificationItemView != null && dotInfo != null) {
             mNotificationItemView.updateHeader(
-                    badgeInfo.getNotificationCount(), itemInfo.iconColor);
+                    dotInfo.getNotificationCount(), itemInfo.iconColor);
         }
     }
 
-    public void trimNotifications(Map<PackageUserKey, BadgeInfo> updatedBadges) {
+    public void trimNotifications(Map<PackageUserKey, DotInfo> updatedDots) {
         if (mNotificationItemView == null) {
             return;
         }
         ItemInfo originalInfo = (ItemInfo) mOriginalIcon.getTag();
-        BadgeInfo badgeInfo = updatedBadges.get(PackageUserKey.fromItemInfo(originalInfo));
-        if (badgeInfo == null || badgeInfo.getNotificationKeys().size() == 0) {
+        DotInfo dotInfo = updatedDots.get(PackageUserKey.fromItemInfo(originalInfo));
+        if (dotInfo == null || dotInfo.getNotificationKeys().size() == 0) {
             // No more notifications, remove the notification views and expand all shortcuts.
             mNotificationItemView.removeAllViews();
             mNotificationItemView = null;
@@ -483,7 +495,7 @@
             updateDividers();
         } else {
             mNotificationItemView.trimNotifications(
-                    NotificationKeyData.extractKeysOnly(badgeInfo.getNotificationKeys()));
+                    NotificationKeyData.extractKeysOnly(dotInfo.getNotificationKeys()));
         }
     }
 
@@ -528,14 +540,14 @@
     protected void onCreateCloseAnimation(AnimatorSet anim) {
         // Animate original icon's text back in.
         anim.play(mOriginalIcon.createTextAlphaAnimator(true /* fadeIn */));
-        mOriginalIcon.forceHideBadge(false);
+        mOriginalIcon.forceHideDot(false);
     }
 
     @Override
     protected void closeComplete() {
         super.closeComplete();
         mOriginalIcon.setTextVisibility(mOriginalIcon.shouldTextBeVisible());
-        mOriginalIcon.forceHideBadge(false);
+        mOriginalIcon.forceHideDot(false);
     }
 
     @Override
diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java
index 3206503..984a03d 100644
--- a/src/com/android/launcher3/popup/PopupDataProvider.java
+++ b/src/com/android/launcher3/popup/PopupDataProvider.java
@@ -23,7 +23,7 @@
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.badge.BadgeInfo;
+import com.android.launcher3.dot.DotInfo;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.notification.NotificationKeyData;
 import com.android.launcher3.notification.NotificationListener;
@@ -53,8 +53,8 @@
 
     /** Maps launcher activity components to a count of how many shortcuts they have. */
     private HashMap<ComponentKey, Integer> mDeepShortcutMap = new HashMap<>();
-    /** Maps packages to their BadgeInfo's . */
-    private Map<PackageUserKey, BadgeInfo> mPackageUserToBadgeInfos = new HashMap<>();
+    /** Maps packages to their DotInfo's . */
+    private Map<PackageUserKey, DotInfo> mPackageUserToDotInfos = new HashMap<>();
     /** Maps packages to their Widgets */
     private ArrayList<WidgetListRowEntry> mAllWidgets = new ArrayList<>();
 
@@ -65,83 +65,83 @@
     @Override
     public void onNotificationPosted(PackageUserKey postedPackageUserKey,
             NotificationKeyData notificationKey, boolean shouldBeFilteredOut) {
-        BadgeInfo badgeInfo = mPackageUserToBadgeInfos.get(postedPackageUserKey);
-        boolean badgeShouldBeRefreshed;
-        if (badgeInfo == null) {
+        DotInfo dotInfo = mPackageUserToDotInfos.get(postedPackageUserKey);
+        boolean dotShouldBeRefreshed;
+        if (dotInfo == null) {
             if (!shouldBeFilteredOut) {
-                BadgeInfo newBadgeInfo = new BadgeInfo(postedPackageUserKey);
-                newBadgeInfo.addOrUpdateNotificationKey(notificationKey);
-                mPackageUserToBadgeInfos.put(postedPackageUserKey, newBadgeInfo);
-                badgeShouldBeRefreshed = true;
+                DotInfo newDotInfo = new DotInfo(postedPackageUserKey);
+                newDotInfo.addOrUpdateNotificationKey(notificationKey);
+                mPackageUserToDotInfos.put(postedPackageUserKey, newDotInfo);
+                dotShouldBeRefreshed = true;
             } else {
-                badgeShouldBeRefreshed = false;
+                dotShouldBeRefreshed = false;
             }
         } else {
-            badgeShouldBeRefreshed = shouldBeFilteredOut
-                    ? badgeInfo.removeNotificationKey(notificationKey)
-                    : badgeInfo.addOrUpdateNotificationKey(notificationKey);
-            if (badgeInfo.getNotificationKeys().size() == 0) {
-                mPackageUserToBadgeInfos.remove(postedPackageUserKey);
+            dotShouldBeRefreshed = shouldBeFilteredOut
+                    ? dotInfo.removeNotificationKey(notificationKey)
+                    : dotInfo.addOrUpdateNotificationKey(notificationKey);
+            if (dotInfo.getNotificationKeys().size() == 0) {
+                mPackageUserToDotInfos.remove(postedPackageUserKey);
             }
         }
-        if (badgeShouldBeRefreshed) {
-            mLauncher.updateIconBadges(Utilities.singletonHashSet(postedPackageUserKey));
+        if (dotShouldBeRefreshed) {
+            mLauncher.updateNotificationDots(Utilities.singletonHashSet(postedPackageUserKey));
         }
     }
 
     @Override
     public void onNotificationRemoved(PackageUserKey removedPackageUserKey,
             NotificationKeyData notificationKey) {
-        BadgeInfo oldBadgeInfo = mPackageUserToBadgeInfos.get(removedPackageUserKey);
-        if (oldBadgeInfo != null && oldBadgeInfo.removeNotificationKey(notificationKey)) {
-            if (oldBadgeInfo.getNotificationKeys().size() == 0) {
-                mPackageUserToBadgeInfos.remove(removedPackageUserKey);
+        DotInfo oldDotInfo = mPackageUserToDotInfos.get(removedPackageUserKey);
+        if (oldDotInfo != null && oldDotInfo.removeNotificationKey(notificationKey)) {
+            if (oldDotInfo.getNotificationKeys().size() == 0) {
+                mPackageUserToDotInfos.remove(removedPackageUserKey);
             }
-            mLauncher.updateIconBadges(Utilities.singletonHashSet(removedPackageUserKey));
-            trimNotifications(mPackageUserToBadgeInfos);
+            mLauncher.updateNotificationDots(Utilities.singletonHashSet(removedPackageUserKey));
+            trimNotifications(mPackageUserToDotInfos);
         }
     }
 
     @Override
     public void onNotificationFullRefresh(List<StatusBarNotification> activeNotifications) {
         if (activeNotifications == null) return;
-        // This will contain the PackageUserKeys which have updated badges.
-        HashMap<PackageUserKey, BadgeInfo> updatedBadges = new HashMap<>(mPackageUserToBadgeInfos);
-        mPackageUserToBadgeInfos.clear();
+        // This will contain the PackageUserKeys which have updated dots.
+        HashMap<PackageUserKey, DotInfo> updatedDots = new HashMap<>(mPackageUserToDotInfos);
+        mPackageUserToDotInfos.clear();
         for (StatusBarNotification notification : activeNotifications) {
             PackageUserKey packageUserKey = PackageUserKey.fromNotification(notification);
-            BadgeInfo badgeInfo = mPackageUserToBadgeInfos.get(packageUserKey);
-            if (badgeInfo == null) {
-                badgeInfo = new BadgeInfo(packageUserKey);
-                mPackageUserToBadgeInfos.put(packageUserKey, badgeInfo);
+            DotInfo dotInfo = mPackageUserToDotInfos.get(packageUserKey);
+            if (dotInfo == null) {
+                dotInfo = new DotInfo(packageUserKey);
+                mPackageUserToDotInfos.put(packageUserKey, dotInfo);
             }
-            badgeInfo.addOrUpdateNotificationKey(NotificationKeyData
-                    .fromNotification(notification));
+            dotInfo.addOrUpdateNotificationKey(NotificationKeyData.fromNotification(notification));
         }
 
-        // Add and remove from updatedBadges so it contains the PackageUserKeys of updated badges.
-        for (PackageUserKey packageUserKey : mPackageUserToBadgeInfos.keySet()) {
-            BadgeInfo prevBadge = updatedBadges.get(packageUserKey);
-            BadgeInfo newBadge = mPackageUserToBadgeInfos.get(packageUserKey);
-            if (prevBadge == null) {
-                updatedBadges.put(packageUserKey, newBadge);
+        // Add and remove from updatedDots so it contains the PackageUserKeys of updated dots.
+        for (PackageUserKey packageUserKey : mPackageUserToDotInfos.keySet()) {
+            DotInfo prevDot = updatedDots.get(packageUserKey);
+            DotInfo newDot = mPackageUserToDotInfos.get(packageUserKey);
+            if (prevDot == null) {
+                updatedDots.put(packageUserKey, newDot);
             } else {
-                if (!prevBadge.shouldBeInvalidated(newBadge)) {
-                    updatedBadges.remove(packageUserKey);
-                }
+                // No need to update the dot if it already existed (no visual change).
+                // Note that if the dot was removed entirely, we wouldn't reach this point because
+                // this loop only includes active notifications added above.
+                updatedDots.remove(packageUserKey);
             }
         }
 
-        if (!updatedBadges.isEmpty()) {
-            mLauncher.updateIconBadges(updatedBadges.keySet());
+        if (!updatedDots.isEmpty()) {
+            mLauncher.updateNotificationDots(updatedDots.keySet());
         }
-        trimNotifications(updatedBadges);
+        trimNotifications(updatedDots);
     }
 
-    private void trimNotifications(Map<PackageUserKey, BadgeInfo> updatedBadges) {
+    private void trimNotifications(Map<PackageUserKey, DotInfo> updatedDots) {
         PopupContainerWithArrow openContainer = PopupContainerWithArrow.getOpen(mLauncher);
         if (openContainer != null) {
-            openContainer.trimNotifications(updatedBadges);
+            openContainer.trimNotifications(updatedDots);
         }
     }
 
@@ -163,17 +163,17 @@
         return count == null ? 0 : count;
     }
 
-    public BadgeInfo getBadgeInfoForItem(ItemInfo info) {
+    public DotInfo getDotInfoForItem(ItemInfo info) {
         if (!DeepShortcutManager.supportsShortcuts(info)) {
             return null;
         }
 
-        return mPackageUserToBadgeInfos.get(PackageUserKey.fromItemInfo(info));
+        return mPackageUserToDotInfos.get(PackageUserKey.fromItemInfo(info));
     }
 
     public @NonNull List<NotificationKeyData> getNotificationKeysForItem(ItemInfo info) {
-        BadgeInfo badgeInfo = getBadgeInfoForItem(info);
-        return badgeInfo == null ? Collections.EMPTY_LIST : badgeInfo.getNotificationKeys();
+        DotInfo dotInfo = getDotInfoForItem(info);
+        return dotInfo == null ? Collections.EMPTY_LIST : dotInfo.getNotificationKeys();
     }
 
     /** This makes a potentially expensive binder call and should be run on a background thread. */
diff --git a/src/com/android/launcher3/popup/RemoteActionShortcut.java b/src/com/android/launcher3/popup/RemoteActionShortcut.java
index c76fb96..3e12429 100644
--- a/src/com/android/launcher3/popup/RemoteActionShortcut.java
+++ b/src/com/android/launcher3/popup/RemoteActionShortcut.java
@@ -76,4 +76,9 @@
                     LauncherLogProto.ControlType.REMOTE_ACTION_SHORTCUT, view);
         };
     }
+
+    @Override
+    public boolean isLeftGroup() {
+        return true;
+    }
 }
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index f9a2007..fdc1b39 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -71,6 +71,13 @@
         mAccessibilityActionId = other.mAccessibilityActionId;
     }
 
+    /**
+     * Should be in the left group of icons in app's context menu header.
+     */
+    public boolean isLeftGroup() {
+        return false;
+    }
+
     public void setIconAndLabelFor(View iconView, TextView labelView) {
         if (mIcon != null) {
             mIcon.loadDrawableAsync(iconView.getContext(),
diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java
index e1b2698..86fcc06 100644
--- a/src/com/android/launcher3/provider/ImportDataTask.java
+++ b/src/com/android/launcher3/provider/ImportDataTask.java
@@ -33,7 +33,6 @@
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.SparseBooleanArray;
-import android.util.SparseIntArray;
 
 import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback;
 import com.android.launcher3.DefaultLayoutParser;
@@ -43,8 +42,6 @@
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.LauncherSettings.Settings;
-import com.android.launcher3.LauncherSettings.WorkspaceScreens;
-import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.compat.UserManagerCompat;
@@ -73,7 +70,6 @@
 
     private final Context mContext;
 
-    private final Uri mOtherScreensUri;
     private final Uri mOtherFavoritesUri;
 
     private int mHotseatSize;
@@ -82,41 +78,14 @@
 
     private ImportDataTask(Context context, String sourceAuthority) {
         mContext = context;
-        mOtherScreensUri = Uri.parse("content://" +
-                sourceAuthority + "/" + WorkspaceScreens.TABLE_NAME);
         mOtherFavoritesUri = Uri.parse("content://" + sourceAuthority + "/" + Favorites.TABLE_NAME);
     }
 
     public boolean importWorkspace() throws Exception {
-        IntArray allScreens = LauncherDbUtils.getScreenIdsFromCursor(
-                mContext.getContentResolver().query(mOtherScreensUri, null, null, null,
-                        LauncherSettings.WorkspaceScreens.SCREEN_RANK));
         FileLog.d(TAG, "Importing DB from " + mOtherFavoritesUri);
 
-        // During import we reset the screen IDs to 0-indexed values.
-        if (allScreens.isEmpty()) {
-            // No thing to migrate
-            FileLog.e(TAG, "No data found to import");
-            return false;
-        }
-
         mHotseatSize = mMaxGridSizeX = mMaxGridSizeY = 0;
-
-        // Build screen update
-        ArrayList<ContentProviderOperation> screenOps = new ArrayList<>();
-        int count = allScreens.size();
-        SparseIntArray screenIdMap = new SparseIntArray(count);
-        for (int i = 0; i < count; i++) {
-            ContentValues v = new ContentValues();
-            v.put(LauncherSettings.WorkspaceScreens._ID, i);
-            v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
-            screenIdMap.put(allScreens.get(i), i);
-            screenOps.add(ContentProviderOperation.newInsert(
-                    LauncherSettings.WorkspaceScreens.CONTENT_URI).withValues(v).build());
-        }
-        mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY, screenOps);
-        importWorkspaceItems(allScreens.get(0), screenIdMap);
-
+        importWorkspaceItems();
         GridSizeMigrationTask.markForMigration(mContext, mMaxGridSizeX, mMaxGridSizeY, mHotseatSize);
 
         // Create empty DB flag.
@@ -130,17 +99,17 @@
      * 2) For home screen entries, maps the screen id based on {@param screenIdMap}
      * 3) In the end fills any holes in hotseat with items from default hotseat layout.
      */
-    private void importWorkspaceItems(
-            int firstScreenId, SparseIntArray screenIdMap) throws Exception {
+    private void importWorkspaceItems() throws Exception {
         String profileId = Long.toString(UserManagerCompat.getInstance(mContext)
                 .getSerialNumberForUser(Process.myUserHandle()));
 
         boolean createEmptyRowOnFirstScreen;
         if (FeatureFlags.QSB_ON_FIRST_SCREEN.get()) {
             try (Cursor c = mContext.getContentResolver().query(mOtherFavoritesUri, null,
-                    // get items on the first row of the first screen
-                    "profileId = ? AND container = -100 AND screen = ? AND cellY = 0",
-                    new String[]{profileId, Integer.toString(firstScreenId)},
+                    // get items on the first row of the first screen (min screen id)
+                    "profileId = ? AND container = -100 AND cellY = 0 AND screen = " +
+                    "(SELECT MIN(screen) FROM favorites WHERE container = -100)",
+                    new String[]{profileId},
                     null)) {
                 // First row of first screen is not empty
                 createEmptyRowOnFirstScreen = c.moveToNext();
@@ -164,7 +133,7 @@
                         Favorites.PROFILE_ID + " = ?", new String[]{profileId},
                         // Get the items sorted by container, so that the folders are loaded
                         // before the corresponding items.
-                        Favorites.CONTAINER)) {
+                        Favorites.CONTAINER + " , " + Favorites.SCREEN)) {
 
             // various columns we expect to exist.
             final int idIndex = c.getColumnIndexOrThrow(Favorites._ID);
@@ -186,6 +155,7 @@
             SparseBooleanArray mValidFolders = new SparseBooleanArray();
             ContentValues values = new ContentValues();
 
+            Integer firstScreenId = null;
             while (c.moveToNext()) {
                 values.clear();
                 int id = c.getInt(idIndex);
@@ -202,16 +172,21 @@
 
                 switch (container) {
                     case Favorites.CONTAINER_DESKTOP: {
-                        Integer newScreenId = screenIdMap.get(screen);
-                        if (newScreenId == null) {
-                            FileLog.d(TAG, String.format("Skipping item %d, type %d not on a valid screen %d", id, type, screen));
+                        if (screen < Workspace.FIRST_SCREEN_ID) {
+                            FileLog.d(TAG, String.format(
+                                    "Skipping item %d, type %d not on a valid screen %d",
+                                    id, type, screen));
                             continue;
                         }
+                        if (firstScreenId == null) {
+                            firstScreenId = screen;
+                        }
                         // Reset the screen to 0-index value
-                        screen = newScreenId;
-                        if (createEmptyRowOnFirstScreen && screen == Workspace.FIRST_SCREEN_ID) {
+                        if (createEmptyRowOnFirstScreen && firstScreenId.equals(screen)) {
                             // Shift items by 1.
                             cellY++;
+                            // Change the screen id to first screen
+                            screen = Workspace.FIRST_SCREEN_ID;
                         }
 
                         mMaxGridSizeX = Math.max(mMaxGridSizeX, cellX + spanX);
@@ -219,7 +194,7 @@
                         break;
                     }
                     case Favorites.CONTAINER_HOTSEAT: {
-                        mHotseatSize = Math.max(mHotseatSize, (int) screen + 1);
+                        mHotseatSize = Math.max(mHotseatSize, screen + 1);
                         break;
                     }
                     default:
@@ -378,18 +353,13 @@
         return false;
     }
 
-    private static int getMyHotseatLayoutId(Context context) {
-        return LauncherAppState.getIDP(context).numHotseatIcons <= 5
-                ? R.xml.dw_phone_hotseat
-                : R.xml.dw_tablet_hotseat;
-    }
-
     /**
      * Extension of {@link DefaultLayoutParser} which only allows icons and shortcuts.
      */
     private static class HotseatLayoutParser extends DefaultLayoutParser {
         public HotseatLayoutParser(Context context, LayoutParserCallback callback) {
-            super(context, null, callback, context.getResources(), getMyHotseatLayoutId(context));
+            super(context, null, callback, context.getResources(),
+                    LauncherAppState.getIDP(context).defaultLayoutId);
         }
 
         @Override
@@ -434,6 +404,12 @@
                 // No need to add more items.
                 return 0;
             }
+            if (!Integer.valueOf(Favorites.CONTAINER_HOTSEAT)
+                    .equals(values.getAsInteger(Favorites.CONTAINER))) {
+                // Ignore items which are not for hotseat.
+                return 0;
+            }
+
             Intent intent;
             try {
                 intent = Intent.parseUri(values.getAsString(Favorites.INTENT), 0);
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
index ab0703f..2c843f9 100644
--- a/src/com/android/launcher3/provider/LauncherDbUtils.java
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -21,15 +21,14 @@
 import android.database.Cursor;
 import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteDatabase;
+import android.os.Binder;
 import android.util.Log;
 
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.LauncherSettings.WorkspaceScreens;
 import com.android.launcher3.util.IntArray;
 
-import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Locale;
 
 /**
  * A set of utility methods for Launcher DB used for DB updates and migration.
@@ -47,26 +46,25 @@
      */
     public static boolean prepareScreenZeroToHostQsb(Context context, SQLiteDatabase db) {
         try (SQLiteTransaction t = new SQLiteTransaction(db)) {
-            // Get the existing screens
-            IntArray screenIds = getScreenIdsFromCursor(db.query(WorkspaceScreens.TABLE_NAME,
-                    null, null, null, null, null, WorkspaceScreens.SCREEN_RANK));
+            // Get the first screen
+            final int firstScreenId;
+            try (Cursor c = db.rawQuery(String.format(Locale.ENGLISH,
+                    "SELECT MIN(%1$s) from %2$s where %3$s = %4$d",
+                    Favorites.SCREEN, Favorites.TABLE_NAME, Favorites.CONTAINER,
+                    Favorites.CONTAINER_DESKTOP), null)) {
 
-            if (screenIds.isEmpty()) {
-                // No update needed
-                t.commit();
-                return true;
-            }
-            if (screenIds.get(0) != 0) {
-                // First screen is not 0, we need to rename screens
-                if (screenIds.contains(0)) {
-                    // There is already a screen 0. First rename it to a different screen.
-                    int newScreenId = 1;
-                    while (screenIds.contains(newScreenId)) newScreenId++;
-                    renameScreen(db, 0, newScreenId);
+                if (!c.moveToNext()) {
+                    // No update needed
+                    t.commit();
+                    return true;
                 }
 
+                firstScreenId = c.getInt(0);
+            }
+
+            if (firstScreenId != 0) {
                 // Rename the first screen to 0.
-                renameScreen(db, screenIds.get(0), 0);
+                renameScreen(db, firstScreenId, 0);
             }
 
             // Check if the first row is empty
@@ -89,39 +87,39 @@
 
     private static void renameScreen(SQLiteDatabase db, int oldScreen, int newScreen) {
         String[] whereParams = new String[] { Integer.toString(oldScreen) };
-
         ContentValues values = new ContentValues();
-        values.put(WorkspaceScreens._ID, newScreen);
-        db.update(WorkspaceScreens.TABLE_NAME, values, "_id = ?", whereParams);
-
-        values.clear();
         values.put(Favorites.SCREEN, newScreen);
         db.update(Favorites.TABLE_NAME, values, "container = -100 and screen = ?", whereParams);
     }
 
-    /**
-     * Parses the cursor containing workspace screens table and returns the list of screen IDs
-     */
-    public static IntArray getScreenIdsFromCursor(Cursor sc) {
-        try {
-            return iterateCursor(sc,
-                    sc.getColumnIndexOrThrow(WorkspaceScreens._ID), new IntArray());
-        } finally {
-            sc.close();
+    public static IntArray queryIntArray(SQLiteDatabase db, String tableName, String columnName,
+            String selection, String groupBy, String orderBy) {
+        IntArray out = new IntArray();
+        try (Cursor c = db.query(tableName, new String[] { columnName }, selection, null,
+                groupBy, null, orderBy)) {
+            while (c.moveToNext()) {
+                out.add(c.getInt(0));
+            }
+        }
+        return out;
+    }
+
+    public static boolean tableExists(SQLiteDatabase db, String tableName) {
+        try (Cursor c = db.query(true, "sqlite_master", new String[] {"tbl_name"},
+                "tbl_name = ?", new String[] {tableName},
+                null, null, null, null, null)) {
+            return c.getCount() > 0;
         }
     }
 
-    public static IntArray iterateCursor(Cursor c, int columnIndex, IntArray out) {
-        while (c.moveToNext()) {
-            out.add(c.getInt(columnIndex));
-        }
-        return out;
+    public static void dropTable(SQLiteDatabase db, String tableName) {
+        db.execSQL("DROP TABLE IF EXISTS " + tableName);
     }
 
     /**
      * Utility class to simplify managing sqlite transactions
      */
-    public static class SQLiteTransaction implements AutoCloseable {
+    public static class SQLiteTransaction extends Binder implements AutoCloseable {
         private final SQLiteDatabase mDb;
 
         public SQLiteTransaction(SQLiteDatabase db) {
@@ -137,5 +135,9 @@
         public void close() {
             mDb.endTransaction();
         }
+
+        public SQLiteDatabase getDb() {
+            return mDb;
+        }
     }
 }
diff --git a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
index 9166b83..6d839f3 100644
--- a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
+++ b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
@@ -37,29 +37,21 @@
  */
 public class LossyScreenMigrationTask extends GridSizeMigrationTask {
 
-    private final SQLiteDatabase mDb;
-
     private final IntSparseArrayMap<DbEntry> mOriginalItems;
     private final IntSparseArrayMap<DbEntry> mUpdates;
 
     protected LossyScreenMigrationTask(
             Context context, InvariantDeviceProfile idp, SQLiteDatabase db) {
         // Decrease the rows count by 1
-        super(context, idp, getValidPackages(context),
+        super(context, db, getValidPackages(context),
                 new Point(idp.numColumns, idp.numRows + 1),
                 new Point(idp.numColumns, idp.numRows));
 
-        mDb = db;
         mOriginalItems = new IntSparseArrayMap<>();
         mUpdates = new IntSparseArrayMap<>();
     }
 
     @Override
-    protected Cursor queryWorkspace(String[] columns, String where) {
-        return mDb.query(Favorites.TABLE_NAME, columns, where, null, null, null, null);
-    }
-
-    @Override
     protected void update(DbEntry item) {
         mUpdates.put(item.id, item.copy());
     }
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 17c66b4..bcca4d8 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.provider;
 
+import static com.android.launcher3.provider.LauncherDbUtils.dropTable;
+
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
@@ -111,7 +113,7 @@
         db.execSQL("ALTER TABLE favorites RENAME TO favorites_old;");
         Favorites.addTableToDb(db, newProfileId, false);
         db.execSQL("INSERT INTO favorites SELECT * FROM favorites_old;");
-        db.execSQL("DROP TABLE favorites_old;");
+        dropTable(db, "favorites_old");
     }
 
     /**
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index ac1fafb..57a458b 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -44,6 +44,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.graphics.FragmentWithPreview;
 
 /**
  * A frame layout which contains a QSB. This internally uses fragment to bind the view, which
@@ -78,7 +79,7 @@
     /**
      * A fragment to display the QSB.
      */
-    public static class QsbFragment extends Fragment {
+    public static class QsbFragment extends FragmentWithPreview {
 
         public static final int QSB_WIDGET_HOST_ID = 1026;
         private static final int REQUEST_BIND_QSB = 1;
@@ -93,14 +94,13 @@
         private int mOrientation;
 
         @Override
-        public void onCreate(Bundle savedInstanceState) {
-            super.onCreate(savedInstanceState);
+        public void onInit(Bundle savedInstanceState) {
             mQsbWidgetHost = createHost();
             mOrientation = getContext().getResources().getConfiguration().orientation;
         }
 
         protected QsbWidgetHost createHost() {
-            return new QsbWidgetHost(getActivity(), QSB_WIDGET_HOST_ID,
+            return new QsbWidgetHost(getContext(), QSB_WIDGET_HOST_ID,
                     (c) -> new QsbWidgetHostView(c));
         }
 
@@ -110,7 +110,7 @@
         public View onCreateView(
                 LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
 
-            mWrapper = new FrameLayout(getActivity());
+            mWrapper = new FrameLayout(getContext());
 
             // Only add the view when enabled
             if (isQsbEnabled()) {
@@ -126,16 +126,16 @@
                 return getDefaultView(container, false /* show setup icon */);
             }
             Bundle opts = createBindOptions();
-            Activity activity = getActivity();
-            AppWidgetManager widgetManager = AppWidgetManager.getInstance(activity);
+            Context context = getContext();
+            AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
 
-            int widgetId = Utilities.getPrefs(activity).getInt(mKeyWidgetId, -1);
+            int widgetId = Utilities.getPrefs(context).getInt(mKeyWidgetId, -1);
             AppWidgetProviderInfo widgetInfo = widgetManager.getAppWidgetInfo(widgetId);
             boolean isWidgetBound = (widgetInfo != null) &&
                     widgetInfo.provider.equals(mWidgetInfo.provider);
 
             int oldWidgetId = widgetId;
-            if (!isWidgetBound) {
+            if (!isWidgetBound && !isInPreviewMode()) {
                 if (widgetId > -1) {
                     // widgetId is already bound and its not the correct provider. reset host.
                     mQsbWidgetHost.deleteHost();
@@ -155,14 +155,16 @@
             }
 
             if (isWidgetBound) {
-                mQsb = (QsbWidgetHostView) mQsbWidgetHost.createView(activity, widgetId, mWidgetInfo);
+                mQsb = (QsbWidgetHostView) mQsbWidgetHost.createView(context, widgetId, mWidgetInfo);
                 mQsb.setId(R.id.qsb_widget);
 
-                if (!Utilities.containsAll(AppWidgetManager.getInstance(activity)
-                        .getAppWidgetOptions(widgetId), opts)) {
-                    mQsb.updateAppWidgetOptions(opts);
+                if (!isInPreviewMode()) {
+                    if (!Utilities.containsAll(AppWidgetManager.getInstance(context)
+                            .getAppWidgetOptions(widgetId), opts)) {
+                        mQsb.updateAppWidgetOptions(opts);
+                    }
+                    mQsbWidgetHost.startListening();
                 }
-                mQsbWidgetHost.startListening();
                 return mQsb;
             }
 
@@ -171,7 +173,7 @@
         }
 
         private void saveWidgetId(int widgetId) {
-            Utilities.getPrefs(getActivity()).edit().putInt(mKeyWidgetId, widgetId).apply();
+            Utilities.getPrefs(getContext()).edit().putInt(mKeyWidgetId, widgetId).apply();
         }
 
         @Override
@@ -206,7 +208,7 @@
                 return;
             }
 
-            if (mWrapper != null && getActivity() != null) {
+            if (mWrapper != null && getContext() != null) {
                 mWrapper.removeAllViews();
                 mWrapper.addView(createQsb(mWrapper));
             }
@@ -217,10 +219,10 @@
         }
 
         protected Bundle createBindOptions() {
-            InvariantDeviceProfile idp = LauncherAppState.getIDP(getActivity());
+            InvariantDeviceProfile idp = LauncherAppState.getIDP(getContext());
 
             Bundle opts = new Bundle();
-            Rect size = AppWidgetResizeFrame.getWidgetSizeRanges(getActivity(),
+            Rect size = AppWidgetResizeFrame.getWidgetSizeRanges(getContext(),
                     idp.numColumns, 1, null);
             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH, size.left);
             opts.putInt(AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT, size.top);
@@ -252,14 +254,14 @@
          */
         protected AppWidgetProviderInfo getSearchWidgetProvider() {
             SearchManager searchManager =
-                    (SearchManager) getActivity().getSystemService(Context.SEARCH_SERVICE);
+                    (SearchManager) getContext().getSystemService(Context.SEARCH_SERVICE);
             ComponentName searchComponent = searchManager.getGlobalSearchActivity();
             if (searchComponent == null) return null;
             String providerPkg = searchComponent.getPackageName();
 
             AppWidgetProviderInfo defaultWidgetForSearchPackage = null;
 
-            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getActivity());
+            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getContext());
             for (AppWidgetProviderInfo info : appWidgetManager.getInstalledProviders()) {
                 if (info.provider.getPackageName().equals(providerPkg) && info.configure == null) {
                     if ((info.widgetCategory
diff --git a/src/com/android/launcher3/settings/IconBadgingPreference.java b/src/com/android/launcher3/settings/NotificationDotsPreference.java
similarity index 89%
rename from src/com/android/launcher3/settings/IconBadgingPreference.java
rename to src/com/android/launcher3/settings/NotificationDotsPreference.java
index 7c97b38..f30470a 100644
--- a/src/com/android/launcher3/settings/IconBadgingPreference.java
+++ b/src/com/android/launcher3/settings/NotificationDotsPreference.java
@@ -38,10 +38,10 @@
 import androidx.preference.PreferenceViewHolder;
 
 /**
- * A {@link Preference} for indicating icon badging status.
- * Also has utility methods for updating UI based on badging status changes.
+ * A {@link Preference} for indicating notification dots status.
+ * Also has utility methods for updating UI based on dots status changes.
  */
-public class IconBadgingPreference extends Preference
+public class NotificationDotsPreference extends Preference
         implements SecureSettingsObserver.OnChangeListener {
 
     private boolean mWidgetFrameVisible = false;
@@ -49,20 +49,20 @@
     /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
     private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
 
-    public IconBadgingPreference(
+    public NotificationDotsPreference(
             Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
         super(context, attrs, defStyleAttr, defStyleRes);
     }
 
-    public IconBadgingPreference(Context context, AttributeSet attrs, int defStyleAttr) {
+    public NotificationDotsPreference(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
     }
 
-    public IconBadgingPreference(Context context, AttributeSet attrs) {
+    public NotificationDotsPreference(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
 
-    public IconBadgingPreference(Context context) {
+    public NotificationDotsPreference(Context context) {
         super(context);
     }
 
@@ -85,7 +85,9 @@
 
     @Override
     public void onSettingsChanged(boolean enabled) {
-        int summary = enabled ? R.string.icon_badging_desc_on : R.string.icon_badging_desc_off;
+        int summary = enabled
+                ? R.string.notification_dots_desc_on
+                : R.string.notification_dots_desc_off;
 
         boolean serviceEnabled = true;
         if (enabled) {
diff --git a/src/com/android/launcher3/settings/PreferenceHighlighter.java b/src/com/android/launcher3/settings/PreferenceHighlighter.java
index 4ed4cf1..8ba8146 100644
--- a/src/com/android/launcher3/settings/PreferenceHighlighter.java
+++ b/src/com/android/launcher3/settings/PreferenceHighlighter.java
@@ -15,7 +15,7 @@
  */
 package com.android.launcher3.settings;
 
-import static androidx.core.graphics.ColorUtils.setAlphaComponent;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -57,7 +57,7 @@
     private static final long HIGHLIGHT_DURATION = 15000L;
     private static final long HIGHLIGHT_FADE_OUT_DURATION = 500L;
     private static final long HIGHLIGHT_FADE_IN_DURATION = 200L;
-    private static final int END_COLOR = setAlphaComponent(Color.WHITE, 0);
+    private static final int END_COLOR = setColorAlphaBound(Color.WHITE, 0);
 
     private final Paint mPaint = new Paint();
     private final RecyclerView mRv;
@@ -91,7 +91,7 @@
 
         if (!mHighLightStarted) {
             // Start highlight
-            int colorTo = setAlphaComponent(Themes.getColorAccent(mRv.getContext()), 66);
+            int colorTo = setColorAlphaBound(Themes.getColorAccent(mRv.getContext()), 66);
             ObjectAnimator anim = ObjectAnimator.ofArgb(this, HIGHLIGHT_COLOR, END_COLOR, colorTo);
             anim.setDuration(HIGHLIGHT_FADE_IN_DURATION);
             anim.setRepeatMode(ValueAnimator.REVERSE);
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 7c158d9..6e7188f 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -32,11 +32,9 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.graphics.IconShapeOverride;
 import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
 import com.android.launcher3.util.SecureSettingsObserver;
 
-import androidx.preference.ListPreference;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceFragment;
 import androidx.preference.PreferenceFragment.OnPreferenceStartFragmentCallback;
@@ -54,7 +52,7 @@
     private static final String DEVELOPER_OPTIONS_KEY = "pref_developer_options";
     private static final String FLAGS_PREFERENCE_KEY = "flag_toggler";
 
-    private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging";
+    private static final String NOTIFICATION_DOTS_PREFERENCE_KEY = "pref_icon_badging";
     /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
     private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
 
@@ -120,7 +118,7 @@
      */
     public static class LauncherSettingsFragment extends PreferenceFragment {
 
-        private SecureSettingsObserver mIconBadgingObserver;
+        private SecureSettingsObserver mNotificationDotsObserver;
 
         private String mHighLightKey;
         private boolean mPreferenceHighlighted = false;
@@ -165,33 +163,26 @@
          */
         protected boolean initPreference(Preference preference) {
             switch (preference.getKey()) {
-                case ICON_BADGING_PREFERENCE_KEY:
+                case NOTIFICATION_DOTS_PREFERENCE_KEY:
                     if (!Utilities.ATLEAST_OREO ||
-                            !getResources().getBoolean(R.bool.notification_badging_enabled)) {
+                            !getResources().getBoolean(R.bool.notification_dots_enabled)) {
                         return false;
                     }
 
-                    // Listen to system notification badge settings while this UI is active.
-                    mIconBadgingObserver = newNotificationSettingsObserver(
-                            getActivity(), (IconBadgingPreference) preference);
-                    mIconBadgingObserver.register();
+                    // Listen to system notification dot settings while this UI is active.
+                    mNotificationDotsObserver = newNotificationSettingsObserver(
+                            getActivity(), (NotificationDotsPreference) preference);
+                    mNotificationDotsObserver.register();
                     // Also listen if notification permission changes
-                    mIconBadgingObserver.getResolver().registerContentObserver(
+                    mNotificationDotsObserver.getResolver().registerContentObserver(
                             Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS), false,
-                            mIconBadgingObserver);
-                    mIconBadgingObserver.dispatchOnChange();
+                            mNotificationDotsObserver);
+                    mNotificationDotsObserver.dispatchOnChange();
                     return true;
 
                 case ADD_ICON_PREFERENCE_KEY:
                     return Utilities.ATLEAST_OREO;
 
-                case IconShapeOverride.KEY_PREFERENCE:
-                    if (!IconShapeOverride.isSupported(getActivity())) {
-                        return false;
-                    }
-                    IconShapeOverride.handlePreferenceUi((ListPreference) preference);
-                    return true;
-
                 case ALLOW_ROTATION_PREFERENCE_KEY:
                     if (getResources().getBoolean(R.bool.allow_rotation)) {
                         // Launcher supports rotation by default. No need to show this setting.
@@ -245,9 +236,9 @@
 
         @Override
         public void onDestroy() {
-            if (mIconBadgingObserver != null) {
-                mIconBadgingObserver.unregister();
-                mIconBadgingObserver = null;
+            if (mNotificationDotsObserver != null) {
+                mNotificationDotsObserver.unregister();
+                mNotificationDotsObserver = null;
             }
             super.onDestroy();
         }
diff --git a/src/com/android/launcher3/states/InternalStateHandler.java b/src/com/android/launcher3/states/InternalStateHandler.java
index c6370c5..d326ff3 100644
--- a/src/com/android/launcher3/states/InternalStateHandler.java
+++ b/src/com/android/launcher3/states/InternalStateHandler.java
@@ -36,6 +36,7 @@
 public abstract class InternalStateHandler extends Binder {
 
     public static final String EXTRA_STATE_HANDLER = "launcher.state_handler";
+    public static final String EXTRA_FROM_HOME_KEY = "android.intent.extra.FROM_HOME_KEY";
 
     private static final Scheduler sScheduler = new Scheduler();
 
@@ -76,6 +77,10 @@
             Launcher launcher, Intent intent, boolean alreadyOnHome, boolean explicitIntent) {
         boolean result = false;
         if (intent != null && intent.getExtras() != null) {
+            // If we know that this the intent comes from pressing Home, defer to the default
+            // processing.
+            if (intent.hasExtra(EXTRA_FROM_HOME_KEY)) return false;
+
             IBinder stateBinder = intent.getExtras().getBinder(EXTRA_STATE_HANDLER);
             if (stateBinder instanceof InternalStateHandler) {
                 InternalStateHandler handler = (InternalStateHandler) stateBinder;
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index 9c4a4ea..65103f6 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -29,6 +29,7 @@
 
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.util.UiThreadHelper;
 
 /**
  * Utility class to manage launcher rotation
@@ -154,7 +155,7 @@
         }
         if (activityFlags != mLastActivityFlags) {
             mLastActivityFlags = activityFlags;
-            mActivity.setRequestedOrientation(activityFlags);
+            UiThreadHelper.setOrientationAsync(mActivity, activityFlags);
         }
     }
 
diff --git a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
index ce1cc89..bb14328 100644
--- a/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
+++ b/src/com/android/launcher3/touch/AbstractStateChangeTouchController.java
@@ -24,6 +24,7 @@
 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 static com.android.launcher3.config.FeatureFlags.QUICKSTEP_SPRINGS;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -45,6 +46,7 @@
 import com.android.launcher3.anim.AnimatorPlaybackController;
 import com.android.launcher3.anim.AnimatorSetBuilder;
 import com.android.launcher3.compat.AccessibilityManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
@@ -372,8 +374,7 @@
 
         final LauncherState targetState;
         final float progress = mCurrentAnimation.getProgressFraction();
-        final float interpolatedProgress = mCurrentAnimation.getInterpolator()
-                .getInterpolation(progress);
+        final float interpolatedProgress = mCurrentAnimation.getInterpolatedProgress();
         if (fling) {
             targetState =
                     Float.compare(Math.signum(velocity), Math.signum(mProgressMultiplier)) == 0
@@ -429,8 +430,8 @@
         maybeUpdateAtomicAnim(mFromState, targetState, targetState == mToState ? 1f : 0f);
         updateSwipeCompleteAnimation(anim, Math.max(duration, getRemainingAtomicDuration()),
                 targetState, velocity, fling);
-        mCurrentAnimation.dispatchOnStart();
-        if (fling && targetState == LauncherState.ALL_APPS) {
+        mCurrentAnimation.dispatchOnStartWithVelocity(endProgress, velocity);
+        if (fling && targetState == LauncherState.ALL_APPS && !QUICKSTEP_SPRINGS.get()) {
             mLauncher.getAppsView().addSpringFromFlingUpdateListener(anim, velocity);
         }
         anim.start();
diff --git a/src/com/android/launcher3/util/ConfigMonitor.java b/src/com/android/launcher3/util/ConfigMonitor.java
index 717acdc..607afab 100644
--- a/src/com/android/launcher3/util/ConfigMonitor.java
+++ b/src/com/android/launcher3/util/ConfigMonitor.java
@@ -29,6 +29,7 @@
 import android.view.Display;
 import android.view.WindowManager;
 
+import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.Utilities.Consumer;
 
@@ -40,6 +41,8 @@
 
     private static final String TAG = "ConfigMonitor";
 
+    private final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
+
     private final Point mTmpPoint1 = new Point();
     private final Point mTmpPoint2 = new Point();
 
@@ -72,7 +75,15 @@
 
         mCallback = callback;
 
+        // Listen for configuration change
         mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED));
+
+        // Listen for {@link OverlayManager} change
+        IntentFilter filter = new IntentFilter(ACTION_OVERLAY_CHANGED);
+        filter.addDataScheme("package");
+        mContext.registerReceiver(this, filter);
+
+        // Listen for display manager change
         mContext.getSystemService(DisplayManager.class)
                 .registerDisplayListener(this, new Handler(UiThreadHelper.getBackgroundLooper()));
     }
@@ -80,8 +91,14 @@
     @Override
     public void onReceive(Context context, Intent intent) {
         Configuration config = context.getResources().getConfiguration();
+        // TODO: when overlay manager service encodes more information to the Uri such as category
+        // of the overlay, only listen to the ones that are of interest to launcher.
+        if (intent != null && ACTION_OVERLAY_CHANGED.equals(intent.getAction())) {
+            Log.d(TAG, "Overlay changed.");
+            notifyChange();
+        }
         if (mFontScale != config.fontScale || mDensity != config.densityDpi) {
-            Log.d(TAG, "Configuration changed");
+            Log.d(TAG, "Configuration changed.");
             notifyChange();
         }
     }
diff --git a/src/com/android/launcher3/util/ContentWriter.java b/src/com/android/launcher3/util/ContentWriter.java
index 4384328..00adf10 100644
--- a/src/com/android/launcher3/util/ContentWriter.java
+++ b/src/com/android/launcher3/util/ContentWriter.java
@@ -25,8 +25,8 @@
 
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.icons.GraphicsUtils;
 
 /**
  * A wrapper around {@link ContentValues} with some utility methods.
@@ -97,7 +97,7 @@
         Preconditions.assertNonUiThread();
         if (mIcon != null && !LauncherAppState.getInstance(context).getIconCache()
                 .isDefaultIcon(mIcon, mUser)) {
-            mValues.put(LauncherSettings.Favorites.ICON, Utilities.flattenBitmap(mIcon));
+            mValues.put(LauncherSettings.Favorites.ICON, GraphicsUtils.flattenBitmap(mIcon));
             mIcon = null;
         }
         return mValues;
diff --git a/src/com/android/launcher3/util/IntArray.java b/src/com/android/launcher3/util/IntArray.java
index b2fb32a..d2a551f 100644
--- a/src/com/android/launcher3/util/IntArray.java
+++ b/src/com/android/launcher3/util/IntArray.java
@@ -100,6 +100,14 @@
     }
 
     /**
+     * Sets the array to be same as {@param other}
+     */
+    public void copyFrom(IntArray other) {
+        clear();
+        addAll(other);
+    }
+
+    /**
      * Ensures capacity to append at least <code>count</code> values.
      */
     private void ensureCapacity(int count) {
@@ -127,6 +135,25 @@
         return wrap(toArray());
     }
 
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        if (obj instanceof IntArray) {
+            IntArray arr = (IntArray) obj;
+            if (mSize == arr.mSize) {
+                for (int i = 0; i < mSize; i++) {
+                    if (arr.mValues[i] != mValues[i]) {
+                        return false;
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Returns the value at the specified position in this array.
      */
diff --git a/src/com/android/launcher3/util/IntSet.java b/src/com/android/launcher3/util/IntSet.java
index 63499b0..851f129 100644
--- a/src/com/android/launcher3/util/IntSet.java
+++ b/src/com/android/launcher3/util/IntSet.java
@@ -48,4 +48,34 @@
     public int size() {
         return mArray.size();
     }
+
+    public void clear() {
+        mArray.clear();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == this) {
+            return true;
+        }
+        return (obj instanceof IntSet) && ((IntSet) obj).mArray.equals(mArray);
+    }
+
+    public IntArray getArray() {
+        return mArray;
+    }
+
+    /**
+     * Sets this set to be same as {@param other}
+     */
+    public void copyFrom(IntSet other) {
+        mArray.copyFrom(other.mArray);
+    }
+
+    public static IntSet wrap(IntArray array) {
+        IntSet set = new IntSet();
+        set.mArray.addAll(array);
+        Arrays.sort(set.mArray.mValues, 0, set.mArray.mSize);
+        return set;
+    }
 }
diff --git a/src/com/android/launcher3/util/RaceConditionTracker.java b/src/com/android/launcher3/util/RaceConditionTracker.java
new file mode 100644
index 0000000..6954d0e
--- /dev/null
+++ b/src/com/android/launcher3/util/RaceConditionTracker.java
@@ -0,0 +1,61 @@
+/*
+ * 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;
+
+/**
+ * Event tracker for reliably reproducing race conditions in tests.
+ * The app should call onEvent() for events that the test will try to reproduce in all possible
+ * orders.
+ */
+public class RaceConditionTracker {
+    public final static boolean ENTER = true;
+    public final static boolean EXIT = false;
+    static final String ENTER_POSTFIX = "enter";
+    static final String EXIT_POSTFIX = "exit";
+
+    public interface EventProcessor {
+        void onEvent(String eventName);
+    }
+
+    private static EventProcessor sEventProcessor;
+
+    static void setEventProcessor(EventProcessor eventProcessor) {
+        sEventProcessor = eventProcessor;
+    }
+
+    public static void onEvent(String eventName) {
+        if (sEventProcessor != null) sEventProcessor.onEvent(eventName);
+    }
+
+    public static void onEvent(String eventName, boolean isEnter) {
+        if (sEventProcessor != null) {
+            sEventProcessor.onEvent(enterExitEvt(eventName, isEnter));
+        }
+    }
+
+    public static String enterExitEvt(String eventName, boolean isEnter) {
+        return eventName + ":" + (isEnter ? ENTER_POSTFIX : EXIT_POSTFIX);
+    }
+
+    public static String enterEvt(String eventName) {
+        return enterExitEvt(eventName, ENTER);
+    }
+
+    public static String exitEvt(String eventName) {
+        return enterExitEvt(eventName, EXIT);
+    }
+}
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index 5f965a3..675e2f4 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -21,6 +21,9 @@
 import android.graphics.Color;
 import android.graphics.ColorMatrix;
 import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+import android.util.TypedValue;
 
 /**
  * Various utility methods associated with theming.
@@ -104,4 +107,29 @@
         target.getArray()[14] = Color.blue(dstColor) - Color.blue(srcColor);
         target.getArray()[19] = Color.alpha(dstColor) - Color.alpha(srcColor);
     }
+
+    /**
+     * Creates a map for attribute-name to value for all the values in {@param attrs} which can be
+     * held in memory for later use.
+     */
+    public static SparseArray<TypedValue> createValueMap(Context context, AttributeSet attrSet,
+            IntArray keysToIgnore) {
+        int count = attrSet.getAttributeCount();
+        IntArray attrNameArray = new IntArray(count);
+        for (int i = 0; i < count; i++) {
+            attrNameArray.add(attrSet.getAttributeNameResource(i));
+        }
+        attrNameArray.removeAllValues(keysToIgnore);
+
+        int[] attrNames = attrNameArray.toArray();
+        SparseArray<TypedValue> result = new SparseArray<>(attrNames.length);
+        TypedArray ta = context.obtainStyledAttributes(attrSet, attrNames);
+        for (int i = 0; i < attrNames.length; i++) {
+            TypedValue tv = new TypedValue();
+            ta.getValue(i, tv);
+            result.put(attrNames[i], tv);
+        }
+
+        return result;
+    }
 }
diff --git a/src/com/android/launcher3/util/TraceHelper.java b/src/com/android/launcher3/util/TraceHelper.java
index 4aa2f37..4fea2e9 100644
--- a/src/com/android/launcher3/util/TraceHelper.java
+++ b/src/com/android/launcher3/util/TraceHelper.java
@@ -41,33 +41,37 @@
 
     public static void beginSection(String sectionName) {
         if (ENABLED) {
-            MutableLong time = sUpTimes.get(sectionName);
-            if (time == null) {
-                time = new MutableLong(isLoggable(sectionName, VERBOSE) ? 0 : -1);
-                sUpTimes.put(sectionName, time);
-            }
-            if (time.value >= 0) {
-                if (SYSTEM_TRACE) {
-                    Trace.beginSection(sectionName);
+            synchronized (sUpTimes) {
+                MutableLong time = sUpTimes.get(sectionName);
+                if (time == null) {
+                    time = new MutableLong(isLoggable(sectionName, VERBOSE) ? 0 : -1);
+                    sUpTimes.put(sectionName, time);
                 }
-                time.value = SystemClock.uptimeMillis();
+                if (time.value >= 0) {
+                    if (SYSTEM_TRACE) {
+                        Trace.beginSection(sectionName);
+                    }
+                    time.value = SystemClock.uptimeMillis();
+                }
             }
         }
     }
 
     public static void partitionSection(String sectionName, String partition) {
         if (ENABLED) {
-            MutableLong time = sUpTimes.get(sectionName);
-            if (time != null && time.value >= 0) {
+            synchronized (sUpTimes) {
+                MutableLong time = sUpTimes.get(sectionName);
+                if (time != null && time.value >= 0) {
 
-                if (SYSTEM_TRACE) {
-                    Trace.endSection();
-                    Trace.beginSection(sectionName);
+                    if (SYSTEM_TRACE) {
+                        Trace.endSection();
+                        Trace.beginSection(sectionName);
+                    }
+
+                    long now = SystemClock.uptimeMillis();
+                    Log.d(sectionName, partition + " : " + (now - time.value));
+                    time.value = now;
                 }
-
-                long now = SystemClock.uptimeMillis();
-                Log.d(sectionName, partition + " : " + (now - time.value));
-                time.value = now;
             }
         }
     }
@@ -80,12 +84,14 @@
 
     public static void endSection(String sectionName, String msg) {
         if (ENABLED) {
-            MutableLong time = sUpTimes.get(sectionName);
-            if (time != null && time.value >= 0) {
-                if (SYSTEM_TRACE) {
-                    Trace.endSection();
+            synchronized (sUpTimes) {
+                MutableLong time = sUpTimes.get(sectionName);
+                if (time != null && time.value >= 0) {
+                    if (SYSTEM_TRACE) {
+                        Trace.endSection();
+                    }
+                    Log.d(sectionName, msg + " : " + (SystemClock.uptimeMillis() - time.value));
                 }
-                Log.d(sectionName, msg + " : " + (SystemClock.uptimeMillis() - time.value));
             }
         }
     }
diff --git a/src/com/android/launcher3/util/UiThreadHelper.java b/src/com/android/launcher3/util/UiThreadHelper.java
index 27140a1..cc442f9 100644
--- a/src/com/android/launcher3/util/UiThreadHelper.java
+++ b/src/com/android/launcher3/util/UiThreadHelper.java
@@ -15,6 +15,7 @@
  */
 package com.android.launcher3.util;
 
+import android.app.Activity;
 import android.content.Context;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -33,6 +34,8 @@
     private static Handler sHandler;
 
     private static final int MSG_HIDE_KEYBOARD = 1;
+    private static final int MSG_SET_ORIENTATION = 2;
+    private static final int MSG_RUN_COMMAND = 3;
 
     public static Looper getBackgroundLooper() {
         if (sHandlerThread == null) {
@@ -55,6 +58,15 @@
         Message.obtain(getHandler(context), MSG_HIDE_KEYBOARD, token).sendToTarget();
     }
 
+    public static void setOrientationAsync(Activity activity, int orientation) {
+        Message.obtain(getHandler(activity), MSG_SET_ORIENTATION, orientation, 0, activity)
+                .sendToTarget();
+    }
+
+    public static void runAsyncCommand(Context context, AsyncCommand command, int arg1, int arg2) {
+        Message.obtain(getHandler(context), MSG_RUN_COMMAND, arg1, arg2, command).sendToTarget();
+    }
+
     private static class UiCallbacks implements Handler.Callback {
 
         private final InputMethodManager mIMM;
@@ -69,8 +81,19 @@
                 case MSG_HIDE_KEYBOARD:
                     mIMM.hideSoftInputFromWindow((IBinder) message.obj, 0);
                     return true;
+                case MSG_SET_ORIENTATION:
+                    ((Activity) message.obj).setRequestedOrientation(message.arg1);
+                    return true;
+                case MSG_RUN_COMMAND:
+                    ((AsyncCommand) message.obj).execute(message.arg1, message.arg2);
+                    return true;
             }
             return false;
         }
     }
+
+    public interface AsyncCommand {
+
+        void execute(int arg1, int arg2);
+    }
 }
diff --git a/src/com/android/launcher3/util/ViewPool.java b/src/com/android/launcher3/util/ViewPool.java
new file mode 100644
index 0000000..8af048d
--- /dev/null
+++ b/src/com/android/launcher3/util/ViewPool.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.util;
+
+import android.content.Context;
+import android.os.Handler;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import com.android.launcher3.util.ViewPool.Reusable;
+
+import androidx.annotation.AnyThread;
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+
+/**
+ * Utility class to maintain a pool of reusable views.
+ * During initialization, views are inflated on the background thread.
+ */
+public class ViewPool<T extends View & Reusable> {
+
+    private final Object[] mPool;
+
+    private final LayoutInflater mInflater;
+    private final ViewGroup mParent;
+    private final int mLayoutId;
+
+    private int mCurrentSize = 0;
+
+    public ViewPool(Context context, @Nullable ViewGroup parent,
+            int layoutId, int maxSize, int initialSize) {
+        mLayoutId = layoutId;
+        mParent = parent;
+        mInflater = LayoutInflater.from(context);
+        mPool = new Object[maxSize];
+
+        if (initialSize > 0) {
+            initPool(initialSize);
+        }
+    }
+
+    @UiThread
+    private void initPool(int initialSize) {
+        Preconditions.assertUIThread();
+        Handler handler = new Handler();
+
+        // Inflate views on a non looper thread. This allows us to catch errors like calling
+        // "new Handler()" in constructor easily.
+        new Thread(() -> {
+            for (int i = 0; i < initialSize; i++) {
+                T view = inflateNewView();
+                handler.post(() -> addToPool(view));
+            }
+        }).start();
+    }
+
+    @UiThread
+    public void recycle(T view) {
+        Preconditions.assertUIThread();
+        view.onRecycle();
+        addToPool(view);
+    }
+
+    @UiThread
+    private void addToPool(T view) {
+        Preconditions.assertUIThread();
+        if (mCurrentSize >= mPool.length) {
+            // pool is full
+            return;
+        }
+
+        mPool[mCurrentSize] = view;
+        mCurrentSize++;
+    }
+
+    @UiThread
+    public T getView() {
+        Preconditions.assertUIThread();
+        if (mCurrentSize > 0) {
+            mCurrentSize--;
+            return (T) mPool[mCurrentSize];
+        }
+        return inflateNewView();
+    }
+
+    @AnyThread
+    private T inflateNewView() {
+        return (T) mInflater.inflate(mLayoutId, mParent, false);
+    }
+
+    /**
+     * Interface to indicate that a view is reusable
+     */
+    public interface Reusable {
+
+        /**
+         * Called when a view is recycled / added back to the pool
+         */
+        void onRecycle();
+    }
+}
diff --git a/src/com/android/launcher3/views/ActivityContext.java b/src/com/android/launcher3/views/ActivityContext.java
index 04100af..c9cdeff 100644
--- a/src/com/android/launcher3/views/ActivityContext.java
+++ b/src/com/android/launcher3/views/ActivityContext.java
@@ -18,10 +18,15 @@
 import android.content.Context;
 import android.content.ContextWrapper;
 import android.view.ContextThemeWrapper;
+import android.view.View.AccessibilityDelegate;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.dot.DotInfo;
 
 /**
- * An interface to be used along with a context. This allows a generic class to depend on Context
- * subclass instead of an Activity.
+ * An interface to be used along with a context for various activities in Launcher. This allows a
+ * generic class to depend on Context subclass instead of an Activity.
  */
 public interface ActivityContext {
 
@@ -29,8 +34,28 @@
         return false;
     }
 
+    default DotInfo getDotInfoForItem(ItemInfo info) {
+        return null;
+    }
+
+    /**
+     * For items with tree hierarchy, notifies the activity to invalidate the parent when a root
+     * is invalidated
+     * @param info info associated with a root node.
+     */
+    default void invalidateParent(ItemInfo info) { }
+
+    default AccessibilityDelegate getAccessibilityDelegate() {
+        return null;
+    }
+
+    /**
+     * The root view to support drag-and-drop and popup support.
+     */
     BaseDragLayer getDragLayer();
 
+    DeviceProfile getDeviceProfile();
+
     static ActivityContext lookupContext(Context context) {
         if (context instanceof ActivityContext) {
             return (ActivityContext) context;
diff --git a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
index 64e166e..d89e7f8 100644
--- a/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
+++ b/src/com/android/launcher3/views/DoubleShadowBubbleTextView.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.views;
 
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
+
 import android.content.Context;
 import android.content.res.TypedArray;
 import android.graphics.Canvas;
@@ -26,8 +28,6 @@
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.R;
 
-import androidx.core.graphics.ColorUtils;
-
 /**
  * Extension of {@link BubbleTextView} which draws two shadows on the text (ambient and key shadows}
  */
@@ -60,20 +60,20 @@
 
         // We enhance the shadow by drawing the shadow twice
         getPaint().setShadowLayer(mShadowInfo.ambientShadowBlur, 0, 0,
-                ColorUtils.setAlphaComponent(mShadowInfo.ambientShadowColor, alpha));
+                setColorAlphaBound(mShadowInfo.ambientShadowColor, alpha));
 
-        drawWithoutBadge(canvas);
+        drawWithoutDot(canvas);
         canvas.save();
         canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
                 getScrollX() + getWidth(),
                 getScrollY() + getHeight());
 
         getPaint().setShadowLayer(mShadowInfo.keyShadowBlur, 0.0f, mShadowInfo.keyShadowOffset,
-                ColorUtils.setAlphaComponent(mShadowInfo.keyShadowColor, alpha));
-        drawWithoutBadge(canvas);
+                setColorAlphaBound(mShadowInfo.keyShadowColor, alpha));
+        drawWithoutDot(canvas);
         canvas.restore();
 
-        drawBadgeIfNecessary(canvas);
+        drawDotIfNecessary(canvas);
     }
 
     public static class ShadowInfo {
@@ -107,11 +107,11 @@
                 return true;
             } else if (ambientShadowAlpha > 0) {
                 textView.getPaint().setShadowLayer(ambientShadowBlur, 0, 0,
-                        ColorUtils.setAlphaComponent(ambientShadowColor, textAlpha));
+                        setColorAlphaBound(ambientShadowColor, textAlpha));
                 return true;
             } else if (keyShadowAlpha > 0) {
                 textView.getPaint().setShadowLayer(keyShadowBlur, 0.0f, keyShadowOffset,
-                        ColorUtils.setAlphaComponent(keyShadowColor, textAlpha));
+                        setColorAlphaBound(keyShadowColor, textAlpha));
                 return true;
             } else {
                 return false;
diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java
index c540b59..6ba2f40 100644
--- a/src/com/android/launcher3/views/OptionsPopupView.java
+++ b/src/com/android/launcher3/views/OptionsPopupView.java
@@ -34,6 +34,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.popup.ArrowPopup;
 import com.android.launcher3.shortcuts.DeepShortcutView;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
@@ -151,8 +152,10 @@
         ArrayList<OptionItem> options = new ArrayList<>();
         options.add(new OptionItem(R.string.wallpaper_button_text, R.drawable.ic_wallpaper,
                 ControlType.WALLPAPER_BUTTON, OptionsPopupView::startWallpaperPicker));
-        options.add(new OptionItem(R.string.widget_button_text, R.drawable.ic_widget,
-                ControlType.WIDGETS_BUTTON, OptionsPopupView::onWidgetsClicked));
+        if (!FeatureFlags.GO_DISABLE_WIDGETS) {
+            options.add(new OptionItem(R.string.widget_button_text, R.drawable.ic_widget,
+                    ControlType.WIDGETS_BUTTON, OptionsPopupView::onWidgetsClicked));
+        }
         options.add(new OptionItem(R.string.settings_button_text, R.drawable.ic_setting,
                 ControlType.SETTINGS_BUTTON, OptionsPopupView::startSettings));
 
diff --git a/src/com/android/launcher3/views/ScrimView.java b/src/com/android/launcher3/views/ScrimView.java
index 6fd84db..deb0965 100644
--- a/src/com/android/launcher3/views/ScrimView.java
+++ b/src/com/android/launcher3/views/ScrimView.java
@@ -22,9 +22,9 @@
 import static com.android.launcher3.LauncherState.NORMAL;
 import static com.android.launcher3.anim.Interpolators.ACCEL;
 import static com.android.launcher3.anim.Interpolators.DEACCEL;
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 
 import static androidx.core.graphics.ColorUtils.compositeColors;
-import static androidx.core.graphics.ColorUtils.setAlphaComponent;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -182,7 +182,7 @@
     @Override
     public void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo) {
         mScrimColor = wallpaperColorInfo.getMainColor();
-        mEndFlatColor = compositeColors(mEndScrim, setAlphaComponent(
+        mEndFlatColor = compositeColors(mEndScrim, setColorAlphaBound(
                 mScrimColor, Math.round(mMaxScrimAlpha * 255)));
         mEndFlatColorAlpha = Color.alpha(mEndFlatColor);
         updateColors();
@@ -201,7 +201,7 @@
     public void reInitUi() { }
 
     protected void updateColors() {
-        mCurrentFlatColor = mProgress >= 1 ? 0 : setAlphaComponent(
+        mCurrentFlatColor = mProgress >= 1 ? 0 : setColorAlphaBound(
                 mEndFlatColor, Math.round((1 - mProgress) * mEndFlatColorAlpha));
     }
 
diff --git a/src/com/android/launcher3/widget/BaseWidgetSheet.java b/src/com/android/launcher3/widget/BaseWidgetSheet.java
index 48c18f8..673b3cc 100644
--- a/src/com/android/launcher3/widget/BaseWidgetSheet.java
+++ b/src/com/android/launcher3/widget/BaseWidgetSheet.java
@@ -17,6 +17,7 @@
 
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
 
+import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
 import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
 
 import android.content.Context;
@@ -42,8 +43,6 @@
 import com.android.launcher3.views.AbstractSlideInView;
 import com.android.launcher3.views.BaseDragLayer;
 
-import androidx.core.graphics.ColorUtils;
-
 /**
  * Base class for various widgets popup
  */
@@ -162,11 +161,11 @@
 
     private static View createColorScrim(Context context) {
         View view = new View(context);
-        view.forceHasOverlappingRendering(false);
+        if (Utilities.ATLEAST_NOUGAT) view.forceHasOverlappingRendering(false);
 
         WallpaperColorInfo colors = WallpaperColorInfo.getInstance(context);
         int alpha = context.getResources().getInteger(R.integer.extracted_color_gradient_alpha);
-        view.setBackgroundColor(ColorUtils.setAlphaComponent(colors.getSecondaryColor(), alpha));
+        view.setBackgroundColor(setColorAlphaBound(colors.getSecondaryColor(), alpha));
 
         BaseDragLayer.LayoutParams lp = new BaseDragLayer.LayoutParams(MATCH_PARENT, MATCH_PARENT);
         lp.ignoreInsets = true;
diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
index 95f8daa..35e44bb 100644
--- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java
@@ -212,7 +212,8 @@
                 }
                 break;
         }
-        return false;
+        // We want to keep receiving though events to be able to cancel long press on ACTION_UP
+        return true;
     }
 
     @Override
diff --git a/src_build_config/BuildConfig.java b/src_build_config/BuildConfig.java
new file mode 100644
index 0000000..36d7f4b
--- /dev/null
+++ b/src_build_config/BuildConfig.java
@@ -0,0 +1,21 @@
+/*
+ * 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;
+
+public final class BuildConfig {
+  public static final String APPLICATION_ID = "com.android.launcher3";
+}
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/LoaderResults.java b/src_shortcuts_overrides/com/android/launcher3/model/LoaderResults.java
new file mode 100644
index 0000000..1710aef
--- /dev/null
+++ b/src_shortcuts_overrides/com/android/launcher3/model/LoaderResults.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.launcher3.model;
+
+import com.android.launcher3.AllAppsList;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherModel.Callbacks;
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.widget.WidgetListRowEntry;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Helper class to handle results of {@link com.android.launcher3.model.LoaderTask}.
+ */
+public class LoaderResults extends BaseLoaderResults {
+
+    public LoaderResults(LauncherAppState app, BgDataModel dataModel,
+            AllAppsList allAppsList, int pageToBindFirst, WeakReference<Callbacks> callbacks) {
+        super(app, dataModel, allAppsList, pageToBindFirst, callbacks);
+    }
+
+    @Override
+    public void bindDeepShortcuts() {
+        final HashMap<ComponentKey, Integer> shortcutMapCopy;
+        synchronized (mBgDataModel) {
+            shortcutMapCopy = new HashMap<>(mBgDataModel.deepShortcutMap);
+        }
+        executeCallbacksTask(c -> c.bindDeepShortcutMap(shortcutMapCopy), mUiExecutor);
+    }
+
+    @Override
+    public void bindWidgets() {
+        final ArrayList<WidgetListRowEntry> widgets =
+                mBgDataModel.widgetsModel.getWidgetsList(mApp.getContext());
+        executeCallbacksTask(c -> c.bindAllWidgets(widgets), mUiExecutor);
+    }
+}
diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
index 9a17ec6..7a7f828 100644
--- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
+++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java
@@ -69,7 +69,8 @@
         WidgetItemComparator widgetComparator = new WidgetItemComparator();
         for (Map.Entry<PackageItemInfo, ArrayList<WidgetItem>> entry : mWidgetsList.entrySet()) {
             WidgetListRowEntry row = new WidgetListRowEntry(entry.getKey(), entry.getValue());
-            row.titleSectionName = indexer.computeSectionName(row.pkgItem.title);
+            row.titleSectionName = (row.pkgItem.title == null) ? "" :
+                    indexer.computeSectionName(row.pkgItem.title);
             Collections.sort(row.widgets, widgetComparator);
             result.add(row);
         }
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index 0be5f11..ebab122 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -18,7 +18,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     package="com.android.launcher3.tests">
 
-    <uses-sdk android:targetSdkVersion="25" android:minSdkVersion="21"
+    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"
               tools:overrideLibrary="android.support.test.uiautomator.v18"/>
 
     <application android:debuggable="true">
diff --git a/tests/dummy_app/AndroidManifest.xml b/tests/dummy_app/AndroidManifest.xml
index 0546015..9d0a74a 100644
--- a/tests/dummy_app/AndroidManifest.xml
+++ b/tests/dummy_app/AndroidManifest.xml
@@ -21,7 +21,7 @@
      to come from a domain that you own or have control over. -->
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.android.aardwolf">
-    <uses-sdk android:targetSdkVersion="25" android:minSdkVersion="21"/>
+    <uses-sdk android:targetSdkVersion="28" android:minSdkVersion="21"/>
     <application android:label="Aardwolf">
         <activity
             android:name="Activity1"
diff --git a/tests/src/com/android/launcher3/model/LoaderCursorTest.java b/tests/src/com/android/launcher3/model/LoaderCursorTest.java
index ac1be17..df935b8 100644
--- a/tests/src/com/android/launcher3/model/LoaderCursorTest.java
+++ b/tests/src/com/android/launcher3/model/LoaderCursorTest.java
@@ -18,16 +18,12 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.icons.BitmapInfo;
-import com.android.launcher3.util.IntArray;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import static com.android.launcher3.LauncherSettings.BaseLauncherColumns.INTENT;
+import static com.android.launcher3.LauncherSettings.Favorites.INTENT;
 import static com.android.launcher3.LauncherSettings.Favorites.CELLX;
 import static com.android.launcher3.LauncherSettings.Favorites.CELLY;
 import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER;
@@ -149,80 +145,56 @@
     }
 
     @Test
-    public void checkItemPlacement_wrongWorkspaceScreen() {
-        IntArray workspaceScreens = IntArray.wrap(1, 3);
-        mIDP.numRows = 4;
-        mIDP.numColumns = 4;
-        mIDP.numHotseatIcons = 3;
-
-        // Item on unknown screen are not placed
-        assertFalse(mLoaderCursor.checkItemPlacement(
-                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 4), workspaceScreens));
-        assertFalse(mLoaderCursor.checkItemPlacement(
-                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 5), workspaceScreens));
-        assertFalse(mLoaderCursor.checkItemPlacement(
-                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 2), workspaceScreens));
-
-        assertTrue(mLoaderCursor.checkItemPlacement(
-                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 1), workspaceScreens));
-        assertTrue(mLoaderCursor.checkItemPlacement(
-                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 3), workspaceScreens));
-
-    }
-    @Test
     public void checkItemPlacement_outsideBounds() {
-        IntArray workspaceScreens = IntArray.wrap(1, 2);
         mIDP.numRows = 4;
         mIDP.numColumns = 4;
         mIDP.numHotseatIcons = 3;
 
         // Item outside screen bounds are not placed
         assertFalse(mLoaderCursor.checkItemPlacement(
-                newItemInfo(4, 4, 1, 1, CONTAINER_DESKTOP, 1), workspaceScreens));
+                newItemInfo(4, 4, 1, 1, CONTAINER_DESKTOP, 1)));
     }
 
     @Test
     public void checkItemPlacement_overlappingItems() {
-        IntArray workspaceScreens = IntArray.wrap(1, 2);
         mIDP.numRows = 4;
         mIDP.numColumns = 4;
         mIDP.numHotseatIcons = 3;
 
         // Overlapping items are not placed
         assertTrue(mLoaderCursor.checkItemPlacement(
-                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 1), workspaceScreens));
+                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 1)));
         assertFalse(mLoaderCursor.checkItemPlacement(
-                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 1), workspaceScreens));
+                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 1)));
 
         assertTrue(mLoaderCursor.checkItemPlacement(
-                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 2), workspaceScreens));
+                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 2)));
         assertFalse(mLoaderCursor.checkItemPlacement(
-                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 2), workspaceScreens));
+                newItemInfo(0, 0, 1, 1, CONTAINER_DESKTOP, 2)));
 
         assertTrue(mLoaderCursor.checkItemPlacement(
-                newItemInfo(1, 1, 1, 1, CONTAINER_DESKTOP, 1), workspaceScreens));
+                newItemInfo(1, 1, 1, 1, CONTAINER_DESKTOP, 1)));
         assertTrue(mLoaderCursor.checkItemPlacement(
-                newItemInfo(2, 2, 2, 2, CONTAINER_DESKTOP, 1), workspaceScreens));
+                newItemInfo(2, 2, 2, 2, CONTAINER_DESKTOP, 1)));
 
         assertFalse(mLoaderCursor.checkItemPlacement(
-                newItemInfo(3, 2, 1, 2, CONTAINER_DESKTOP, 1), workspaceScreens));
+                newItemInfo(3, 2, 1, 2, CONTAINER_DESKTOP, 1)));
     }
 
     @Test
     public void checkItemPlacement_hotseat() {
-        IntArray workspaceScreens = new IntArray();
         mIDP.numRows = 4;
         mIDP.numColumns = 4;
         mIDP.numHotseatIcons = 3;
 
         // Hotseat items are only placed based on screenId
         assertTrue(mLoaderCursor.checkItemPlacement(
-                newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 1), workspaceScreens));
+                newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 1)));
         assertTrue(mLoaderCursor.checkItemPlacement(
-                newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 2), workspaceScreens));
+                newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 2)));
 
         assertFalse(mLoaderCursor.checkItemPlacement(
-                newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 3), workspaceScreens));
+                newItemInfo(3, 3, 1, 1, CONTAINER_HOTSEAT, 3)));
     }
 
     private ItemInfo newItemInfo(int cellX, int cellY, int spanX, int spanY,
diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index bc5aaee..1b34598 100644
--- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -17,6 +17,7 @@
 
 import static androidx.test.InstrumentationRegistry.getInstrumentation;
 
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 import android.app.Instrumentation;
@@ -25,11 +26,13 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.LauncherActivityInfo;
+import android.content.pm.PackageManager;
 import android.os.Process;
 import android.os.RemoteException;
 import android.view.Surface;
 
 import androidx.test.InstrumentationRegistry;
+import androidx.test.uiautomator.By;
 import androidx.test.uiautomator.BySelector;
 import androidx.test.uiautomator.Direction;
 import androidx.test.uiautomator.UiDevice;
@@ -77,6 +80,7 @@
 
     public static final long SHORT_UI_TIMEOUT= 300;
     public static final long DEFAULT_UI_TIMEOUT = 10000;
+    protected static final int LONG_WAIT_TIME_MS = 60000;
 
     protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
     protected final UiDevice mDevice;
@@ -119,7 +123,7 @@
                 public void evaluate() throws Throwable {
                     try {
                         // Create launcher activity if necessary and bring it to the front.
-                        mDevice.pressHome();
+                        mLauncher.pressHome();
                         waitForLauncherCondition("Launcher activity wasn't created",
                                 launcher -> launcher != null);
 
@@ -325,4 +329,33 @@
             return intent == null ? null : (Intent) intent.getParcelableExtra(Intent.EXTRA_INTENT);
         }
     }
+
+    protected void startAppFast(String packageName) {
+        final Instrumentation instrumentation = getInstrumentation();
+        final Intent intent = instrumentation.getContext().getPackageManager().
+                getLaunchIntentForPackage(packageName);
+        intent.addCategory(Intent.CATEGORY_LAUNCHER);
+        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        instrumentation.getTargetContext().startActivity(intent);
+        assertTrue(packageName + " didn't start",
+                mDevice.wait(Until.hasObject(By.pkg(packageName).depth(0)), LONG_WAIT_TIME_MS));
+    }
+
+    protected String resolveSystemApp(String category) {
+        return getInstrumentation().getContext().getPackageManager().resolveActivity(
+                new Intent(Intent.ACTION_MAIN).addCategory(category),
+                PackageManager.MATCH_SYSTEM_ONLY).
+                activityInfo.packageName;
+    }
+
+    protected void closeLauncherActivity() {
+        // Destroy Launcher activity.
+        executeOnLauncher(launcher -> {
+            if (launcher != null) {
+                launcher.finish();
+            }
+        });
+        waitForLauncherCondition(
+                "Launcher still active", launcher -> launcher == null, DEFAULT_UI_TIMEOUT);
+    }
 }
diff --git a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
index 9354862..fdf87be 100644
--- a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
+++ b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
@@ -21,14 +21,12 @@
         LauncherActivityInfo settingsApp = getSettingsApp();
 
         clearHomescreen();
-        mDevice.pressHome();
-        mDevice.waitForIdle();
 
         final String appName = settingsApp.getLabel().toString();
         // 1. Open all apps and wait for load complete.
         // 2. Drag icon to homescreen.
         // 3. Verify that the icon works on homescreen.
-        mLauncher.getWorkspace().
+        mLauncher.pressHome().
                 switchToAllApps().
                 getAppIcon(appName).
                 dragToWorkspace().
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index 22bc05c..8b8e436 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -297,10 +297,6 @@
         if (screenId > Workspace.FIRST_SCREEN_ID) {
             screenId = Workspace.FIRST_SCREEN_ID;
         }
-        ContentValues v = new ContentValues();
-        v.put(LauncherSettings.WorkspaceScreens._ID, screenId);
-        v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, 0);
-        mResolver.insert(LauncherSettings.WorkspaceScreens.CONTENT_URI, v);
 
         // Insert the item
         ContentWriter writer = new ContentWriter(mTargetContext);
diff --git a/tests/src/com/android/launcher3/util/IntSetTest.java b/tests/src/com/android/launcher3/util/IntSetTest.java
deleted file mode 100644
index 934b749..0000000
--- a/tests/src/com/android/launcher3/util/IntSetTest.java
+++ /dev/null
@@ -1,58 +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.util;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-/**
- * Unit tests for {@link IntSet}
- */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class IntSetTest {
-
-    @Test
-    public void testDuplicateEntries() {
-        IntSet set = new IntSet();
-
-        set.add(2);
-        assertEquals(1, set.size());
-
-        set.add(2);
-        assertEquals(1, set.size());
-        assertTrue(set.contains(2));
-        assertFalse(set.contains(1));
-
-        set.add(1);
-        assertEquals(2, set.size());
-        assertTrue(set.contains(2));
-        assertTrue(set.contains(1));
-
-
-        set.add(10);
-        assertEquals(3, set.size());
-
-        assertEquals("1, 2, 10", set.mArray.toConcatString());
-    }
-}
diff --git a/tests/src/com/android/launcher3/util/RaceConditionReproducer.java b/tests/src/com/android/launcher3/util/RaceConditionReproducer.java
new file mode 100644
index 0000000..0235f95
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/RaceConditionReproducer.java
@@ -0,0 +1,488 @@
+/*
+ * 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 static com.android.launcher3.util.RaceConditionTracker.ENTER_POSTFIX;
+import static com.android.launcher3.util.RaceConditionTracker.EXIT_POSTFIX;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Event processor for reliably reproducing multithreaded apps race conditions in tests.
+ *
+ * The app notifies us about “events” that happen in its threads. The race condition test runs the
+ * test action multiple times (aka iterations), trying to generate all possible permutations of
+ * these events. It keeps a set of all seen event sequences and steers the execution towards
+ * executing events in previously unseen order. It does it by postponing execution of threads that
+ * would lead to an already seen sequence.
+ *
+ * If an event A occurs before event B in the sequence, this is how execution order looks like:
+ * Events: ... A ... B ...
+ * Events and instructions, guaranteed order:
+ * (instructions executed prior to A) A ... B (instructions executed after B)
+ *
+ * Each iteration has 3 parts (phases).
+ * Phase 1. Picking a previously seen event subsequence that we believe can have previously unseen
+ * continuations. Reproducing this sequence by pausing threads that would lead to other sequences.
+ * Phase 2. Trying to generate previously unseen continuation of the sequence from Phase 1. We need
+ * one new event after that sequence. All threads leading to seen continuations will be postponed
+ * for some short period of time. The phase ends once the new event is registered, or after the
+ * period of time ends (in which case we declare that the sequence can’t have new continuations).
+ * Phase 3. Releasing all threads and letting the test iteration run till its end.
+ *
+ * The iterations end when all seen paths have been declared “uncontinuable”.
+ *
+ * When we register event XXX:enter, we hold all other events until we register XXX:exit.
+ */
+public class RaceConditionReproducer implements RaceConditionTracker.EventProcessor {
+    private static final String TAG = "RaceConditionReproducer";
+    private static final long SHORT_TIMEOUT_MS = 2000;
+    private static final long LONG_TIMEOUT_MS = 60000;
+    // Handler used to resume postponed events.
+    private static final Handler POSTPONED_EVENT_RESUME_HANDLER = createEventResumeHandler();
+
+    private static Handler createEventResumeHandler() {
+        final HandlerThread thread = new HandlerThread("RaceConditionEventResumer");
+        thread.start();
+        return new Handler(thread.getLooper());
+    }
+
+    /**
+     * Event in a particular sequence of events. A node in the prefix tree of all seen event
+     * sequences.
+     */
+    private class EventNode {
+        // Events that were seen just after this event.
+        private final Map<String, EventNode> mNextEvents = new HashMap<>();
+        // Whether we believe that further iterations will not be able to add more events to
+        // mNextEvents.
+        private boolean mStoppedAddingChildren = true;
+
+        private void debugDump(StringBuilder sb, int indent, String name) {
+            for (int i = 0; i < indent; ++i) sb.append('.');
+            sb.append(!mStoppedAddingChildren ? "+" : "-");
+            sb.append(" : ");
+            sb.append(name);
+            if (mLastRegisteredEvent == this) sb.append(" <");
+            sb.append('\n');
+
+            for (String key : mNextEvents.keySet()) {
+                mNextEvents.get(key).debugDump(sb, indent + 2, key);
+            }
+        }
+
+        /** Number of leaves in the subtree with this node as a root. */
+        private int numberOfLeafNodes() {
+            if (mNextEvents.isEmpty()) return 1;
+
+            int leaves = 0;
+            for (String event : mNextEvents.keySet()) {
+                leaves += mNextEvents.get(event).numberOfLeafNodes();
+            }
+            return leaves;
+        }
+
+        /**
+         * Whether we believe that further iterations will not be able add nodes to the subtree with
+         * this node as a root.
+         */
+        private boolean stoppedAddingChildrenToTree() {
+            if (!mStoppedAddingChildren) return false;
+
+            for (String event : mNextEvents.keySet()) {
+                if (!mNextEvents.get(event).stoppedAddingChildrenToTree()) return false;
+            }
+            return true;
+        }
+
+        /**
+         * In the subtree with this node as a root, tries finding a node where we may have a
+         * chance to add new children.
+         * If succeeds, returns true and fills 'path' with the sequence of events to that node;
+         * otherwise returns false.
+         */
+        private boolean populatePathToGrowthPoint(List<String> path) {
+            for (String event : mNextEvents.keySet()) {
+                if (mNextEvents.get(event).populatePathToGrowthPoint(path)) {
+                    path.add(0, event);
+                    return true;
+                }
+            }
+            if (!mStoppedAddingChildren) {
+                // Mark that we have finished adding children. It will remain true if no new
+                // children are added, or will be set to false upon adding a new child.
+                mStoppedAddingChildren = true;
+                return true;
+            }
+            return false;
+        }
+    }
+
+    // Starting point of all event sequences; the root of the prefix tree representation all
+    // sequences generated by test iterations. A test iteration can add nodes int it.
+    private EventNode mRoot = new EventNode();
+    // During a test iteration, the last event that was registered.
+    private EventNode mLastRegisteredEvent;
+    // Length of the current sequence of registered events for the current test iteration.
+    private int mRegisteredEventCount = 0;
+    // During the first part of a test iteration, we go to a specific node under mRoot by
+    // 'playing back' mSequenceToFollow. During this part, all events that don't belong to this
+    // sequence get postponed.
+    private List<String> mSequenceToFollow = new ArrayList<>();
+    // Collection of events that got postponed, with corresponding wait objects used to let them go.
+    private Map<String, Semaphore> mPostponedEvents = new HashMap<>();
+    // Callback to run by POSTPONED_EVENT_RESUME_HANDLER, used to let go of all currently
+    // postponed events.
+    private Runnable mResumeAllEventsCallback;
+    // String representation of the sequence of events registered so far for the current test
+    // iteration. After registering any event, we output it to the log. The last output before
+    // the test failure can be later played back to reliable reproduce the exact sequence of
+    // events that broke the test.
+    // Format: EV1|EV2|...\EVN
+    private StringBuilder mCurrentSequence;
+    // When not null, we are in a repro mode. We run only one test iteration, and are trying to
+    // reproduce the event sequence represented by this string. The format is same as for
+    // mCurrentSequence.
+    private final String mReproString;
+
+    /* Constructor for a normal test. */
+    public RaceConditionReproducer() {
+        mReproString = null;
+    }
+
+    /**
+     * Constructor for reliably reproducing a race condition failure. The developer should find in
+     * the log the latest "Repro sequence:" record and locally modify the test by passing that
+     * string to the constructor. Running the test will have only one iteration that will reliably
+     * "play back" that sequence.
+     */
+    public RaceConditionReproducer(String reproString) {
+        mReproString = reproString;
+    }
+
+    public RaceConditionReproducer(String... reproSequence) {
+        this(String.join("|", reproSequence));
+    }
+
+    public synchronized String getCurrentSequenceString() {
+        return mCurrentSequence.toString();
+    }
+
+    /**
+     * Starts a new test iteration. Events reported via RaceConditionTracker.onEvent before this
+     * call will be ignored.
+     */
+    public synchronized void startIteration() {
+        mLastRegisteredEvent = mRoot;
+        mRegisteredEventCount = 0;
+        mCurrentSequence = new StringBuilder();
+        Log.d(TAG, "Repro sequence: " + mCurrentSequence);
+        mSequenceToFollow = mReproString != null ?
+                parseReproString(mReproString) : generateSequenceToFollowLocked();
+        Log.e(TAG, "---- Start of iteration; state:\n" + dumpStateLocked());
+        checkIfCompletedSequenceToFollowLocked();
+        RaceConditionTracker.setEventProcessor(this);
+    }
+
+    /**
+     * Ends a new test iteration. Events reported via RaceConditionTracker.onEvent after this call
+     * will be ignored.
+     * Returns whether we need more iterations.
+     */
+    public synchronized boolean finishIteration() {
+        RaceConditionTracker.setEventProcessor(null);
+        runResumeAllEventsCallbackLocked();
+        assertTrue("Non-empty postponed events", mPostponedEvents.isEmpty());
+        assertTrue("Last registered event is :enter", lastEventAsEnter() == null);
+
+        // No events came after mLastRegisteredEvent. It doesn't make sense to come to it again
+        // because we won't see new continuations.
+        mLastRegisteredEvent.mStoppedAddingChildren = true;
+        Log.e(TAG, "---- End of iteration; state:\n" + dumpStateLocked());
+        if (mReproString != null) {
+            assertTrue("Repro mode: failed to reproduce the sequence",
+                    mCurrentSequence.toString().startsWith(mReproString));
+        }
+        // If we are in a repro mode, we need only one iteration. Otherwise, continue if the tree
+        // has prospective growth points.
+        return mReproString == null && !mRoot.stoppedAddingChildrenToTree();
+    }
+
+    private static List<String> parseReproString(String reproString) {
+        return Arrays.asList(reproString.split("\\|"));
+    }
+
+    /**
+     * Called when the app issues an event.
+     */
+    @Override
+    public void onEvent(String event) {
+        final Semaphore waitObject = tryRegisterEvent(event);
+        if (waitObject != null) {
+            waitUntilCanRegister(event, waitObject);
+        }
+    }
+
+    /**
+     * Returns whether the last event was not an XXX:enter, or this event is a matching XXX:exit.
+     */
+    private boolean canRegisterEventNowLocked(String event) {
+        final String lastEventAsEnter = lastEventAsEnter();
+        final String thisEventAsExit = eventAsExit(event);
+
+        if (lastEventAsEnter != null) {
+            if (!lastEventAsEnter.equals(thisEventAsExit)) {
+                assertTrue("YYY:exit after XXX:enter", thisEventAsExit == null);
+                // Last event was :enter, but this event is not :exit.
+                return false;
+            }
+        } else {
+            // Previous event was not :enter.
+            assertTrue(":exit after a non-enter event", thisEventAsExit == null);
+        }
+        return true;
+    }
+
+    /**
+     * Registers an event issued by the app and returns null or decides that the event must be
+     * postponed, and returns an object to wait on.
+     */
+    private synchronized Semaphore tryRegisterEvent(String event) {
+        Log.d(TAG, "Event issued by the app: " + event);
+
+        if (!canRegisterEventNowLocked(event)) {
+            return createWaitObjectForPostponedEventLocked(event);
+        }
+
+        if (mRegisteredEventCount < mSequenceToFollow.size()) {
+            // We are in the first part of the iteration. We only register events that follow the
+            // mSequenceToFollow and postponing all other events.
+            if (event.equals(mSequenceToFollow.get(mRegisteredEventCount))) {
+                // The event is the next one expected in the sequence. Register it.
+                registerEventLocked(event);
+
+                // If there are postponed events that could continue the sequence, register them.
+                while (mRegisteredEventCount < mSequenceToFollow.size() &&
+                        mPostponedEvents.containsKey(
+                                mSequenceToFollow.get(mRegisteredEventCount))) {
+                    registerPostponedEventLocked(mSequenceToFollow.get(mRegisteredEventCount));
+                }
+
+                // Perhaps we just completed the required sequence...
+                checkIfCompletedSequenceToFollowLocked();
+            } else {
+                // The event is not the next one in the sequence. Postpone it.
+                return createWaitObjectForPostponedEventLocked(event);
+            }
+        } else if (mRegisteredEventCount == mSequenceToFollow.size()) {
+            // The second phase of the iteration. We have just registered the whole
+            // mSequenceToFollow, and want to add previously not seen continuations for the last
+            // node in the sequence aka 'growth point'.
+            if (!mLastRegisteredEvent.mNextEvents.containsKey(event) || mReproString != null) {
+                // The event was never seen as a continuation for the current node.
+                // Or we are in repro mode, in which case we are not in business of generating
+                // new sequences after we've played back the required sequence.
+                // Register it immediately.
+                registerEventLocked(event);
+            } else {
+                // The event was seen as a continuation for the current node. Postpone it, hoping
+                // that a new event will come from other threads.
+                return createWaitObjectForPostponedEventLocked(event);
+            }
+        } else {
+            // The third phase of the iteration. We are past the growth point and register
+            // everything that comes.
+            registerEventLocked(event);
+            // Register events that may have been postponed while waiting for an :exit event
+            // during the third phase. We don't do this if just registered event is :enter.
+            if (eventAsEnter(event) == null && mRegisteredEventCount > mSequenceToFollow.size()) {
+                registerPostponedEventsLocked(new HashSet<>(mPostponedEvents.keySet()));
+            }
+        }
+        return null;
+    }
+
+    /** Called when there are chances that we just have registered the whole mSequenceToFollow. */
+    private void checkIfCompletedSequenceToFollowLocked() {
+        if (mRegisteredEventCount == mSequenceToFollow.size()) {
+            // We just entered the second phase of the iteration. We have just registered the
+            // whole mSequenceToFollow, and want to add previously not seen continuations for the
+            // last node in the sequence aka 'growth point'. All seen continuations will be
+            // postponed for SHORT_TIMEOUT_MS. At the end of this time period, we'll let them go.
+            scheduleResumeAllEventsLocked();
+
+            // Among the events that were postponed during the first stage, there may be an event
+            // that wasn't seen after the current. If so, register it immediately because this
+            // creates a new sequence.
+            final Set<String> keys = new HashSet<>(mPostponedEvents.keySet());
+            keys.removeAll(mLastRegisteredEvent.mNextEvents.keySet());
+            if (!keys.isEmpty()) {
+                registerPostponedEventLocked(keys.iterator().next());
+            }
+        }
+    }
+
+    private Semaphore createWaitObjectForPostponedEventLocked(String event) {
+        final Semaphore waitObject = new Semaphore(0);
+        assertTrue("Event already postponed: " + event, !mPostponedEvents.containsKey(event));
+        mPostponedEvents.put(event, waitObject);
+        return waitObject;
+    }
+
+    private void waitUntilCanRegister(String event, Semaphore waitObject) {
+        try {
+            assertTrue("Never registered event: " + event,
+                    waitObject.tryAcquire(LONG_TIMEOUT_MS, TimeUnit.MILLISECONDS));
+        } catch (InterruptedException e) {
+            fail("Wait was interrupted");
+        }
+    }
+
+    /** Schedules resuming all postponed events after SHORT_TIMEOUT_MS */
+    private void scheduleResumeAllEventsLocked() {
+        assertTrue(mResumeAllEventsCallback == null);
+        mResumeAllEventsCallback = this::allEventsResumeCallback;
+        POSTPONED_EVENT_RESUME_HANDLER.postDelayed(mResumeAllEventsCallback, SHORT_TIMEOUT_MS);
+    }
+
+    private synchronized void allEventsResumeCallback() {
+        assertTrue("In callback, but callback is not set", mResumeAllEventsCallback != null);
+        mResumeAllEventsCallback = null;
+        registerPostponedEventsLocked(new HashSet<>(mPostponedEvents.keySet()));
+    }
+
+    private void registerPostponedEventsLocked(Collection<String> events) {
+        for (String event : events) {
+            registerPostponedEventLocked(event);
+            if (eventAsEnter(event) != null) {
+                // Once :enter is registered, switch to waiting for :exit to come. Won't register
+                // other postponed events.
+                break;
+            }
+        }
+    }
+
+    private void registerPostponedEventLocked(String event) {
+        mPostponedEvents.remove(event).release();
+        registerEventLocked(event);
+    }
+
+    /**
+     * If the last registered event was XXX:enter, returns XXX, otherwise, null.
+     */
+    private String lastEventAsEnter() {
+        return eventAsEnter(mCurrentSequence.substring(mCurrentSequence.lastIndexOf("|") + 1));
+    }
+
+    /**
+     * If the event is XXX:postfix, returns XXX, otherwise, null.
+     */
+    private static String prefixFromPostfixedEvent(String event, String postfix) {
+        final int columnPos = event.indexOf(':');
+        if (columnPos != -1 && postfix.equals(event.substring(columnPos + 1))) {
+            return event.substring(0, columnPos);
+        }
+        return null;
+    }
+
+    /**
+     * If the event is XXX:enter, returns XXX, otherwise, null.
+     */
+    private static String eventAsEnter(String event) {
+        return prefixFromPostfixedEvent(event, ENTER_POSTFIX);
+    }
+
+    /**
+     * If the event is XXX:exit, returns XXX, otherwise, null.
+     */
+    private static String eventAsExit(String event) {
+        return prefixFromPostfixedEvent(event, EXIT_POSTFIX);
+    }
+
+    private void registerEventLocked(String event) {
+        assertTrue(canRegisterEventNowLocked(event));
+
+        Log.d(TAG, "Actually registering event: " + event);
+        EventNode next = mLastRegisteredEvent.mNextEvents.get(event);
+        if (next == null) {
+            // This event wasn't seen after mLastRegisteredEvent.
+            next = new EventNode();
+            mLastRegisteredEvent.mNextEvents.put(event, next);
+            // The fact that we've added a new event after the previous one means that the
+            // previous event is still a growth point, unless this event is :exit, which means
+            // that the previous event is :enter.
+            mLastRegisteredEvent.mStoppedAddingChildren = eventAsExit(event) != null;
+        }
+
+        mLastRegisteredEvent = next;
+        mRegisteredEventCount++;
+
+        if (mCurrentSequence.length() > 0) mCurrentSequence.append("|");
+        mCurrentSequence.append(event);
+        Log.d(TAG, "Repro sequence: " + mCurrentSequence);
+    }
+
+    private void runResumeAllEventsCallbackLocked() {
+        if (mResumeAllEventsCallback != null) {
+            POSTPONED_EVENT_RESUME_HANDLER.removeCallbacks(mResumeAllEventsCallback);
+            mResumeAllEventsCallback.run();
+        }
+    }
+
+    private CharSequence dumpStateLocked() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("Sequence to follow: ");
+        for (String event : mSequenceToFollow) sb.append(" " + event);
+        sb.append(".\n");
+        sb.append("Registered event count: " + mRegisteredEventCount);
+
+        sb.append("\nPostponed events: ");
+        for (String event : mPostponedEvents.keySet()) sb.append(" " + event);
+        sb.append(".");
+
+        sb.append("\nNodes: \n");
+        mRoot.debugDump(sb, 0, "");
+        return sb;
+    }
+
+    public int numberOfLeafNodes() {
+        return mRoot.numberOfLeafNodes();
+    }
+
+    private List<String> generateSequenceToFollowLocked() {
+        ArrayList<String> sequence = new ArrayList<>();
+        mRoot.populatePathToGrowthPoint(sequence);
+        return sequence;
+    }
+}
diff --git a/tests/src/com/android/launcher3/util/RaceConditionReproducerTest.java b/tests/src/com/android/launcher3/util/RaceConditionReproducerTest.java
new file mode 100644
index 0000000..3fc268e
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/RaceConditionReproducerTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import androidx.test.filters.LargeTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class RaceConditionReproducerTest {
+    private final static String SOME_VALID_SEQUENCE_3_3 = "B1|A1|A2|B2|A3|B3";
+
+    private static int factorial(int n) {
+        int res = 1;
+        for (int i = 2; i <= n; ++i) res *= i;
+        return res;
+    }
+
+    private static void run3_3_TestAction() throws InterruptedException {
+        Thread tb = new Thread(() -> {
+            RaceConditionTracker.onEvent("B1");
+            RaceConditionTracker.onEvent("B2");
+            RaceConditionTracker.onEvent("B3");
+        });
+        tb.start();
+
+        RaceConditionTracker.onEvent("A1");
+        RaceConditionTracker.onEvent("A2");
+        RaceConditionTracker.onEvent("A3");
+
+        tb.join();
+    }
+
+    @Test
+    @Ignore // The test is too long for continuous testing.
+    // 2 threads, 3 events each.
+    public void test3_3() throws Exception {
+        final RaceConditionReproducer eventProcessor = new RaceConditionReproducer();
+        boolean sawTheValidSequence = false;
+
+        for (; ; ) {
+            eventProcessor.startIteration();
+            run3_3_TestAction();
+            final boolean needMoreIterations = eventProcessor.finishIteration();
+
+            sawTheValidSequence = sawTheValidSequence ||
+                    SOME_VALID_SEQUENCE_3_3.equals(eventProcessor.getCurrentSequenceString());
+
+            if (!needMoreIterations) break;
+        }
+
+        assertEquals("Wrong number of leaf nodes",
+                factorial(3 + 3) / (factorial(3) * factorial(3)),
+                eventProcessor.numberOfLeafNodes());
+        assertTrue(sawTheValidSequence);
+    }
+
+    @Test
+    @Ignore // The test is too long for continuous testing.
+    // 2 threads, 3 events, including enter-exit pairs each.
+    public void test3_3_enter_exit() throws Exception {
+        final RaceConditionReproducer eventProcessor = new RaceConditionReproducer();
+        boolean sawTheValidSequence = false;
+
+        for (; ; ) {
+            eventProcessor.startIteration();
+            Thread tb = new Thread(() -> {
+                RaceConditionTracker.onEvent("B1:enter");
+                RaceConditionTracker.onEvent("B1:exit");
+                RaceConditionTracker.onEvent("B2");
+                RaceConditionTracker.onEvent("B3:enter");
+                RaceConditionTracker.onEvent("B3:exit");
+            });
+            tb.start();
+
+            RaceConditionTracker.onEvent("A1");
+            RaceConditionTracker.onEvent("A2:enter");
+            RaceConditionTracker.onEvent("A2:exit");
+            RaceConditionTracker.onEvent("A3:enter");
+            RaceConditionTracker.onEvent("A3:exit");
+
+            tb.join();
+            final boolean needMoreIterations = eventProcessor.finishIteration();
+
+            sawTheValidSequence = sawTheValidSequence ||
+                    "B1:enter|B1:exit|A1|A2:enter|A2:exit|B2|A3:enter|A3:exit|B3:enter|B3:exit".
+                            equals(eventProcessor.getCurrentSequenceString());
+
+            if (!needMoreIterations) break;
+        }
+
+        assertEquals("Wrong number of leaf nodes",
+                factorial(3 + 3) / (factorial(3) * factorial(3)),
+                eventProcessor.numberOfLeafNodes());
+        assertTrue(sawTheValidSequence);
+    }
+
+    @Test
+    // 2 threads, 3 events each; reproducing a particular event sequence.
+    public void test3_3_ReproMode() throws Exception {
+        final RaceConditionReproducer eventProcessor = new RaceConditionReproducer(
+                SOME_VALID_SEQUENCE_3_3);
+
+        eventProcessor.startIteration();
+        run3_3_TestAction();
+        assertTrue(!eventProcessor.finishIteration());
+        assertEquals(SOME_VALID_SEQUENCE_3_3, eventProcessor.getCurrentSequenceString());
+
+        assertEquals("Wrong number of leaf nodes", 1, eventProcessor.numberOfLeafNodes());
+    }
+
+    @Test
+    @Ignore // The test is too long for continuous testing.
+    // 2 threads with 2 events; 1 thread with 1 event.
+    public void test2_1_2() throws Exception {
+        final RaceConditionReproducer eventProcessor = new RaceConditionReproducer();
+
+        for (; ; ) {
+            eventProcessor.startIteration();
+            Thread tb = new Thread(() -> {
+                RaceConditionTracker.onEvent("B1");
+                RaceConditionTracker.onEvent("B2");
+            });
+            tb.start();
+
+            Thread tc = new Thread(() -> {
+                RaceConditionTracker.onEvent("C1");
+            });
+            tc.start();
+
+            RaceConditionTracker.onEvent("A1");
+            RaceConditionTracker.onEvent("A2");
+
+            tb.join();
+            tc.join();
+
+            if (!eventProcessor.finishIteration()) break;
+        }
+
+        assertEquals("Wrong number of leaf nodes",
+                factorial(2 + 2 + 1) / (factorial(2) * factorial(2) * factorial(1)),
+                eventProcessor.numberOfLeafNodes());
+    }
+
+    @Test
+    @Ignore // The test is too long for continuous testing.
+    // 2 threads with 2 events; 1 thread with 1 event. Includes enter-exit pairs.
+    public void test2_1_2_enter_exit() throws Exception {
+        final RaceConditionReproducer eventProcessor = new RaceConditionReproducer();
+
+        for (; ; ) {
+            eventProcessor.startIteration();
+            Thread tb = new Thread(() -> {
+                RaceConditionTracker.onEvent("B1:enter");
+                RaceConditionTracker.onEvent("B1:exit");
+                RaceConditionTracker.onEvent("B2:enter");
+                RaceConditionTracker.onEvent("B2:exit");
+            });
+            tb.start();
+
+            Thread tc = new Thread(() -> {
+                RaceConditionTracker.onEvent("C1:enter");
+                RaceConditionTracker.onEvent("C1:exit");
+            });
+            tc.start();
+
+            RaceConditionTracker.onEvent("A1:enter");
+            RaceConditionTracker.onEvent("A1:exit");
+            RaceConditionTracker.onEvent("A2:enter");
+            RaceConditionTracker.onEvent("A2:exit");
+
+            tb.join();
+            tc.join();
+
+            if (!eventProcessor.finishIteration()) break;
+        }
+
+        assertEquals("Wrong number of leaf nodes",
+                factorial(2 + 2 + 1) / (factorial(2) * factorial(2) * factorial(1)),
+                eventProcessor.numberOfLeafNodes());
+    }
+}
diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java
index 84fd908..82ea8be 100644
--- a/tests/tapl/com/android/launcher3/tapl/AllApps.java
+++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java
@@ -54,7 +54,7 @@
     @NonNull
     public AppIcon getAppIcon(String appName) {
         final UiObject2 allAppsContainer = verifyActiveContainer();
-        final BySelector appIconSelector = AppIcon.getAppIconSelector(appName);
+        final BySelector appIconSelector = AppIcon.getAppIconSelector(appName, mLauncher);
         if (!allAppsContainer.hasObject(appIconSelector)) {
             scrollBackToBeginning();
             int attempts = 0;
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIcon.java b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
index efefc0d..3ffd30c 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIcon.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIcon.java
@@ -31,8 +31,8 @@
         super(launcher, icon);
     }
 
-    static BySelector getAppIconSelector(String appName) {
-        return By.clazz(TextView.class).text(appName).pkg(LauncherInstrumentation.LAUNCHER_PKG);
+    static BySelector getAppIconSelector(String appName, LauncherInstrumentation launcher) {
+        return By.clazz(TextView.class).text(appName).pkg(launcher.getLauncherPackageName());
     }
 
     /**
diff --git a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
index 2a03f9a..7f28151 100644
--- a/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
+++ b/tests/tapl/com/android/launcher3/tapl/AppIconMenu.java
@@ -20,6 +20,8 @@
 
 import androidx.test.uiautomator.UiObject2;
 
+import java.util.List;
+
 /**
  * Context menu of an app icon.
  */
@@ -37,10 +39,9 @@
      * Returns a menu item with a given number. Fails if it doesn't exist.
      */
     public AppIconMenuItem getMenuItem(int itemNumber) {
-        assertTrue(mDeepShortcutsContainer.getChildCount() > itemNumber);
-
-        final UiObject2 shortcut = mLauncher.waitForObjectInContainer(
-                mDeepShortcutsContainer.getChildren().get(itemNumber), "bubble_text");
-        return new AppIconMenuItem(mLauncher, shortcut);
+        final List<UiObject2> menuItems = mLauncher.getObjectsInContainer(mDeepShortcutsContainer,
+                "bubble_text");
+        assertTrue(menuItems.size() > itemNumber);
+        return new AppIconMenuItem(mLauncher, menuItems.get(itemNumber));
     }
 }
diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java
index 27e0954..08d2889 100644
--- a/tests/tapl/com/android/launcher3/tapl/Background.java
+++ b/tests/tapl/com/android/launcher3/tapl/Background.java
@@ -64,7 +64,7 @@
 
             mLauncher.swipe(
                     navBar.getVisibleBounds().centerX(), navBar.getVisibleBounds().centerY(),
-                    navBar.getVisibleBounds().centerX(), height - 300);
+                    navBar.getVisibleBounds().centerX(), height - 400);
         } else {
             mLauncher.getSystemUiObject("recent_apps").click();
         }
diff --git a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
index 4fce211..5f60113 100644
--- a/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
+++ b/tests/tapl/com/android/launcher3/tapl/BaseOverview.java
@@ -16,13 +16,13 @@
 
 package com.android.launcher3.tapl;
 
-import java.util.Collections;
-import java.util.List;
-
 import androidx.annotation.NonNull;
 import androidx.test.uiautomator.Direction;
 import androidx.test.uiautomator.UiObject2;
 
+import java.util.Collections;
+import java.util.List;
+
 /**
  * Common overview pane for both Launcher and fallback recents
  */
@@ -69,7 +69,7 @@
     public OverviewTask getCurrentTask() {
         verifyActiveContainer();
         final List<UiObject2> taskViews = mLauncher.getDevice().findObjects(
-                LauncherInstrumentation.getLauncherObjectSelector("snapshot"));
+                mLauncher.getLauncherObjectSelector("snapshot"));
         LauncherInstrumentation.assertNotEquals("Unable to find a task", 0, taskViews.size());
 
         // taskViews contains up to 3 task views: the 'main' (having the widest visible
diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
index 67106f7..49bd73a 100644
--- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
+++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java
@@ -41,6 +41,7 @@
 import org.junit.Assert;
 
 import java.lang.ref.WeakReference;
+import java.util.List;
 import java.util.concurrent.TimeoutException;
 
 /**
@@ -83,7 +84,6 @@
     private static final String APPS_RES_ID = "apps_view";
     private static final String OVERVIEW_RES_ID = "overview_panel";
     private static final String WIDGETS_RES_ID = "widgets_list_view";
-    static final String LAUNCHER_PKG = "com.google.android.apps.nexuslauncher";
     public static final int WAIT_TIME_MS = 60000;
     private static final String SYSTEMUI_PACKAGE = "com.android.systemui";
 
@@ -177,7 +177,7 @@
 
         switch (containerType) {
             case WORKSPACE: {
-                waitUntilGone(APPS_RES_ID);
+                waitForLauncherObject(APPS_RES_ID);
                 waitUntilGone(OVERVIEW_RES_ID);
                 waitUntilGone(WIDGETS_RES_ID);
                 return waitForLauncherObject(WORKSPACE_RES_ID);
@@ -368,6 +368,11 @@
     }
 
     @NonNull
+    List<UiObject2> getObjectsInContainer(UiObject2 container, String resName) {
+        return container.findObjects(getLauncherObjectSelector(resName));
+    }
+
+    @NonNull
     UiObject2 waitForObjectInContainer(UiObject2 container, String resName) {
         final UiObject2 object = container.wait(
                 Until.findObject(getLauncherObjectSelector(resName)),
@@ -379,14 +384,18 @@
 
     @NonNull
     UiObject2 waitForLauncherObject(String resName) {
-        final UiObject2 object = mDevice.wait(Until.findObject(getLauncherObjectSelector(resName)),
-                WAIT_TIME_MS);
-        assertNotNull("Can't find a launcher object; id: " + resName, object);
+        final BySelector selector = getLauncherObjectSelector(resName);
+        final UiObject2 object = mDevice.wait(Until.findObject(selector), WAIT_TIME_MS);
+        assertNotNull("Can't find a launcher object; selector: " + selector, object);
         return object;
     }
 
-    static BySelector getLauncherObjectSelector(String resName) {
-        return By.res(LAUNCHER_PKG, resName);
+    BySelector getLauncherObjectSelector(String resName) {
+        return By.res(getLauncherPackageName(), resName);
+    }
+
+    String getLauncherPackageName() {
+        return mDevice.getLauncherPackageName();
     }
 
     @NonNull
diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java
index c63822e..5e6ad4d 100644
--- a/tests/tapl/com/android/launcher3/tapl/Workspace.java
+++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java
@@ -46,28 +46,16 @@
     @NonNull
     public AllApps switchToAllApps() {
         verifyActiveContainer();
-        if (mLauncher.isSwipeUpEnabled()) {
-            int midX = mLauncher.getDevice().getDisplayWidth() / 2;
-            int height = mLauncher.getDevice().getDisplayHeight();
-            // Swipe from 6/7ths down the screen to 1/7th down the screen.
-            mLauncher.swipe(
-                    midX,
-                    height * 6 / 7,
-                    midX,
-                    height / 7
-            );
-        } else {
-            // Swipe from the hotseat to near the top, e.g. 10% of the screen.
-            final UiObject2 hotseat = mHotseat;
-            final Point start = hotseat.getVisibleCenter();
-            final int endY = (int) (mLauncher.getDevice().getDisplayHeight() * 0.1f);
-            mLauncher.swipe(
-                    start.x,
-                    start.y,
-                    start.x,
-                    endY
-            );
-        }
+        // Swipe from the hotseat to near the top, e.g. 10% of the screen.
+        final UiObject2 hotseat = mHotseat;
+        final Point start = hotseat.getVisibleCenter();
+        final int endY = (int) (mLauncher.getDevice().getDisplayHeight() * 0.1f);
+        mLauncher.swipe(
+                start.x,
+                start.y,
+                start.x,
+                endY
+        );
 
         return new AllApps(mLauncher);
     }
@@ -81,7 +69,7 @@
     @Nullable
     public AppIcon tryGetWorkspaceAppIcon(String appName) {
         final UiObject2 workspace = verifyActiveContainer();
-        final UiObject2 icon = workspace.findObject(AppIcon.getAppIconSelector(appName));
+        final UiObject2 icon = workspace.findObject(AppIcon.getAppIconSelector(appName, mLauncher));
         return icon != null ? new AppIcon(mLauncher, icon) : null;
     }
 
@@ -97,7 +85,7 @@
         return new AppIcon(mLauncher,
                 mLauncher.getObjectInContainer(
                         verifyActiveContainer(),
-                        AppIcon.getAppIconSelector(appName)));
+                        AppIcon.getAppIconSelector(appName, mLauncher)));
     }
 
     /**
@@ -120,7 +108,7 @@
     @NonNull
     private AppIcon getHotseatAppIcon(String appName) {
         return new AppIcon(mLauncher, mLauncher.getObjectInContainer(
-                mHotseat, AppIcon.getAppIconSelector(appName)));
+                mHotseat, AppIcon.getAppIconSelector(appName, mLauncher)));
     }
 
     private void dragIconToNextScreen(AppIcon app, UiObject2 workspace) {