resolve merge conflicts of 5cc7bbdbb to ub-launcher3-dorval-polish

Test: I solemnly swear I tested this conflict resolution.
Change-Id: If3359341d5269f2c908b3a8856b6f38ba69a05eb
diff --git a/Android.mk b/Android.mk
index 713d082..c8a53d2 100644
--- a/Android.mk
+++ b/Android.mk
@@ -26,11 +26,13 @@
 LOCAL_STATIC_JAVA_LIBRARIES := \
     android-support-v4 \
     android-support-v7-recyclerview \
-    android-support-v7-palette
+    android-support-v7-palette \
+    android-support-dynamic-animation
 
 LOCAL_SRC_FILES := \
     $(call all-java-files-under, src) \
     $(call all-java-files-under, src_config) \
+    $(call all-java-files-under, src_flags) \
     $(call all-proto-files-under, protos)
 
 LOCAL_RESOURCE_DIR := \
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index ab582fe..ad404c0 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -86,6 +86,12 @@
             android:permission="android.permission.BIND_JOB_SERVICE">
         </service>
 
+        <service
+            android:name="com.android.launcher3.compat.WallpaperManagerCompatVL$ColorExtractionService"
+            android:exported="false"
+            android:process=":wallpaper_chooser"
+            android:permission="android.permission.BIND_JOB_SERVICE" />
+
         <service android:name="com.android.launcher3.notification.NotificationListener"
                  android:enabled="@bool/notification_badging_enabled"
                  android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
diff --git a/build.gradle b/build.gradle
index 9c71693..ef782d9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -39,7 +39,7 @@
     sourceSets {
         main {
             res.srcDirs = ['res']
-            java.srcDirs = ['src', 'src_config']
+            java.srcDirs = ['src', 'src_flags']
             manifest.srcFile 'AndroidManifest-common.xml'
             proto.srcDirs 'protos/'
         }
@@ -92,6 +92,7 @@
                     remove java
                     javanano {
                         option "java_package=launcher_log.proto|com.android.launcher3.userevent.nano"
+                        option "java_package=launcher_dump.proto|com.android.launcher3.model.nano"
                         option "enum_style=java"
                     }
                 }
diff --git a/proguard.flags b/proguard.flags
index 8ee6ccd..51abcca 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -82,6 +82,10 @@
   *;
 }
 
+-keep class com.android.launcher3.graphics.ShadowDrawable {
+  public <init>(...);
+}
+
 # Proguard will strip methods required for talkback to properly scroll to
 # next row when focus is on the last item of last row when using a RecyclerView
 # Keep optimized and shrunk proguard to prevent issues like this when using
diff --git a/res/color-v24/all_apps_bg_hand_fill.xml b/res/color-v24/all_apps_bg_hand_fill.xml
new file mode 100644
index 0000000..1b0b538
--- /dev/null
+++ b/res/color-v24/all_apps_bg_hand_fill.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<gradient
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:startX="158.5"
+    android:startY="141.5"
+    android:endX="196.0"
+    android:endY="206.5"
+    android:type="linear" >
+    <item android:offset="0" android:color="#E1E1E1" />
+    <item android:offset="0.3317" android:color="#E1E1E1" />
+    <item android:offset="0.493" android:color="#C1E5E5E5" />
+    <item android:offset="1" android:color="#00EEEEEE" />
+</gradient>
\ No newline at end of file
diff --git a/res/drawable-hdpi/ic_all_apps_bg_hand.png b/res/drawable-hdpi/ic_all_apps_bg_hand.png
deleted file mode 100644
index 437fd37..0000000
--- a/res/drawable-hdpi/ic_all_apps_bg_hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_info_launcher.png b/res/drawable-hdpi/ic_info_launcher.png
deleted file mode 100644
index 11162e1..0000000
--- a/res/drawable-hdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_remove_launcher.png b/res/drawable-hdpi/ic_remove_launcher.png
deleted file mode 100644
index ad2b9af..0000000
--- a/res/drawable-hdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_uninstall_launcher.png b/res/drawable-hdpi/ic_uninstall_launcher.png
deleted file mode 100644
index 426683c..0000000
--- a/res/drawable-hdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_all_apps_bg_hand.png b/res/drawable-mdpi/ic_all_apps_bg_hand.png
deleted file mode 100644
index 0a00241..0000000
--- a/res/drawable-mdpi/ic_all_apps_bg_hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_info_launcher.png b/res/drawable-mdpi/ic_info_launcher.png
deleted file mode 100644
index 6fbe5e3..0000000
--- a/res/drawable-mdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_remove_launcher.png b/res/drawable-mdpi/ic_remove_launcher.png
deleted file mode 100644
index 2bb281d..0000000
--- a/res/drawable-mdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_uninstall_launcher.png b/res/drawable-mdpi/ic_uninstall_launcher.png
deleted file mode 100644
index bfcbc6df..0000000
--- a/res/drawable-mdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/bg_white_round_rect.xml b/res/drawable-v24/ic_info_shadow.xml
similarity index 69%
rename from res/drawable/bg_white_round_rect.xml
rename to res/drawable-v24/ic_info_shadow.xml
index c7f786f..1fe2c46 100644
--- a/res/drawable/bg_white_round_rect.xml
+++ b/res/drawable-v24/ic_info_shadow.xml
@@ -5,7 +5,7 @@
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
 
-          http://www.apache.org/licenses/LICENSE-2.0
+        http://www.apache.org/licenses/LICENSE-2.0
 
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,9 +13,7 @@
      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="#FFFFFF" />
-    <corners android:radius="@dimen/bg_round_rect_radius" />
-</shape>
\ No newline at end of file
+<com.android.launcher3.graphics.ShadowDrawable
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:src="@drawable/ic_info_no_shadow"
+    android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/layout/qsb_blocker_view.xml b/res/drawable-v24/ic_remove_shadow.xml
similarity index 69%
rename from res/layout/qsb_blocker_view.xml
rename to res/drawable-v24/ic_remove_shadow.xml
index 453eebe..48abc10 100644
--- a/res/layout/qsb_blocker_view.xml
+++ b/res/drawable-v24/ic_remove_shadow.xml
@@ -1,12 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2016 The Android Open Source Project
+<!-- 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
+        http://www.apache.org/licenses/LICENSE-2.0
 
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.qsb.QsbBlockerView
+<com.android.launcher3.graphics.ShadowDrawable
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent" />
\ No newline at end of file
+    android:src="@drawable/ic_remove_no_shadow"
+    android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/layout/qsb_blocker_view.xml b/res/drawable-v24/ic_uninstall_shadow.xml
similarity index 69%
copy from res/layout/qsb_blocker_view.xml
copy to res/drawable-v24/ic_uninstall_shadow.xml
index 453eebe..b441b0e 100644
--- a/res/layout/qsb_blocker_view.xml
+++ b/res/drawable-v24/ic_uninstall_shadow.xml
@@ -1,12 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2016 The Android Open Source Project
+<!-- 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
+        http://www.apache.org/licenses/LICENSE-2.0
 
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +13,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.qsb.QsbBlockerView
+<com.android.launcher3.graphics.ShadowDrawable
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent" />
\ No newline at end of file
+    android:src="@drawable/ic_uninstall_no_shadow"
+    android:elevation="@dimen/drop_target_shadow_elevation" />
diff --git a/res/drawable-xhdpi/ic_all_apps_bg_hand.png b/res/drawable-xhdpi/ic_all_apps_bg_hand.png
deleted file mode 100644
index 1acb378..0000000
--- a/res/drawable-xhdpi/ic_all_apps_bg_hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_info_launcher.png b/res/drawable-xhdpi/ic_info_launcher.png
deleted file mode 100644
index 041f2b3..0000000
--- a/res/drawable-xhdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_remove_launcher.png b/res/drawable-xhdpi/ic_remove_launcher.png
deleted file mode 100644
index ff94eb8..0000000
--- a/res/drawable-xhdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_uninstall_launcher.png b/res/drawable-xhdpi/ic_uninstall_launcher.png
deleted file mode 100644
index 2c7ab56..0000000
--- a/res/drawable-xhdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/all_apps_alpha_mask.png b/res/drawable-xxhdpi/all_apps_alpha_mask.png
new file mode 100644
index 0000000..ed53ff9
--- /dev/null
+++ b/res/drawable-xxhdpi/all_apps_alpha_mask.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_all_apps_bg_hand.png b/res/drawable-xxhdpi/ic_all_apps_bg_hand.png
deleted file mode 100644
index 09c6c8d..0000000
--- a/res/drawable-xxhdpi/ic_all_apps_bg_hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_info_launcher.png b/res/drawable-xxhdpi/ic_info_launcher.png
deleted file mode 100644
index 8e602da..0000000
--- a/res/drawable-xxhdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_remove_launcher.png b/res/drawable-xxhdpi/ic_remove_launcher.png
deleted file mode 100644
index 78ca080..0000000
--- a/res/drawable-xxhdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_uninstall_launcher.png b/res/drawable-xxhdpi/ic_uninstall_launcher.png
deleted file mode 100644
index 43aba6e..0000000
--- a/res/drawable-xxhdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png b/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png
deleted file mode 100644
index 49c004d..0000000
--- a/res/drawable-xxxhdpi/ic_all_apps_bg_hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_info_launcher.png b/res/drawable-xxxhdpi/ic_info_launcher.png
deleted file mode 100644
index 3540de1..0000000
--- a/res/drawable-xxxhdpi/ic_info_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_remove_launcher.png b/res/drawable-xxxhdpi/ic_remove_launcher.png
deleted file mode 100644
index 418d81a..0000000
--- a/res/drawable-xxxhdpi/ic_remove_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxxhdpi/ic_uninstall_launcher.png b/res/drawable-xxxhdpi/ic_uninstall_launcher.png
deleted file mode 100644
index 724437a..0000000
--- a/res/drawable-xxxhdpi/ic_uninstall_launcher.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/ic_all_apps_bg_hand.xml b/res/drawable/ic_all_apps_bg_hand.xml
new file mode 100644
index 0000000..94af008
--- /dev/null
+++ b/res/drawable/ic_all_apps_bg_hand.xml
@@ -0,0 +1,100 @@
+<?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.
+-->
+
+<vector
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="208dp"
+    android:height="212dp"
+    android:viewportWidth="208.0"
+    android:viewportHeight="212.0">
+    <path
+        android:fillColor="#1A000000"
+        android:pathData="M89.4,61.8H85l-1.6-1.5c5.5-6.4,8.8-14.7,8.8-23.7C92.2,16.6,76,0.3,55.9,0.3
+        S19.5,16.6,19.5,36.6S35.8,73,55.9,73c9,0,17.3-3.3,23.7-8.8l1.5,1.6v4.4l40.5,40.4l8.3-8.3L89.4,61.8z M54,66.6
+        c-13.9,0-28.8-16-28.8-30S41.5,8.9,55.4,8.9S81,22.7,81,36.6S67.9,66.6,54,66.6z"/>
+    <path
+        android:fillColor="#1A000000"
+        android:pathData="M33.4,29.2l-0.3-1.8l-4.2-3.1L18.1,26l-3.1,4.2l0.3,1.8L4.5,33.7L9,62.5
+        c0.2,1.5,1.6,2.5,3.1,2.3l34.2-5.3c1.5-0.2,2.5-1.6,2.3-3.1l-4.4-28.8L33.4,29.2z"/>
+    <path
+        android:fillColor="#3367D6"
+        android:pathData="M30.2,27.9l-0.3-1.8l-4.1-3L15,24.7l-3,4.1l0.3,1.8L1.6,32.3L6,60.9
+        c0.2,1.5,1.6,2.5,3.1,2.3L43,57.9c1.5-0.2,2.5-1.6,2.3-3.1l-4.4-28.6L30.2,27.9z M26.6,28.4l-10.7,1.6l-0.3-1.8l10.7-1.6L26.6,28.4z"/>
+    <group>
+        <clip-path
+            android:pathData="M25.1,37.7a28.9,28.9 0 1,0 57.8,0a28.9,28.9 0 1,0 -57.8,0"/>
+        <path
+            android:fillColor="#4285F4"
+            android:pathData="M41.7,23l-0.3-2.1l-4.9-3.6l-12.6,1.9l-3.6,4.9l0.3,2.1L8.1,28.1l5.2,33.7
+                c0.3,1.7,1.9,2.9,3.6,2.7l40-6.1c1.7-0.3,2.9-1.9,2.7-3.6L54.4,21L41.7,23z M37.5,23.6l-12.6,1.9l-0.3-2.1l12.6-1.9L37.5,23.6z"/>
+    </group>
+    <path
+        android:fillColor="#BDBDBD"
+        android:pathData="M87.5,62.9h-4.4l-1.6-1.5c5.5-6.4,8.8-14.7,8.8-23.7C90.3,17.7,74,1.4,54,1.4
+        S17.6,17.7,17.6,37.7S33.9,74.1,54,74.1c9,0,17.3-3.3,23.7-8.8l1.5,1.6v4.4l40.5,40.4l8.3-8.3L87.5,62.9z M54,64.2
+        c-14.7,0-26.5-11.8-26.5-26.5S39.3,11.2,54,11.2s26.5,11.8,26.5,26.5S68.6,64.2,54,64.2z"/>
+    <path
+        android:fillColor="#1A000000"
+        android:pathData="M153.4,112.9c-14.9-17.2-38.6-9.1-38.6-9.1l-10.2-11.3c0,0-4.8-5.9-9-3.7
+        c-7,3.6-0.6,10.7-0.6,10.7s12.3,15.1,15.4,20.1c2.1,3.4,8.4,4.5,10.1,4.9l17.1,3.7l-0.9-0.7l-1-0.7L153.4,112.9z"/>
+    <path
+        android:fillColor="#FFDBA6"
+        android:pathData="M152.1,113.9c-14.9-17.2-37.6-8-37.6-8l-11.1-12.3c0,0-4.8-5.9-9-3.7
+        c-7,3.6-0.6,10.7-0.6,10.7s12.3,15.1,15.4,20.1c2.1,3.4,8.4,4.5,10.1,4.9l19,4.1"/>
+    <path
+        android:fillColor="#1A000000"
+        android:pathData="M148.6,77.9c0.6,0.7,2,2.5,2.1,2.6c1.1,1.7,6.2,13.6,11.8,35.1c0,0.1,1.9,3,1.9,3.1
+        c0,0,0.1,0.1,0.1,0.2c0,0,0,0,0-0.1c0.9,1.3,4.4,6.6,8.9,13.7c0.1,0.2,0.3,0.5,0.4,0.7c0,0.1,0.1,0.1,0.1,0.2
+        c0.2,0.3,0.4,0.6,0.6,0.9c0.1-0.1,0.2-0.2,0.3-0.3c0.2-0.3,0.6-0.3,0.8,0c2.9,4.8,21.2,35,26.7,49c2.1,5.3,3.2,8.4,3.6,11.6
+        c0.3,2.3,0,4.4-1.2,6c1.5-1.9,3.5-6.8-1.5-19c-1.2-2.9-2.8-6.5-4.8-10.5c-7.5-15.2-20-35.6-22.4-39.6c-0.2-0.3-0.6-0.3-0.8,0
+        c-0.2,0.2-0.3,0.4-0.5,0.6c-4.5-7.1-8.2-12.6-8.8-13.5c-0.1-0.1-1.9-3-1.9-3.1c-5.7-21.6-10.7-33.4-11.8-35.1
+        c-0.1-0.1-1.5-1.9-2.1-2.6l-6.5-8.3c-1.9-2.3-4.2-4.1-6.7-2.3c-2.5,1.8-1.6,4.5-0.1,7.1l3.3,5.2l7-2
+        C147.7,77.4,148.1,77.3,148.6,77.9z"/>
+    <path
+        android:fillColor="#FFDBA6"
+        android:pathData="M148.6,77.9l-6.5-8.3c-1.9-2.3-4.2-4.1-6.7-2.3l0,0l0,0c-2.5,1.8-1.6,4.5-0.1,7.1l3.8,6L148.6,77.9C148.6,77.9,148.6,77.9,148.6,77.9z"/>
+    <path
+        android:fillColor="#1A000000"
+        android:pathData="M151.1,92.5l-19.7-25.3c-1.9-2.3-4.2-4.1-6.7-2.3l0,0l0,0c-2.5,1.8-1.6,4.5-0.1,7.1l17.1,27.2L151.1,92.5z"/>
+    <path
+        android:fillColor="#FFDBA6"
+        android:pathData="M149.7,92.9l-19.7-25.3c-1.9-2.3-4.2-4.1-6.7-2.3l0,0l0,0c-2.5,1.8-1.6,4.5-0.1,7.1l17.1,27.2L149.7,92.9z"/>
+    <path
+        android:fillColor="#1A000000"
+        android:pathData="M141.6,94.6l-20.8-26.7c-2.1-2.5-4.4-4.3-7.1-2.5l0,0l0,0c-2.6,1.9-1.7,4.7-0.1,7.5l18,28.6L141.6,94.6z"/>
+    <path
+        android:fillColor="#FFDBA6"
+        android:pathData="M140.1,95l-20.8-26.7c-2.1-2.5-4.4-4.3-7.1-2.5l0,0h0c-2.6,1.9-1.7,4.7-0.1,7.5l18,28.6L140.1,95z"/>
+    <path
+        android:fillColor="#1A000000"
+        android:pathData="M140.4,99.1c-0.5-0.6-2.1-7.5-2.8-7.3l-15.9-6.9c-0.3,0-0.5-0.1-0.7-0.3l-2.3-3.5
+        l-0.4-0.6L100,54.5c-1.5-2-3.3-4-5.3-4.3c-0.7-0.1-1.3-0.2-2,0.2v0c-1,0.6-1.2,1.5-1.3,2.4c-0.2,1.8,0.6,3.9,1.6,5.9L108.5,87
+        l0.2,0.4l6.6,11.7l0,0c2.5,4.5,4.4,10.5,4.4,10.7L140.4,99.1"/>
+    <path
+        android:fillColor="#FFDBA6"
+        android:pathData="M129.7,125.1c3,0.7,8.1,4,11.8,9.1c2.7,3.7,5.5,8.3,8.2,13
+        c7.6-2.3,19.9-6.8,24.9-12.9c-0.2-0.3-0.4-0.6-0.6-0.9c0-0.1-0.1-0.1-0.1-0.2c-0.1-0.2-0.3-0.5-0.4-0.7c-4.5-7.1-8-12.4-8.9-13.7
+        c0,0,0,0,0,0.1c0-0.1-0.1-0.1-0.1-0.2c-0.1-0.1-1.9-3-1.9-3.1c-5.7-21.5-10.7-33.4-11.8-35.1c-0.1-0.1-1.5-1.9-2.1-2.6
+        c-0.5-0.6-0.9-0.5-1.6-0.3l-26.8,7.7c-0.3,0-0.5-0.1-0.7-0.3l-2.3-3.5l-0.4-0.6L98.5,54.8c-1.5-2-3.3-4-5.3-4.3
+        c-0.7-0.1-1.3-0.2-2,0.2c-1,0.6-1.2,1.5-1.3,2.4c-0.2,1.8,0.6,3.9,1.6,5.9L107,87.3l0.2,0.4l6.6,11.7l0,0
+        c2.5,4.5,4.4,10.5,4.4,10.7L129.7,125.1"/>
+    <path
+        android:fillColor="@color/all_apps_bg_hand_fill"
+        android:pathData="M202.3,183.1c-5.4-14.1-23.8-44.3-26.7-49c-0.2-0.3-0.6-0.3-0.8,0
+        c-5.1,6.6-19,11.4-26.5,13.6c-0.3,0.1-1,0.1-1.2,0.6c-0.2,0.4,0.1,1,0.2,1.1c7.8,12.9,14.7,27.9,15.3,29.3c0,0.1,0.1,0.1,0.1,0.2
+        l9.6,22.9c0,0,0,0,0,0l1.7,4.1c1.4,2.7,3,4.3,5.3,5.1c1.5,0.5,2.1,0.6,3.2,0.6c4.8,0.1,15.2-6.1,20.5-9.4c2.7-1.7,3.3-4.4,2.9-7.6
+        C205.5,191.5,204.4,188.4,202.3,183.1z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_info_no_shadow.xml b/res/drawable/ic_info_no_shadow.xml
index 3d0c6d6..91a3a56 100644
--- a/res/drawable/ic_info_no_shadow.xml
+++ b/res/drawable/ic_info_no_shadow.xml
@@ -17,8 +17,9 @@
         android:width="24dp"
         android:height="24dp"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorPrimary" >
     <path
-        android:fillColor="@color/workspace_icon_text_color"
+        android:fillColor="#FFFFFFFF"
         android:pathData="M11 17h2v-6h-2v6zm1-15C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zM11 9h2V7h-2v2z"/>
 </vector>
diff --git a/res/drawable/ic_remove_no_shadow.xml b/res/drawable/ic_remove_no_shadow.xml
new file mode 100644
index 0000000..ef538a6
--- /dev/null
+++ b/res/drawable/ic_remove_no_shadow.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorPrimary" >
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/>
+</vector>
diff --git a/res/drawable/ic_setting.xml b/res/drawable/ic_setting.xml
index e89c158..b0009c5 100644
--- a/res/drawable/ic_setting.xml
+++ b/res/drawable/ic_setting.xml
@@ -19,6 +19,6 @@
         android:viewportWidth="48.0"
         android:viewportHeight="48.0">
     <path
-        android:fillColor="@color/workspace_icon_text_color"
+        android:fillColor="?android:attr/textColorPrimary"
         android:pathData="M38.86 25.95c.08-.64 .14-1.29 .14-1.95s-.06-1.31-.14-1.95l4.23-3.31c.38-.3 .49-.84 .24-1.28l-4-6.93c-.25-.43-.77-.61-1.22-.43l-4.98 2.01c-1.03-.79-2.16-1.46-3.38-1.97L29 4.84c-.09-.47-.5-.84-1-.84h-8c-.5 0-.91 .37-.99 .84l-.75 5.3c-1.22 .51-2.35 1.17-3.38 1.97L9.9 10.1c-.45-.17-.97 0-1.22 .43l-4 6.93c-.25 .43-.14 .97 .24 1.28l4.22 3.31C9.06 22.69 9 23.34 9 24s.06 1.31 .14 1.95l-4.22 3.31c-.38 .3-.49 .84-.24 1.28l4 6.93c.25 .43 .77 .61 1.22 .43l4.98-2.01c1.03 .79 2.16 1.46 3.38 1.97l.75 5.3c.08 .47 .49 .84 .99 .84h8c.5 0 .91-.37 .99-.84l.75-5.3c1.22-.51 2.35-1.17 3.38-1.97l4.98 2.01c.45 .17 .97 0 1.22-.43l4-6.93c.25-.43 .14-.97-.24-1.28l-4.22-3.31zM24 31c-3.87 0-7-3.13-7-7s3.13-7 7-7 7 3.13 7 7-3.13 7-7 7z"/>
 </vector>
diff --git a/res/drawable/ic_uninstall_no_shadow.xml b/res/drawable/ic_uninstall_no_shadow.xml
new file mode 100644
index 0000000..5bab422
--- /dev/null
+++ b/res/drawable/ic_uninstall_no_shadow.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorPrimary" >
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/>
+</vector>
diff --git a/res/drawable/ic_wallpaper.xml b/res/drawable/ic_wallpaper.xml
index b7fcfbf..30f6d1a 100644
--- a/res/drawable/ic_wallpaper.xml
+++ b/res/drawable/ic_wallpaper.xml
@@ -19,6 +19,6 @@
         android:viewportWidth="48.0"
         android:viewportHeight="48.0">
     <path
-        android:fillColor="@color/workspace_icon_text_color"
+        android:fillColor="?android:attr/textColorPrimary"
         android:pathData="M8 8h14V4H8C5.79 4 4 5.79 4 8v14h4V8zm12 18l-8 10h24l-6-8-4.06 5.42L20 26zm14-9c0-1.66-1.34-3-3-3s-3 1.34-3 3 1.34 3 3 3 3-1.34 3-3zm6-13H26v4h14v14h4V8c0-2.21-1.79-4-4-4zm0 36H26v4h14c2.21 0 4-1.79 4-4V26h-4v14zM8 26H4v14c0 2.21 1.79 4 4 4h14v-4H8V26z"/>
 </vector>
diff --git a/res/drawable/ic_widget.xml b/res/drawable/ic_widget.xml
index 97706e3..3e7bd7b 100644
--- a/res/drawable/ic_widget.xml
+++ b/res/drawable/ic_widget.xml
@@ -19,6 +19,6 @@
         android:viewportWidth="48.0"
         android:viewportHeight="48.0">
     <path
-        android:fillColor="@color/workspace_icon_text_color"
+        android:fillColor="#FFFFFFFF"
         android:pathData="M26 26v16h16V26H26zM6 42h16V26H6v16zM6 6v16h16V6H6zm27.31-2.63L22 14.69 33.31 26l11.31-11.31L33.31 3.37z"/>
 </vector>
diff --git a/res/interpolator/folder_interpolator.xml b/res/interpolator/folder_interpolator.xml
new file mode 100644
index 0000000..b95d454
--- /dev/null
+++ b/res/interpolator/folder_interpolator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:controlX1="0.2"
+    android:controlY1="0"
+    android:controlX2="0"
+    android:controlY2="1"/>
diff --git a/res/interpolator/large_folder_preview_item_interpolator.xml b/res/interpolator/large_folder_preview_item_interpolator.xml
new file mode 100644
index 0000000..dcf0157
--- /dev/null
+++ b/res/interpolator/large_folder_preview_item_interpolator.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<pathInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
+    android:controlX1="0"
+    android:controlY1="1"
+    android:controlX2="0"
+    android:controlY2="1"/>
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index ef0dfdc..2e03576 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -27,7 +27,7 @@
         android:id="@+id/drag_layer"
         android:clipChildren="false"
         android:clipToPadding="false"
-        android:background="@drawable/workspace_bg"
+        android:background="?attr/workspaceStatusBarScrim"
         android:importantForAccessibility="no"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
@@ -35,12 +35,15 @@
         <!-- The workspace contains 5 screens of cells -->
         <!-- DO NOT CHANGE THE ID -->
         <com.android.launcher3.Workspace
+            android:theme="@style/HomeScreenElementTheme"
             android:id="@+id/workspace"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="center"
             launcher:pageIndicator="@id/page_indicator" />
 
+        <include layout="@layout/gradient_scrim" />
+
         <!-- DO NOT CHANGE THE ID -->
         <include layout="@layout/hotseat"
             android:id="@+id/hotseat"
@@ -59,16 +62,11 @@
 
         <com.android.launcher3.pageindicators.PageIndicatorCaretLandscape
             android:id="@+id/page_indicator"
+            android:theme="@style/HomeScreenElementTheme"
             android:layout_width="@dimen/dynamic_grid_page_indicator_height"
             android:layout_height="@dimen/dynamic_grid_page_indicator_height"
             android:layout_gravity="bottom|left"/>
 
-        <!-- A place holder view instead of the QSB in transposed layout -->
-        <View
-            android:layout_width="0dp"
-            android:layout_height="10dp"
-            android:id="@+id/workspace_blocked_row" />
-
         <include layout="@layout/widgets_view"
             android:id="@+id/widgets_view"
             android:layout_width="match_parent"
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index dd981dd..93c9078 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -29,13 +29,14 @@
         android:clipChildren="false"
         android:importantForAccessibility="no"
         android:clipToPadding="false"
-        android:background="@drawable/workspace_bg"
+        android:background="?attr/workspaceStatusBarScrim"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
         <!-- The workspace contains 5 screens of cells -->
         <!-- DO NOT CHANGE THE ID -->
         <com.android.launcher3.Workspace
+            android:theme="@style/HomeScreenElementTheme"
             android:id="@+id/workspace"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
@@ -43,6 +44,8 @@
             launcher:pageIndicator="@+id/page_indicator">
         </com.android.launcher3.Workspace>
 
+        <include layout="@layout/gradient_scrim" />
+
         <!-- DO NOT CHANGE THE ID -->
         <include layout="@layout/hotseat"
             android:id="@+id/hotseat"
@@ -63,10 +66,6 @@
             android:id="@+id/drop_target_bar"
             layout="@layout/drop_target_bar_horz" />
 
-        <include
-            layout="@layout/qsb_container"
-            android:id="@+id/qsb_container" />
-
         <include layout="@layout/widgets_view"
             android:id="@+id/widgets_view"
             android:layout_width="match_parent"
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 06cb550..ca4d846 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -28,13 +28,14 @@
         android:clipChildren="false"
         android:clipToPadding="false"
         android:importantForAccessibility="no"
-        android:background="@drawable/workspace_bg"
+        android:background="?attr/workspaceStatusBarScrim"
         android:layout_width="match_parent"
         android:layout_height="match_parent">
 
         <!-- The workspace contains 5 screens of cells -->
         <!-- DO NOT CHANGE THE ID -->
         <com.android.launcher3.Workspace
+            android:theme="@style/HomeScreenElementTheme"
             android:layout_gravity="center"
             android:id="@+id/workspace"
             android:layout_width="match_parent"
@@ -42,6 +43,8 @@
             launcher:pageIndicator="@id/page_indicator">
         </com.android.launcher3.Workspace>
 
+        <include layout="@layout/gradient_scrim" />
+
         <!-- DO NOT CHANGE THE ID -->
         <include layout="@layout/hotseat"
             android:id="@+id/hotseat"
@@ -62,10 +65,6 @@
         <include layout="@layout/page_indicator"
                  android:id="@+id/page_indicator" />
 
-        <include
-            layout="@layout/qsb_container"
-            android:id="@+id/qsb_container" />
-
         <include layout="@layout/widgets_view"
             android:id="@+id/widgets_view"
             android:layout_width="match_parent"
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index d6bdac2..09b9655 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -51,6 +51,7 @@
             android:layout_height="match_parent"
             android:layout_gravity="center_horizontal|top"
             android:clipToPadding="false"
+            android:overScrollMode="never"
             android:descendantFocusability="afterDescendants"
             android:focusable="true"
             android:paddingStart="@dimen/container_fastscroll_thumb_max_width"
@@ -59,38 +60,16 @@
         <!-- Fast scroller popup -->
         <TextView
             style="@style/FastScrollerPopup"
-            android:layout_below="@+id/search_container"
+            android:layout_alignTop="@+id/apps_list_view"
             android:id="@+id/fast_scroller_popup"
             android:layout_alignParentEnd="true"
             android:layout_marginEnd="@dimen/container_fastscroll_popup_margin" />
 
-        <FrameLayout
-            android:id="@+id/search_container"
-            android:layout_width="match_parent"
-            android:layout_height="@dimen/all_apps_search_bar_height"
-            android:layout_gravity="center|top"
-            android:gravity="center|bottom"
-            android:orientation="horizontal"
-            android:saveEnabled="false">
-
-            <com.android.launcher3.ExtendedEditText
-                android:id="@+id/search_box_input"
-                android:layout_width="match_parent"
-                android:layout_height="@dimen/all_apps_search_bar_field_height"
-                android:background="@android:color/transparent"
-                android:layout_gravity="bottom"
-                android:focusableInTouchMode="true"
-                android:gravity="center"
-                android:imeOptions="actionSearch|flagNoExtractUi"
-                android:inputType="text|textNoSuggestions|textCapWords"
-                android:maxLines="1"
-                android:scrollHorizontally="true"
-                android:singleLine="true"
-                android:textColor="?android:attr/textColorSecondary"
-                android:hint="@string/all_apps_search_bar_hint"
-                android:textColorHint="@drawable/all_apps_search_hint"
-                android:textSize="16sp" />
-        </FrameLayout>
+        <!-- Note: we are reusing/repurposing a system attribute for search layout, because of a
+         platform bug, which prevents using custom attributes in <include> tag -->
+        <include
+            layout="?android:attr/keyboardLayout"
+            android:id="@+id/search_container" />
 
     </com.android.launcher3.allapps.AllAppsRecyclerViewContainerView>
     <View
diff --git a/res/layout/all_apps_search_container.xml b/res/layout/all_apps_search_container.xml
new file mode 100644
index 0000000..c79360f
--- /dev/null
+++ b/res/layout/all_apps_search_container.xml
@@ -0,0 +1,42 @@
+<?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.
+-->
+<com.android.launcher3.allapps.search.AppsSearchContainerLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/search_container"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/all_apps_search_bar_height"
+    android:layout_gravity="center|top"
+    android:gravity="center|bottom"
+    android:saveEnabled="false">
+
+    <com.android.launcher3.ExtendedEditText
+        android:id="@+id/search_box_input"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/all_apps_search_bar_field_height"
+        android:layout_gravity="bottom"
+        android:background="@android:color/transparent"
+        android:focusableInTouchMode="true"
+        android:gravity="center"
+        android:hint="@string/all_apps_search_bar_hint"
+        android:imeOptions="actionSearch|flagNoExtractUi"
+        android:inputType="text|textNoSuggestions|textCapWords"
+        android:maxLines="1"
+        android:scrollHorizontally="true"
+        android:singleLine="true"
+        android:textColor="?android:attr/textColorSecondary"
+        android:textColorHint="@drawable/all_apps_search_hint"
+        android:textSize="16sp" />
+</com.android.launcher3.allapps.search.AppsSearchContainerLayout>
\ No newline at end of file
diff --git a/res/layout/app_widget_resize_frame.xml b/res/layout/app_widget_resize_frame.xml
index 91a1e45..874fecc 100644
--- a/res/layout/app_widget_resize_frame.xml
+++ b/res/layout/app_widget_resize_frame.xml
@@ -20,38 +20,43 @@
     android:layout_height="match_parent"
     android:background="@drawable/widget_resize_shadow"
     android:foreground="@drawable/widget_resize_frame"
+    android:foregroundTint="?attr/workspaceTextColor"
     android:padding="0dp" >
 
     <!-- Left -->
     <ImageView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:src="@drawable/ic_widget_resize_handle"
         android:layout_gravity="left|center_vertical"
-        android:layout_marginLeft="@dimen/widget_handle_margin" />
+        android:layout_marginLeft="@dimen/widget_handle_margin"
+        android:src="@drawable/ic_widget_resize_handle"
+        android:tint="?attr/workspaceTextColor" />
 
     <!-- Top -->
     <ImageView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:src="@drawable/ic_widget_resize_handle"
         android:layout_gravity="top|center_horizontal"
-        android:layout_marginTop="@dimen/widget_handle_margin" />
+        android:layout_marginTop="@dimen/widget_handle_margin"
+        android:src="@drawable/ic_widget_resize_handle"
+        android:tint="?attr/workspaceTextColor" />
 
     <!-- Right -->
     <ImageView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:src="@drawable/ic_widget_resize_handle"
         android:layout_gravity="right|center_vertical"
-        android:layout_marginRight="@dimen/widget_handle_margin" />
+        android:layout_marginRight="@dimen/widget_handle_margin"
+        android:src="@drawable/ic_widget_resize_handle"
+        android:tint="?attr/workspaceTextColor" />
 
     <!-- Bottom -->
     <ImageView
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:src="@drawable/ic_widget_resize_handle"
         android:layout_gravity="bottom|center_horizontal"
-        android:layout_marginBottom="@dimen/widget_handle_margin" />
+        android:layout_marginBottom="@dimen/widget_handle_margin"
+        android:src="@drawable/ic_widget_resize_handle"
+        android:tint="?attr/workspaceTextColor" />
 
 </com.android.launcher3.AppWidgetResizeFrame>
\ No newline at end of file
diff --git a/res/layout/deep_shortcut.xml b/res/layout/deep_shortcut.xml
index 85caba4..4a2ad42 100644
--- a/res/layout/deep_shortcut.xml
+++ b/res/layout/deep_shortcut.xml
@@ -18,7 +18,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="@dimen/bg_popup_item_width"
-    android:layout_height="@dimen/bg_popup_item_height" >
+    android:layout_height="@dimen/bg_popup_item_height"
+    android:theme="@style/PopupItem" >
 
     <com.android.launcher3.shortcuts.DeepShortcutTextView
         style="@style/BaseIcon"
@@ -50,6 +51,6 @@
         android:layout_height="@dimen/popup_item_divider_height"
         android:layout_gravity="end|bottom"
         android:visibility="gone"
-        android:background="?android:attr/listDivider" />
+        android:background="?attr/popupColorTertiary" />
 
 </com.android.launcher3.shortcuts.DeepShortcutView>
diff --git a/res/layout/drop_target_bar_horz.xml b/res/layout/drop_target_bar_horz.xml
index ee22d1e..ed18192 100644
--- a/res/layout/drop_target_bar_horz.xml
+++ b/res/layout/drop_target_bar_horz.xml
@@ -17,8 +17,10 @@
 <com.android.launcher3.DropTargetBar
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:theme="@style/HomeScreenElementTheme"
     android:layout_width="match_parent"
     android:layout_height="@dimen/dynamic_grid_drop_target_size"
+    android:visibility="invisible"
     android:layout_gravity="center_horizontal|top"
     android:focusable="false">
 
diff --git a/res/layout/drop_target_bar_vert.xml b/res/layout/drop_target_bar_vert.xml
index 10b1d7c..2394d0d 100644
--- a/res/layout/drop_target_bar_vert.xml
+++ b/res/layout/drop_target_bar_vert.xml
@@ -15,11 +15,13 @@
      limitations under the License.
 -->
 <com.android.launcher3.DropTargetBar
+    android:theme="@style/HomeScreenElementTheme"
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/dynamic_grid_drop_target_size"
     android:orientation="vertical"
     android:layout_height="match_parent"
     android:layout_gravity="left"
+    android:visibility="invisible"
     android:focusable="false"
     android:paddingTop="@dimen/vert_drop_target_vertical_gap" >
 
@@ -30,8 +32,7 @@
         android:gravity="center"
         android:paddingLeft="@dimen/vert_drop_target_horizontal_gap"
         android:paddingRight="@dimen/vert_drop_target_horizontal_gap"
-        android:id="@+id/delete_target_text"
-        android:textColor="@android:color/white" />
+        android:id="@+id/delete_target_text" />
 
     <!-- Uninstall target -->
     <com.android.launcher3.UninstallDropTarget
@@ -41,7 +42,6 @@
         android:paddingLeft="@dimen/vert_drop_target_horizontal_gap"
         android:paddingRight="@dimen/vert_drop_target_horizontal_gap"
         android:id="@+id/uninstall_target_text"
-        android:textColor="@android:color/white"
         android:layout_marginTop="@dimen/vert_drop_target_vertical_gap"/>
 
     <Space
@@ -57,7 +57,6 @@
         android:paddingLeft="@dimen/vert_drop_target_horizontal_gap"
         android:paddingRight="@dimen/vert_drop_target_horizontal_gap"
         android:id="@+id/info_target_text"
-        android:textColor="@android:color/white"
         android:layout_marginBottom="64dp"/>
 
 </com.android.launcher3.DropTargetBar>
\ No newline at end of file
diff --git a/res/layout/gradient_scrim.xml b/res/layout/gradient_scrim.xml
new file mode 100644
index 0000000..c40c5fc
--- /dev/null
+++ b/res/layout/gradient_scrim.xml
@@ -0,0 +1,31 @@
+<?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"
+    xmlns:app="http://schemas.android.com/apk/res-auto">
+    <com.android.launcher3.graphics.GradientView
+        android:id="@+id/gradient_bg"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone"
+        app:layout_ignoreInsets="true"/>
+
+    <com.android.launcher3.graphics.ScrimView
+        android:id="@+id/scrim_bg"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:visibility="gone"
+        app:layout_ignoreInsets="true"/>
+</merge>
\ No newline at end of file
diff --git a/res/layout/horizontal_divider.xml b/res/layout/horizontal_divider.xml
new file mode 100644
index 0000000..167f8f5
--- /dev/null
+++ b/res/layout/horizontal_divider.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<View xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/popup_item_divider_height"
+    android:background="?attr/popupColorTertiary" />
\ No newline at end of file
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
index f5b5bbf..582a83f 100644
--- a/res/layout/hotseat.xml
+++ b/res/layout/hotseat.xml
@@ -14,6 +14,7 @@
      limitations under the License.
 -->
 <com.android.launcher3.Hotseat
+    android:theme="@style/HomeScreenElementTheme"
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto">
     <com.android.launcher3.CellLayout
diff --git a/res/layout/notification.xml b/res/layout/notification.xml
index f955c6b..085dfa9 100644
--- a/res/layout/notification.xml
+++ b/res/layout/notification.xml
@@ -19,9 +19,8 @@
     android:id="@+id/notification_view"
     android:layout_width="@dimen/bg_popup_item_width"
     android:layout_height="wrap_content"
-    android:elevation="@dimen/deep_shortcuts_elevation"
-    android:background="@drawable/bg_white_round_rect"
-    android:backgroundTint="@color/notification_color_beneath">
+    android:theme="@style/PopupItem"
+    android:elevation="@dimen/deep_shortcuts_elevation">
 
     <RelativeLayout
         android:layout_width="match_parent"
@@ -35,7 +34,7 @@
             android:layout_height="@dimen/notification_header_height"
             android:paddingStart="@dimen/notification_padding_start"
             android:paddingEnd="@dimen/notification_padding_end"
-            android:background="@color/popup_header_background_color"
+            android:background="?attr/popupColorPrimary"
             android:elevation="@dimen/notification_elevation">
             <TextView
                 android:id="@+id/notification_text"
@@ -67,8 +66,9 @@
             android:id="@+id/divider"
             android:layout_width="match_parent"
             android:layout_height="@dimen/popup_item_divider_height"
-            android:background="?android:attr/listDivider"
-            android:layout_below="@id/main_view"/>
+            android:background="?attr/popupColorTertiary"
+            android:layout_below="@id/main_view"
+            android:visibility="gone" />
 
         <include layout="@layout/notification_footer"
             android:id="@+id/footer"
diff --git a/res/layout/notification_footer.xml b/res/layout/notification_footer.xml
index ed2212b..86280e0 100644
--- a/res/layout/notification_footer.xml
+++ b/res/layout/notification_footer.xml
@@ -22,7 +22,7 @@
     android:elevation="@dimen/notification_elevation"
     android:clipChildren="false"
     android:layout_gravity="center_vertical"
-    android:background="@color/popup_background_color">
+    android:background="?attr/popupColorPrimary">
 
     <LinearLayout
         android:id="@+id/icon_row"
diff --git a/res/layout/notification_main.xml b/res/layout/notification_main.xml
index ce4e137..b2443f5 100644
--- a/res/layout/notification_main.xml
+++ b/res/layout/notification_main.xml
@@ -28,7 +28,7 @@
         android:layout_height="match_parent"
         android:orientation="vertical"
         android:gravity="center_vertical"
-        android:background="@color/popup_background_color"
+        android:background="?attr/popupColorPrimary"
         android:paddingStart="@dimen/notification_padding_start"
         android:paddingEnd="@dimen/notification_main_text_padding_end">
         <TextView
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml
index 2091721..d1ac56c 100644
--- a/res/layout/overview_panel.xml
+++ b/res/layout/overview_panel.xml
@@ -14,8 +14,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<LinearLayout
+      xmlns:android="http://schemas.android.com/apk/res/android"
       xmlns:launcher="http://schemas.android.com/apk/res-auto"
+      android:theme="@style/HomeScreenElementTheme"
       launcher:layout_ignoreInsets="true"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
@@ -30,12 +32,13 @@
         android:layout_weight="1"
         android:drawablePadding="4dp"
         android:drawableTop="@drawable/ic_wallpaper"
+        android:drawableTint="?attr/workspaceTextColor"
         android:fontFamily="sans-serif-condensed"
         android:gravity="center_horizontal"
         android:stateListAnimator="@animator/overview_button_anim"
         android:text="@string/wallpaper_button_text"
         android:textAllCaps="true"
-        android:textColor="@android:color/white"
+        android:textColor="?attr/workspaceTextColor"
         android:textSize="12sp" />
 
     <TextView
@@ -45,12 +48,13 @@
         android:layout_weight="1"
         android:drawablePadding="4dp"
         android:drawableTop="@drawable/ic_widget"
+        android:drawableTint="?attr/workspaceTextColor"
         android:fontFamily="sans-serif-condensed"
         android:gravity="center_horizontal"
         android:stateListAnimator="@animator/overview_button_anim"
         android:text="@string/widget_button_text"
         android:textAllCaps="true"
-        android:textColor="@android:color/white"
+        android:textColor="?attr/workspaceTextColor"
         android:textSize="12sp" />
 
     <TextView
@@ -60,12 +64,13 @@
         android:layout_weight="1"
         android:drawablePadding="4dp"
         android:drawableTop="@drawable/ic_setting"
+        android:drawableTint="?attr/workspaceTextColor"
         android:fontFamily="sans-serif-condensed"
         android:gravity="center_horizontal"
         android:stateListAnimator="@animator/overview_button_anim"
         android:text="@string/settings_button_text"
         android:textAllCaps="true"
-        android:textColor="@android:color/white"
+        android:textColor="?attr/workspaceTextColor"
         android:textSize="12sp" />
 
 </LinearLayout>
\ No newline at end of file
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
index 2e1b57f..e29e5b1 100644
--- a/res/layout/page_indicator.xml
+++ b/res/layout/page_indicator.xml
@@ -16,6 +16,7 @@
 
 <com.android.launcher3.pageindicators.PageIndicatorLineCaret
     xmlns:android="http://schemas.android.com/apk/res/android"
+    android:theme="@style/HomeScreenElementTheme"
     android:layout_width="match_parent"
     android:layout_height="@dimen/dynamic_grid_page_indicator_height">
         <ImageView
diff --git a/res/layout/shortcuts_item.xml b/res/layout/shortcuts_item.xml
index 8b20bcb..e54462e 100644
--- a/res/layout/shortcuts_item.xml
+++ b/res/layout/shortcuts_item.xml
@@ -19,8 +19,7 @@
     android:id="@+id/shortcuts_view"
     android:layout_width="@dimen/bg_popup_item_width"
     android:layout_height="wrap_content"
-    android:elevation="@dimen/deep_shortcuts_elevation"
-    android:background="@drawable/bg_white_round_rect">
+    android:elevation="@dimen/deep_shortcuts_elevation">
 
     <LinearLayout
         android:id="@+id/deep_shortcuts"
diff --git a/res/layout/system_shortcut.xml b/res/layout/system_shortcut.xml
index bf849aa..04f3d02 100644
--- a/res/layout/system_shortcut.xml
+++ b/res/layout/system_shortcut.xml
@@ -18,7 +18,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="@dimen/bg_popup_item_width"
-    android:layout_height="@dimen/bg_popup_item_height" >
+    android:layout_height="@dimen/bg_popup_item_height"
+    android:theme="@style/PopupItem" >
 
     <com.android.launcher3.BubbleTextView
         style="@style/BaseIcon"
@@ -40,7 +41,8 @@
         android:layout_width="@dimen/system_shortcut_icon_size"
         android:layout_height="@dimen/system_shortcut_icon_size"
         android:layout_marginStart="@dimen/system_shortcut_margin_start"
-        android:layout_gravity="start|center_vertical" />
+        android:layout_gravity="start|center_vertical"
+        android:backgroundTint="?android:attr/textColorTertiary"/>
 
     <View
         android:id="@+id/divider"
@@ -48,6 +50,6 @@
         android:layout_height="@dimen/popup_item_divider_height"
         android:layout_gravity="end|bottom"
         android:visibility="gone"
-        android:background="?android:attr/listDivider" />
+        android:background="?attr/popupColorTertiary" />
 
 </com.android.launcher3.shortcuts.DeepShortcutView>
diff --git a/res/layout/system_shortcut_icon_only.xml b/res/layout/system_shortcut_icon_only.xml
index 313c69c..c59cb53 100644
--- a/res/layout/system_shortcut_icon_only.xml
+++ b/res/layout/system_shortcut_icon_only.xml
@@ -19,4 +19,6 @@
     android:layout_width="@dimen/system_shortcut_header_icon_touch_size"
     android:layout_height="@dimen/system_shortcut_header_icon_touch_size"
     android:background="?android:attr/selectableItemBackgroundBorderless"
-    android:padding="@dimen/system_shortcut_header_icon_padding" />
+    android:tint="?android:attr/textColorHint"
+    android:padding="@dimen/system_shortcut_header_icon_padding"
+    android:theme="@style/PopupItem" />
diff --git a/res/layout/system_shortcut_icons.xml b/res/layout/system_shortcut_icons.xml
index 676be8e..db59d49 100644
--- a/res/layout/system_shortcut_icons.xml
+++ b/res/layout/system_shortcut_icons.xml
@@ -21,4 +21,4 @@
     android:layout_height="@dimen/system_shortcut_header_height"
     android:orientation="horizontal"
     android:gravity="end|center_vertical"
-    android:background="@color/popup_header_background_color" />
+    android:background="?attr/popupColorSecondary" />
diff --git a/res/layout/widgets_bottom_sheet.xml b/res/layout/widgets_bottom_sheet.xml
index c2270d2..f1370f0 100644
--- a/res/layout/widgets_bottom_sheet.xml
+++ b/res/layout/widgets_bottom_sheet.xml
@@ -25,11 +25,11 @@
     android:layout_gravity="bottom">
 
     <TextView
+        style="@style/TextTitle"
         android:id="@+id/title"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:gravity="center_horizontal"
-        android:fontFamily="sans-serif"
         android:textColor="?android:attr/textColorPrimary"
         android:textSize="24sp"/>
 
diff --git a/res/layout/widgets_view.xml b/res/layout/widgets_view.xml
index 2f11c28..476901d 100644
--- a/res/layout/widgets_view.xml
+++ b/res/layout/widgets_view.xml
@@ -51,7 +51,6 @@
         <!-- Fast scroller popup -->
         <TextView
             style="@style/FastScrollerPopup"
-            android:layout_below="@+id/search_container"
             android:id="@+id/fast_scroller_popup"
             android:layout_gravity="top|end"
             android:layout_marginEnd="@dimen/container_fastscroll_popup_margin" />
diff --git a/res/raw/downgrade_schema.json b/res/raw/downgrade_schema.json
new file mode 100644
index 0000000..3c1b64f
--- /dev/null
+++ b/res/raw/downgrade_schema.json
@@ -0,0 +1,20 @@
+{
+  // Note: Comments are not supported in JSON schema, but android parser is lenient.
+
+  // Maximum DB version supported by this schema
+  "version" : 27,
+
+  // Downgrade from 27 to 26. Empty array indicates, the DB is compatible
+  "downgrade_to_26" : [],
+  "downgrade_to_25" : [],
+  "downgrade_to_24" : [],
+  "downgrade_to_23" : [],
+  "downgrade_to_22" : [
+    "ALTER TABLE favorites RENAME TO temp_favorites;",
+    "CREATE TABLE favorites(_id INTEGER PRIMARY KEY, title TEXT, intent TEXT, container INTEGER, screen INTEGER, cellX INTEGER, cellY INTEGER, spanX INTEGER, spanY INTEGER, itemType INTEGER, appWidgetId INTEGER NOT NULL DEFAULT - 1, iconPackage TEXT, iconResource TEXT, icon BLOB, appWidgetProvider TEXT, modified INTEGER NOT NULL DEFAULT 0, restored INTEGER NOT NULL DEFAULT 0, profileId INTEGER DEFAULT 0, rank INTEGER NOT NULL DEFAULT 0);",
+    "INSERT INTO favorites SELECT _id, title, intent, container, screen, cellX, cellY, spanX, spanY, itemType, appWidgetId, iconPackage, iconResource, icon, appWidgetProvider, modified, restored, profileId, rank FROM temp_favorites;",
+    "DROP TABLE temp_favorites;"
+  ]
+
+  // Missing values indicate the DB is not compatible
+}
\ No newline at end of file
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 29e27ea..68b8307 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Vouer: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Legstukke"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Muurpapiere"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Instellings"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Home-instellings"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gedeaktiveer deur jou administrateur"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Oorsig"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Laat toe dat tuisskerm gedraai word"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 59c44e2..ba39963 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"አቃፊ፦ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ፍርግሞች"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"የግድግዳ ወረቀቶች"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"ቅንብሮች"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"የመነሻ ቅንብሮች"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"በእርስዎ አስተዳዳሪ የተሰናከለ"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"አጠቃላይ ዕይታ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"የመነሻ ማያ ገጽ ማሽከርከርን ይፍቀዱ"</string>
@@ -84,6 +84,14 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <string name="icon_shape_system_default" msgid="1709762974822753030">"የሥርዓቱን ነባሪ ተጠቀም"</string>
+    <!-- no translation found for icon_shape_square (633575066111622774) -->
+    <skip />
+    <!-- no translation found for icon_shape_squircle (5658049910802669495) -->
+    <skip />
+    <!-- no translation found for icon_shape_circle (6550072265930144217) -->
+    <skip />
+    <!-- no translation found for icon_shape_teardrop (4525869388200835463) -->
+    <skip />
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"የማይታወቅ"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index d8b1cc9..cb2634d 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"المجلد: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"الأدوات"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"الخلفيات"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"الإعدادات"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"إعدادات الصفحة الرئيسية"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"عطَّل المشرف هذه الميزة"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"نظرة عامة"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"السماح بتدوير الشاشة الرئيسية"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"غير معروفة"</string>
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
index e5d0a6c..1f89f5a 100644
--- a/res/values-az-rAZ/strings.xml
+++ b/res/values-az-rAZ/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Vidcet"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Divar kağızları"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Ayarlar"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Home ayarları"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Admininiz tərəfindən deaktiv edilib"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"İcmal"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Əsas ekranın firlanmağına icazə verin"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Naməlum"</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
new file mode 100644
index 0000000..5cbe408
--- /dev/null
+++ b/res/values-az/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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">"Tətbiq quraşdırılmayıb."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Tətbiq əlçatmazdır"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Güvənli rejimdə icazə verilməyən tətbiq endirildi"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Vidcetlər Güvənli rejimdə deaktiv edilib"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"Qısayol əlçatan deyil"</string>
+    <string name="home_screen" msgid="806512411299847073">"Əsas ekran"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Fərdi əməliyyatlar"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidceti götürmək üçün toxunub saxlayın."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Vidceti götürmək üçün &amp; iki dəfə toxunub saxlayın və ya fərdi fəaliyyətləri istifadə edin."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d hündürlük %1$d enində"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Manual olaraq yerləşdirmək üçün toxunaraq basıb saxlayın"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Avtomatik əlavə edin"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Tətbiq Axtarın"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Tətbiqlər endirilir..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" sorğusuna uyğun Tətbiqlər tapılmadı"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Daha çox tətbiq üçün axtarış edin"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Bildirişlər"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Bu Əsas ekranda boş yer yoxdur."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Favoritlər-də yer yoxdur"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Tətbiq siyahısı"</string>
+    <string name="all_apps_home_button_label" msgid="252062713717058851">"Əsas səhifə"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Silin"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Sistemdən sil"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Tətbiq məlumatı"</string>
+    <string name="permlab_install_shortcut" msgid="5632423390354674437">"qısayolları quraşdır"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Tətbiqə istifadəçi müdaxiləsi olmadan qısayolları əlavə etməyə icazə verir."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"Əsas Səhifə ayarlarını və qısayolları oxuyun"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Tətbiqə Əsas Səhifədə parametrləri və qısayolları oxumağa icazə verir."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"Əsas Səhifə ayarlarını və qısayolları yazın"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Tətbiqə Əsas Səhifədə ayarları və qısayolları dəyişməyə icazə verir."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqinə telefon zəngləri etmək üçün icazə verilmir"</string>
+    <string name="gadget_error_text" msgid="6081085226050792095">"Vidcet yükləmə problemi"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Quraşdırma"</string>
+    <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>
+    <string name="default_scroll_format" msgid="7475544710230993317">"Səhifə %1$d of %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"Əsas Səhifə ekranı %1$d of %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"Yeni əsas ekran səhifəsi"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Qovluq açıldı, <xliff:g id="HEIGHT">%2$d</xliff:g> hündürlük ilə <xliff:g id="WIDTH">%1$d</xliff:g> enində"</string>
+    <string name="folder_tap_to_close" msgid="4625795376335528256">"Qovluq bağlamaq üçün toxunun"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Ad dəyişikliyini yadda saxlamaq üçün toxunun"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"Qovluq bağlıdır"</string>
+    <string name="folder_renamed" msgid="1794088362165669656">"Qovluq adı <xliff:g id="NAME">%1$s</xliff:g> ilə dəyişdirildi"</string>
+    <string name="folder_name_format" msgid="6629239338071103179">"Qovluq: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"Vidcet"</string>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Divar kağızları"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Ayarlar"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Admininiz tərəfindən deaktiv edilib"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"İcmal"</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="allow_rotation_blocked_desc" msgid="3212602545192996253">"Cari Ekran ayarı fırlatmağa icazə vermir"</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>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"Bu tətbiq quraşdırılmayıb"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Bu ikona üçün tətbiq quraşdırılmayıb. Onu silə bilərsiniz, və ya tətbiqi taparaq manual yol ilə quraşdıra bilərsiniz."</string>
+    <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> endirilir, <xliff:g id="PROGRESS">%2$s</xliff:g> tamamlandı"</string>
+    <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> yüklənmək üçün gözləyir"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> vidcetləri"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"Əsas ekrana əlavə edin"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Elementi bura köçürün"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"Element əsas ekrana əlavə edildi"</string>
+    <string name="item_removed" msgid="851119963877842327">"Element silindi"</string>
+    <string name="action_move" msgid="4339390619886385032">"Elementi köçürün"</string>
+    <string name="move_to_empty_cell" msgid="2833711483015685619">"Sıra <xliff:g id="NUMBER_0">%1$s</xliff:g> sütun <xliff:g id="NUMBER_1">%2$s</xliff:g> köçürün"</string>
+    <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g> mövqeyinə köçürün"</string>
+    <string name="move_to_hotseat_position" msgid="6295412897075147808">"<xliff:g id="NUMBER">%1$s</xliff:g> sevimlilər mövqeyinə köçürün"</string>
+    <string name="item_moved" msgid="4606538322571412879">"Elementin yeri dəyişildi"</string>
+    <string name="add_to_folder" msgid="9040534766770853243">"Qovluğa əlavə edin: <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> adlı qovluğa əlavə edin"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Element qovluğa əlavə edildi"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Qovluq yaradın: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Qovluq yaradıldı"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Əsas ekrana köçürün"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Ekranı sola köçürün"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Ekranı sağa köçürün"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Ekran köçürülüb"</string>
+    <string name="action_resize" msgid="1802976324781771067">"Ölçüsünü dəyişin"</string>
+    <string name="action_increase_width" msgid="8773715375078513326">"Eni artırın"</string>
+    <string name="action_increase_height" msgid="459390020612501122">"Hündürlüyü artırın"</string>
+    <string name="action_decrease_width" msgid="1374549771083094654">"Eni azaldın"</string>
+    <string name="action_decrease_height" msgid="282377193880900022">"Hündürlüyü azaldın"</string>
+    <string name="widget_resized" msgid="9130327887929620">"Vidcetin eni <xliff:g id="NUMBER_0">%1$s</xliff:g> hündürlüyü <xliff:g id="NUMBER_1">%2$s</xliff:g> kimi ölçüləndirildi"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"Qısa yollar"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> üçün <xliff:g id="APP_NAME">%2$s</xliff:g> qısa yolu"</string>
+</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 401fef3..9f2855d 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Direktorijum: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Vidžeti"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Podešavanja"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Podešavanja početnog ekrana"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator je onemogućio"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Pregled"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotaciju početnog ekrana"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
diff --git a/res/values-be-rBY/strings.xml b/res/values-be-rBY/strings.xml
index e3f9ad1..a0b7a69 100644
--- a/res/values-be-rBY/strings.xml
+++ b/res/values-be-rBY/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Папка: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Віджэты"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Шпалеры"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Налады"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Налады галоўнага экрана"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Адключаная адміністратарам"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Агляд"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Дазволіць паварот галоўнага экрана"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Невядома"</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index fc5390b..8eb7e84 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -19,188 +19,103 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <!-- no translation found for application_name (5181331383435256801) -->
-    <skip />
-    <!-- no translation found for home (7658288663002113681) -->
-    <skip />
-    <!-- no translation found for uid_name (7820867637514617527) -->
-    <skip />
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <!-- no translation found for wallpaper_instructions (563973358787555519) -->
+    <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="shortcut_not_available" msgid="2536503539825726397">"Ярлык недаступны"</string>
+    <string name="home_screen" msgid="806512411299847073">"Галоўны экран"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Спецыяльныя дзеянні"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Дакраніцеся і ўтрымлiвайце віджэт, каб выбр. яго."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Дакраніцеся двойчы і ўтрымлівайце, каб выбраць віджэт або выкарыстоўваць карыстальніцкія дзеянні."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Шырына: %1$d, вышыня: %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Каб размясціць уручную, дакраніцеся і ўтрымлівайце"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Дадаць аўтаматычна"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Пошук у Праграмах"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Ідзе загрузка праграм…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Праграм, якія адпавядаюць запыту \"<xliff:g id="QUERY">%1$s</xliff:g>\", не знойдзена"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукаць іншыя праграмы"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Апавяшчэнні"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"На гэтым Галоўным экране больш няма месца."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"У латку \"Абранае\" больш няма месца"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Спіс праграм"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"усталёўваць ярлыкі"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Дазваляе праграмам дадаваць ярлыкі без умяшання карыстальніка."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"счытваць налады і ярлыкі на Галоўнай старонцы"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Дазваляе праграме счытваць налады і ярлыкі на Галоўнай старонцы."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"запісваць налады і ярлыкі на галоўнай старонцы"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Дазваляе праграме змяняць налады і ярлыкі на Галоўнай старонцы."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> не мае дазволу на здзяйсненне тэлефонных званкоў"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"Папка без назвы"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> адключана"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"Старонка %1$d з %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"Галоўны экран %1$d з %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"Новая старонка галоўнага экрана"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Папка адкрыта, <xliff:g id="WIDTH">%1$d</xliff:g> на <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Шпалеры"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Налады"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Адключаная адміністратарам"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Агляд"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"Дазволіць паварот галоўнага экрана"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"Пры павароце тэлефона"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Бягучая налада дысплэя не прадугледжвае паварот"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Дадаць значок на Галоўны экран"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Для новых праграм"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
-    <!-- no translation found for image_load_fail (2821429163328561136) -->
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
     <skip />
-    <!-- no translation found for wallpaper_load_fail (1261270681127096352) -->
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
-    <!-- no translation found for number_of_items_selected:zero (7464587177007785408) -->
-    <!-- no translation found for number_of_items_selected:one (142482526010824029) -->
-    <!-- no translation found for number_of_items_selected:other (1418352074806573570) -->
-    <!-- no translation found for wallpaper_accessibility_name (1655953108132967972) -->
-    <skip />
-    <!-- no translation found for announce_selection (8338254712932127413) -->
-    <skip />
-    <!-- no translation found for wallpaper_delete (8095005658756613921) -->
-    <skip />
-    <!-- no translation found for pick_image (1272073934062909527) -->
-    <skip />
-    <!-- no translation found for pick_wallpaper (8179698221502010609) -->
-    <skip />
-    <!-- no translation found for crop_wallpaper (8334345984491368009) -->
-    <skip />
-    <!-- no translation found for activity_not_found (8071924732094499514) -->
-    <skip />
-    <!-- no translation found for widgets_tab_label (2921133187116603919) -->
-    <skip />
-    <!-- no translation found for widget_adder (3201040140710381657) -->
-    <skip />
-    <!-- no translation found for toggle_weight_watcher (5645299835184636119) -->
-    <skip />
-    <!-- no translation found for long_press_widget_to_add (7699152356777458215) -->
-    <skip />
-    <!-- no translation found for market (2619650989819296998) -->
-    <skip />
-    <!-- no translation found for widget_dims_format (2370757736025621599) -->
-    <skip />
-    <!-- no translation found for external_drop_widget_error (3165821058322217155) -->
-    <skip />
-    <!-- no translation found for external_drop_widget_pick_title (3486317258037690630) -->
-    <skip />
-    <!-- no translation found for rename_folder_label (3727762225964550653) -->
-    <skip />
-    <!-- no translation found for rename_folder_title (3771389277707820891) -->
-    <skip />
-    <!-- no translation found for rename_action (5559600076028658757) -->
-    <skip />
-    <!-- no translation found for cancel_action (7009134900002915310) -->
-    <skip />
-    <!-- no translation found for menu_item_add_item (1264911265836810421) -->
-    <skip />
-    <!-- no translation found for group_applications (3797214114206693605) -->
-    <skip />
-    <!-- no translation found for group_shortcuts (6012256992764410535) -->
-    <skip />
-    <!-- no translation found for group_widgets (1569030723286851002) -->
-    <skip />
-    <!-- no translation found for completely_out_of_space (6106288382070760318) -->
-    <skip />
-    <!-- no translation found for out_of_space (4691004494942118364) -->
-    <skip />
-    <!-- no translation found for hotseat_out_of_space (9139760413395605841) -->
-    <skip />
-    <!-- no translation found for invalid_hotseat_item (1211534262129849507) -->
-    <skip />
-    <!-- no translation found for shortcut_installed (1701742129426969556) -->
-    <skip />
-    <!-- no translation found for shortcut_uninstalled (8176767991305701821) -->
-    <skip />
-    <!-- no translation found for shortcut_duplicate (9167217446062498127) -->
-    <skip />
-    <!-- no translation found for title_select_shortcut (6680642571148153868) -->
-    <skip />
-    <!-- no translation found for title_select_application (3280812711670683644) -->
-    <skip />
-    <!-- no translation found for all_apps_button_label (9110807029020582876) -->
-    <skip />
-    <!-- no translation found for all_apps_home_button_label (252062713717058851) -->
-    <skip />
-    <!-- no translation found for delete_zone_label_workspace (4009607676751398685) -->
-    <skip />
-    <!-- no translation found for delete_zone_label_all_apps (8083826390278958980) -->
-    <skip />
-    <!-- no translation found for delete_target_label (1822697352535677073) -->
-    <skip />
-    <!-- no translation found for delete_target_uninstall_label (5100785476250872595) -->
-    <skip />
-    <!-- no translation found for info_target_label (8053346143994679532) -->
-    <skip />
-    <!-- no translation found for accessibility_search_button (1628520399424565142) -->
-    <skip />
-    <!-- no translation found for accessibility_voice_search_button (4637324840434406584) -->
-    <skip />
-    <!-- no translation found for accessibility_all_apps_button (2603132375383800483) -->
-    <skip />
-    <!-- no translation found for accessibility_delete_button (6466114477993744621) -->
-    <skip />
-    <!-- no translation found for delete_zone_label_all_apps_system_app (449755632749610895) -->
-    <skip />
-    <!-- no translation found for cab_menu_delete_app (7435191475867183689) -->
-    <skip />
-    <!-- no translation found for cab_menu_app_info (8593722221450362342) -->
-    <skip />
-    <!-- no translation found for cab_app_selection_text (374688303047985416) -->
-    <skip />
-    <!-- no translation found for cab_widget_selection_text (1833458597831541241) -->
-    <skip />
-    <!-- no translation found for cab_folder_selection_text (7999992513806132118) -->
-    <skip />
-    <!-- no translation found for cab_shortcut_selection_text (2103811025667946450) -->
-    <skip />
-    <!-- no translation found for permlab_install_shortcut (5632423390354674437) -->
-    <skip />
-    <!-- no translation found for permdesc_install_shortcut (923466509822011139) -->
-    <skip />
-    <!-- no translation found for permlab_uninstall_shortcut (864595034498083837) -->
-    <skip />
-    <!-- no translation found for permdesc_uninstall_shortcut (5134129545001836849) -->
-    <skip />
-    <!-- no translation found for permlab_read_settings (1941457408239617576) -->
-    <skip />
-    <!-- no translation found for permdesc_read_settings (5833423719057558387) -->
-    <skip />
-    <!-- no translation found for permlab_write_settings (3574213698004620587) -->
-    <skip />
-    <!-- no translation found for permdesc_write_settings (5440712911516509985) -->
-    <skip />
-    <!-- no translation found for gadget_error_text (6081085226050792095) -->
-    <skip />
-    <!-- no translation found for uninstall_system_app_text (4172046090762920660) -->
-    <skip />
-    <!-- no translation found for dream_name (1530253749244328964) -->
-    <skip />
-    <!-- no translation found for folder_hint_text (6617836969016293992) -->
-    <skip />
-    <!-- no translation found for workspace_description_format (2950174241104043327) -->
-    <skip />
-    <!-- no translation found for default_scroll_format (7475544710230993317) -->
-    <skip />
-    <!-- no translation found for workspace_scroll_format (8458889198184077399) -->
-    <skip />
-    <!-- no translation found for apps_customize_apps_scroll_format (370005296147130238) -->
-    <skip />
-    <!-- no translation found for apps_customize_widgets_scroll_format (3106209519974971521) -->
-    <skip />
-    <!-- no translation found for first_run_cling_title (7257389003637362144) -->
-    <skip />
-    <!-- no translation found for first_run_cling_description (6447072552696253358) -->
-    <skip />
-    <!-- no translation found for first_run_cling_create_screens_hint (6950729526680114157) -->
-    <skip />
-    <!-- no translation found for workspace_cling_title (5626202359865825661) -->
-    <skip />
-    <!-- no translation found for workspace_cling_move_item (528201129978005352) -->
-    <skip />
-    <!-- no translation found for folder_cling_title (3894908818693254164) -->
-    <skip />
-    <!-- no translation found for folder_cling_create_folder (6158215559475836131) -->
-    <skip />
-    <!-- no translation found for cling_dismiss (8962359497601507581) -->
-    <skip />
-    <!-- no translation found for folder_opened (94695026776264709) -->
-    <skip />
-    <!-- no translation found for folder_tap_to_close (1884479294466410023) -->
-    <skip />
-    <!-- no translation found for folder_tap_to_rename (9191075570492871147) -->
-    <skip />
-    <!-- no translation found for folder_closed (4100806530910930934) -->
-    <skip />
-    <!-- no translation found for folder_renamed (1794088362165669656) -->
-    <skip />
-    <!-- no translation found for folder_name_format (6629239338071103179) -->
-    <skip />
-    <!-- no translation found for widget_button_text (2880537293434387943) -->
-    <skip />
-    <!-- no translation found for wallpaper_button_text (8404103075899945851) -->
-    <skip />
-    <!-- no translation found for settings_button_text (8119458837558863227) -->
-    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"Дадаць у папку: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Дадаць у папку з <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Элемент дададзены ў папку"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Стварыць папку з: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Папка створана"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Перамясціць на Галоўны экран"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Перамясціць экран налева"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Перамясціць экран направа"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Экран перамешчаны"</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="action_deep_shortcut" msgid="2864038805849372848">"Ярлыкі"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"Ярлыкі (<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>) для <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index c19a8b4..fc3ba4b 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Папка: „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Приспособления"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Тапети"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Настройки"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Настройки за Google Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Деактивирано от администратора ви"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Общ преглед"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Разрешаване на завъртането на началния екран"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Няма информация"</string>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index 70e2c9b..1ee4b6b 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"ফোল্ডার: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"উইজেটগুলি"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"ওয়ালপেপারগুলি"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"সেটিংস"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"হোম এর সেটিংস"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"এক নজরে"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"হোমস্ক্রীন ঘোরানোর অনুমতি দিন"</string>
@@ -83,6 +83,10 @@
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"নতুন অ্যাপ্লিকেশানগুলির জন্যে"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"আইকনের আকৃতি পরিবর্তন করুন"</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>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
new file mode 100644
index 0000000..065019a
--- /dev/null
+++ b/res/values-bn/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"একটি উইজেট তুলতে তা স্পর্শ করে ধরে রাখুন৷"</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"কোনো উইজেট বেছে নিতে দুবার-আলতো চেপে ধরে থাকুন অথবা কাস্টম ক্রিয়াগুলি ব্যবহার করুন৷"</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d উচ্চতা অনুযায়ী %1$d প্রস্থ"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"নিজে যোগ করতে টাচ করে ধরে রাখুন"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"স্বয়ংক্রিয়ভাবে যোগ করুন"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"অ্যাপ্লিকেশানগুলি অনুসন্ধান করুন"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"অ্যাপ্লিকেশানগুলি লোড হচ্ছে..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" এর সাথে মেলে এমন কোনো অ্যাপ্লিকেশান পাওয়া যায়নি"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"আরো অ্যাপ্লিকেশানের জন্য অনুসন্ধান করুন"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"বিজ্ঞপ্তি"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"এই হোম স্ক্রীনে আর কোনো জায়গা নেই৷"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"পছন্দসই ট্রে-তে আর কোনো জায়গা নেই"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"অ্যাপ্লিকেশানগুলির তালিকা"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"শর্টকাটগুলি ইনস্টল করে"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"একটি অ্যাপ্লিকেশানকে ব্যবহারকারীর হস্তক্ষেপ ছাড়াই শর্টকাটগুলি যোগ করার অনুমতি দেয়৷"</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"হোম সেটিংস এবং শর্টকাটগুলি পড়ে"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"হোমে অ্যাপ্লিকেশানটিকে সেটিংস এবং শর্টকাটগুলি পড়তে দেয়৷"</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"হোম সেটিংস এবং শর্টকাটগুলি লেখে"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"হোমে অ্যাপ্লিকেশানটিকে সেটিংস এবং শর্টকাটগুলি পরিবর্তন করতে দেয়৷"</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"ফোন কলগুলি করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g> এর অনুমতি নেই"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"নামবিহীন ফোল্ডার"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> অক্ষম করা হয়েছে"</string>
+    <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> বাই <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"ওয়ালপেপারগুলি"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"সেটিংস"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"আপনার প্রশাসক দ্বারা অক্ষম করা হয়েছে"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"এক নজরে"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"হোমস্ক্রীন ঘোরানোর অনুমতি দিন"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"যখন ফোনটি ঘোরানো হয়"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"বর্তমান প্রদর্শনের সেটিংস ঘোরানোর মঞ্জুরি দেয় না"</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_no_override" msgid="3678524428085518367">"পরিবর্তন করবেন না"</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_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="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="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="add_to_folder" msgid="9040534766770853243">"ফোল্ডারে যোগ করুন: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> সহ ফোল্ডারে যোগ করা হয়েছে"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"আইটেম ফোল্ডারে যোগ করা হয়েছে"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"এর সাথে ফোল্ডার তৈরি করুন: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ফোল্ডার তৈরি করা হয়েছে"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"হোম স্ক্রীনে সরান"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"স্ক্রীন বাঁ দিকে সরান"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"স্ক্রীন ডান দিকে সরান"</string>
+    <string name="screen_moved" msgid="266230079505650577">"স্ক্রীন সরানো হয়েছে"</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="action_deep_shortcut" msgid="2864038805849372848">"শর্টকাট"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> এর <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>টি শর্টকার্ট"</string>
+</resources>
diff --git a/res/values-bs-rBA/strings.xml b/res/values-bs-rBA/strings.xml
index 37850db..259e516 100644
--- a/res/values-bs-rBA/strings.xml
+++ b/res/values-bs-rBA/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Dodaci"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadinske slike"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Postavke"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Postavke za Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio vaš administrator"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Pregled"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Dozvoli rotiranje početnog ekrana"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
new file mode 100644
index 0000000..8e1234e
--- /dev/null
+++ b/res/values-bs/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="app_name" msgid="649227358658669779">"Launcher3"</string>
+    <string name="folder_name" msgid="7371454440695724752"></string>
+    <string name="work_folder_name" msgid="3753320833950115786">"Posao"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"Aplikacija nije instalirana."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Aplikacija nije dostupna"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Preuzeta aplikacija je onemogućena u sigurnom načinu rada"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Vidžeti su onemogućeni u sigurnom načinu rada."</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"Prečica nije dostupna"</string>
+    <string name="home_screen" msgid="806512411299847073">"Početni ekran"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Prilagođene akcije"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Dodirnite &amp; i držite da biste uzeli dodatak."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dvaput dodirnite &amp; i držite da biste uzeli vidžet ili koristite prilagođene radnje."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, visina %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i držite da postavite ručno"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatski"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pretraži aplikacije"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Aplikacije se učitavaju…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nije pronađena nijedna aplikacija koja odgovara upitu \"<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="notifications_header" msgid="1404149926117359025">"Obavještenja"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Na ovom početnom ekranu nema više prostora."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Nema više prostora u ladici Favoriti"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Spisak aplikacija"</string>
+    <string name="all_apps_home_button_label" msgid="252062713717058851">"Tipka za početak"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Ukloni"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Deinstaliraj"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Informacije o aplikaciji"</string>
+    <string name="permlab_install_shortcut" msgid="5632423390354674437">"instaliraj prečice"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Dopušta aplikaciji dodavanje prečica bez posredovanja korisnika."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"čitaj postavke na početnom ekranu i prečice"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Dopušta aplikaciji čitanje postavki i prečica na početnom ekranu."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"zapisuj postavke na početnom ekranu i prečice"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Dopušta aplikaciji promjenu postavki i prečica na početnom ekranu."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nema dozvolu da uspostavlja telefonske pozive"</string>
+    <string name="gadget_error_text" msgid="6081085226050792095">"Problem pri učitavanju dodatka"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Postavljanje"</string>
+    <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">"Neimenovana fascikla"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućena"</string>
+    <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>
+    <string name="workspace_new_page" msgid="257366611030256142">"Nova stranica početnog ekrana"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Fascikla je otvorena, (š) <xliff:g id="WIDTH">%1$d</xliff:g> (v) <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+    <string name="folder_tap_to_close" msgid="4625795376335528256">"Dodirnite da zatvorite folder"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Dodirnite da sačuvate promjenu imena"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"Fascikla je zatvorena"</string>
+    <string name="folder_renamed" msgid="1794088362165669656">"Ime fascikle je promijenjeno u <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_name_format" msgid="6629239338071103179">"Fascikla: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"Dodaci"</string>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Postavke"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio vaš administrator"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Pregled"</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="allow_rotation_blocked_desc" msgid="3212602545192996253">"Trenutne postavke ekrana ne dozvoljavaju rotiranje"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Dodajte ikonu na početni ekran"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Za nove aplikacije"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"Ova aplikacija nije instalirana"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacija za ovu ikonu nije instalirana. Možete je ukloniti ili potražiti aplikaciju i ručno je instalirati."</string>
+    <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> se preuzima, završeno <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> čeka da se instalira"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Vidžeti za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"Dodaj na početni ekran"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Premjesti stavku ovdje"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"Stavka je dodana na Početni ekran."</string>
+    <string name="item_removed" msgid="851119963877842327">"Stavka je uklonjena"</string>
+    <string name="action_move" msgid="4339390619886385032">"Premjesti stavku"</string>
+    <string name="move_to_empty_cell" msgid="2833711483015685619">"Pomjeri stavku u red <xliff:g id="NUMBER_0">%1$s</xliff:g> kolonu <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="move_to_position" msgid="6750008980455459790">"Pomjeri stavku na poziciju <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+    <string name="move_to_hotseat_position" msgid="6295412897075147808">"Pomjeri stavku na poziciju <xliff:g id="NUMBER">%1$s</xliff:g> među favoritima"</string>
+    <string name="item_moved" msgid="4606538322571412879">"Stavka je premještena"</string>
+    <string name="add_to_folder" msgid="9040534766770853243">"Dodaj u folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Dodaj u folder sa aplikacijom <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Stavka je dodana u folder"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Kreirajte folder sa stavkom: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Folder je kreiran"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Pomjeri na početni ekran"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Pomjeri ekran ulijevo"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Pomjeri ekran udesno"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Ekran je pomjeren"</string>
+    <string name="action_resize" msgid="1802976324781771067">"Promijeni veličinu"</string>
+    <string name="action_increase_width" msgid="8773715375078513326">"Povećaj širinu"</string>
+    <string name="action_increase_height" msgid="459390020612501122">"Povećaj visinu"</string>
+    <string name="action_decrease_width" msgid="1374549771083094654">"Smanji širinu"</string>
+    <string name="action_decrease_height" msgid="282377193880900022">"Smanji visinu"</string>
+    <string name="widget_resized" msgid="9130327887929620">"Veličina vidžeta je promijenjena na širinu <xliff:g id="NUMBER_0">%1$s</xliff:g> visinu <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"Prečice"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> prečica za aplikaciju <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 9913d6d..feee97d 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Fons de pantalla"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Configuració"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Configuració de la pantalla d\'inici"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desactivada per l\'administrador"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Visió general"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permet la rotació de la pantalla d\'inici"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconegut"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 03c109d..2560de3 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Složka: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgety"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Nastavení"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Nastavení plochy"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázáno administrátorem"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Přehled"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Povolit otáčení plochy"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Neznámé"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index c16b8c1..521f9ea 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Baggrunde"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Indstillinger"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Indstillinger for startskærmen"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Deaktiveret af din administrator"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Oversigt"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Tillad rotation af startskærmen"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Ukendt"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index c627b74..03eb048 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Ordner: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Hintergründe"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Einstellungen"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Einstellungen für den Startbildschirm"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Von deinem Administrator deaktiviert"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Übersicht"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Drehung des Startbildschirms zulassen"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Unbekannt"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 9f5c01f..a2b44b4 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Φάκελος: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Γραφικά στοιχεία"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Ταπετσαρίες"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Ρυθμίσεις"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Ρυθμίσεις Αρχικής σελίδας"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Απενεργοποιήθηκε από τον διαχειριστή σας"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Επισκόπηση"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Να επιτρέπεται η περιστροφή της αρχικής οθόνης"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Άγνωστο"</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 1a1c1c9..08ef4f4 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Settings"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Overview"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 1a1c1c9..08ef4f4 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Settings"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Overview"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 1a1c1c9..08ef4f4 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpapers"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Settings"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Home settings"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disabled by your admin"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Overview"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Allow Homescreen rotation"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Unknown"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 28d8be3..e4315bb 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Configuración"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Configuración de Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"El administrador inhabilitó esta función"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Recientes"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir la rotación de la pantalla principal"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <string name="icon_shape_system_default" msgid="1709762974822753030">"Usar el sistema predeterminado"</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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index badb33e..3c26910 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Carpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Ajustes"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Ajustes de Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inhabilitada por el administrador"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Visión general"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotación de la pantalla de inicio"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconocido"</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index a1747de..3cd9a9e 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Vidinad"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Taustapildid"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Seaded"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Avalehe seaded"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Keelas administraator"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Ülevaade"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Luba avaekraani pööramine"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Teadmata"</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index afed3b5..91a7333 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -19,35 +19,103 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="8424725141379931883">"Käivitaja"</string>
-    <string name="folder_name" msgid="8551881338202938211"></string>
-    <string name="wallpaper_instructions" msgid="4215640646180727542">"Määra taustapilt"</string>
-    <string name="pick_wallpaper" msgid="5630222540525626723">"Taustapildid"</string>
-    <string name="activity_not_found" msgid="217823393239365967">"Rakendus pole installitud."</string>
-    <string name="long_press_widget_to_add" msgid="7395697462851217506">"Vidina valimiseks puudutage seda pikalt."</string>
-    <string name="widget_dims_format" msgid="1386418557719032947">"%1$d × %2$d"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Sellel avalehel pole enam ruumi."</string>
-    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Kohandataval dokialal pole rohkem ruumi."</string>
-    <string name="all_apps_button_label" msgid="2578400570124163469">"Rakendused"</string>
-    <string name="all_apps_home_button_label" msgid="1022222300329398558">"Kodu"</string>
-    <string name="delete_target_label" msgid="665300185123139530">"Eemalda"</string>
-    <string name="delete_target_uninstall_label" msgid="748894921183769150">"Desinstalli"</string>
-    <string name="info_target_label" msgid="4019495079517426980">"Rakenduse teave"</string>
-    <string name="permlab_install_shortcut" msgid="1201690825493376489">"otseteede installimine"</string>
-    <string name="permdesc_install_shortcut" msgid="8634424803272077038">"Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta."</string>
-    <string name="permlab_read_settings" msgid="3452408290738106747">"avalehe seadete ja otseteede lugemine"</string>
-    <string name="permdesc_read_settings" msgid="5788109303585403679">"Võimaldab rakendusel lugeda avalehe seadeid ja otseteid."</string>
-    <string name="permlab_write_settings" msgid="1360567537236705628">"avalehe seadete ja otseteede kirjutamine"</string>
-    <string name="permdesc_write_settings" msgid="8530105489115785531">"Võimaldab rakendusel muuta avalehel seadeid ja otseteid."</string>
-    <string name="gadget_error_text" msgid="8359351016167075858">"Probleem vidina laadimisel"</string>
-    <string name="uninstall_system_app_text" msgid="6429814133777046491">"See on süsteemirakendus ja seda ei saa desinstallida."</string>
-    <string name="folder_hint_text" msgid="8633351560105748141">"Nimeta kaust"</string>
-    <string name="default_scroll_format" msgid="4057140866420001240">"Leht %1$d/%2$d"</string>
-    <string name="workspace_scroll_format" msgid="1704767047951143301">"Avakuva %1$d/%2$d"</string>
-    <string name="folder_opened" msgid="1262064100943801533">"Kaust on avatud, <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="1335478160661137579">"Puudutage kausta sulgemiseks"</string>
-    <string name="folder_tap_to_rename" msgid="5201612989905472442">"Puudutage uue nime salvestamiseks"</string>
-    <string name="folder_closed" msgid="3130534551370511932">"Kaust suletud"</string>
-    <string name="folder_renamed" msgid="7951233572858053642">"Kausta uus nimi: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="folder_name_format" msgid="3051680259794759037">"<xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+    <string name="folder_name" msgid="7371454440695724752"></string>
+    <string name="work_folder_name" msgid="3753320833950115786">"Töö"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"Rakendus pole installitud."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Rakendus ei ole saadaval"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Allalaetud rakendus on turvarežiimis keelatud"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Turvarežiimis on vidinad keelatud"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"Otsetee pole saadaval"</string>
+    <string name="home_screen" msgid="806512411299847073">"Avaekraan"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Kohandatud toimingud"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidina valimiseks vajutage ja hoidke seda all."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Topeltpuudutage ja hoidke vidina valimiseks või kohandatud toimingute kasutamiseks."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lai ja %2$d kõrge"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Puudutage pikalt, et käsitsi asetada"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Lisa automaatselt"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Otsige rakendustest"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Rakenduste laadimine ..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"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="notifications_header" msgid="1404149926117359025">"Märguanded"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Sellel avaekraanil pole enam ruumi."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Salves Lemmikud pole rohkem ruumi"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Rakenduste loend"</string>
+    <string name="all_apps_home_button_label" msgid="252062713717058851">"Avaekraan"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Eemalda"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalli"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Rakenduse teave"</string>
+    <string name="permlab_install_shortcut" msgid="5632423390354674437">"installi otseteed"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Võimaldab rakendusel lisada otseteid kasutaja sekkumiseta."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"loe avaekraani seadeid ja otseteid"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Võimaldab rakendusel lugeda avaekraanil seadeid ja otseteid."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"kirjuta avaekraani seaded ja otseteed"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Võimaldab rakendusel muuta avaekraanil seadeid ja otseteid."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"Rakendusel <xliff:g id="APP_NAME">%1$s</xliff:g> pole lubatud helistada"</string>
+    <string name="gadget_error_text" msgid="6081085226050792095">"Probleem vidina laadimisel"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Seadistamine"</string>
+    <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>
+    <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>
+    <string name="workspace_new_page" msgid="257366611030256142">"Uus avaekraan"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Kaust on avatud, <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">"Puudutage kausta sulgemiseks"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Puudutage ümbernimetamise salvestamiseks"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"Kaust on suletud"</string>
+    <string name="folder_renamed" msgid="1794088362165669656">"Kausta uus nimi: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_name_format" msgid="6629239338071103179">"Kaust: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"Vidinad"</string>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Taustapildid"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Seaded"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Keelas administraator"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Ülevaade"</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="allow_rotation_blocked_desc" msgid="3212602545192996253">"Praegune kuvaseade ei luba pööramist"</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>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"See rakendus ei ole installitud"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Selle ikooni rakendust pole installitud. Saate selle eemaldada või rakendust otsida ja käsitsi installida."</string>
+    <string name="app_downloading_title" msgid="8336702962104482644">"Rakenduse <xliff:g id="NAME">%1$s</xliff:g> allalaadimine, <xliff:g id="PROGRESS">%2$s</xliff:g> on valmis"</string>
+    <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> on installimise ootel"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Teenuse <xliff:g id="NAME">%1$s</xliff:g> vidinad"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"Lisa avaekraanile"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Teisalda üksus siia"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"Üksus lisati avaekraanile"</string>
+    <string name="item_removed" msgid="851119963877842327">"Üksus eemaldati"</string>
+    <string name="action_move" msgid="4339390619886385032">"Teisalda üksus"</string>
+    <string name="move_to_empty_cell" msgid="2833711483015685619">"Teisaldamine <xliff:g id="NUMBER_0">%1$s</xliff:g>. rea <xliff:g id="NUMBER_1">%2$s</xliff:g>. veergu"</string>
+    <string name="move_to_position" msgid="6750008980455459790">"Teisaldamine <xliff:g id="NUMBER">%1$s</xliff:g>. positsioonile"</string>
+    <string name="move_to_hotseat_position" msgid="6295412897075147808">"Teisaldamine lemmikute <xliff:g id="NUMBER">%1$s</xliff:g>. positsioonile"</string>
+    <string name="item_moved" msgid="4606538322571412879">"Üksus teisaldati"</string>
+    <string name="add_to_folder" msgid="9040534766770853243">"Lisamine kausta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Lisamine kausta nimega <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Üksus lisati kausta"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Kausta loomine nimega <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Kaust on loodud"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Teisalda avaekraanile"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Teisalda ekraan vasakule"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Teisalda ekraan paremale"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Ekraan teisaldati"</string>
+    <string name="action_resize" msgid="1802976324781771067">"Muuda suurust"</string>
+    <string name="action_increase_width" msgid="8773715375078513326">"Suurenda laiust"</string>
+    <string name="action_increase_height" msgid="459390020612501122">"Suurenda kõrgust"</string>
+    <string name="action_decrease_width" msgid="1374549771083094654">"Vähenda laiust"</string>
+    <string name="action_decrease_height" msgid="282377193880900022">"Vähenda kõrgust"</string>
+    <string name="widget_resized" msgid="9130327887929620">"Vidina suurust muudeti. Laius: <xliff:g id="NUMBER_0">%1$s</xliff:g>. Kõrgus: <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"Otseteed"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> otseteed rakenduse <xliff:g id="APP_NAME">%2$s</xliff:g> jaoks"</string>
 </resources>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index aa9c796..dfb969f 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Karpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgetak"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Horma-paperak"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Ezarpenak"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Hasierako pantailaren ezarpenak"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Ikuspegi orokorra"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Baimendu hasierako pantaila biratzea"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Ezezaguna"</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
new file mode 100644
index 0000000..1a4d809
--- /dev/null
+++ b/res/values-eu/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="app_name" msgid="649227358658669779">"Launcher3"</string>
+    <string name="folder_name" msgid="7371454440695724752"></string>
+    <string name="work_folder_name" msgid="3753320833950115786">"Lana"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"Aplikazioa instalatu gabe dago."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Ez dago erabilgarri aplikazioa"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Deskargatutako aplikazioa modu seguruan desgaitu da"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgetak desgaitu egin dira modu seguruan"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"Lasterbideak ez daude erabilgarri"</string>
+    <string name="home_screen" msgid="806512411299847073">"Hasierako pantaila"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Ekintza pertsonalizatuak"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Eduki sakatuta widgeta aukeratzeko."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Sakatu birritan eta eduki sakatuta widgeta aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d zabal eta %2$d luze"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Eduki sakatuta eskuz gehitzeko"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Gehitu automatikoki"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Bilatu aplikazioetan"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Aplikazioak kargatzen…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketarekin bat datorren aplikaziorik"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Bilatu aplikazio gehiago"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Jakinarazpenak"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Hasierako pantaila honetan ez dago toki gehiago."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ez dago toki gehiago Gogokoak erretiluan"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Aplikazioen zerrenda"</string>
+    <string name="all_apps_home_button_label" msgid="252062713717058851">"Hasiera"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Kendu"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalatu"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Aplikazioaren datuak"</string>
+    <string name="permlab_install_shortcut" msgid="5632423390354674437">"Instalatu lasterbideak"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Erabiltzaileak ezer egin gabe lasterbideak gehitzea baimentzen die aplikazioei."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"Irakurri hasierako ezarpenak eta lasterbideak"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Hasierako pantailako ezarpenak eta lasterbideak irakurtzea baimentzen die aplikazioei."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"Idatzi hasierako ezarpenak eta lasterbideak"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Hasierako pantailako ezarpenak eta lasterbideak aldatzea baimentzen die aplikazioei."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak ez du telefono-deiak egiteko baimenik"</string>
+    <string name="gadget_error_text" msgid="6081085226050792095">"Arazo bat izan da widgeta kargatzean"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Konfigurazioa"</string>
+    <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>
+    <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>
+    <string name="workspace_new_page" msgid="257366611030256142">"Hasierako pantailaren orri berria"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Karpeta ireki da: <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">"Karpeta ixteko, sakatu hau"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Izen berria gordetzeko, sakatu hau"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"Karpeta itxi da"</string>
+    <string name="folder_renamed" msgid="1794088362165669656">"Karpetari <xliff:g id="NAME">%1$s</xliff:g> izena eman zaio"</string>
+    <string name="folder_name_format" msgid="6629239338071103179">"Karpeta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"Widgetak"</string>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Horma-paperak"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Ezarpenak"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratzaileak desgaitu du"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Ikuspegi orokorra"</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="allow_rotation_blocked_desc" msgid="3212602545192996253">"Uneko pantaila-ezarpenak ez du onartzen ikuspegia biratzea"</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>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"Aplikazio hau ez dago instalatuta"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Ikono honen aplikazioa ez dago instalatuta. Ikonoa ken dezakezu, edo aplikazioa bilatu eta eskuz instalatu."</string>
+    <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> deskargatzen, <xliff:g id="PROGRESS">%2$s</xliff:g> osatuta"</string>
+    <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> instalatzeko zain"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> widgetak"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"Gehitu hasierako pantailan"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Ekarri elementua hona"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"Gehitu da elementua hasierako pantailan"</string>
+    <string name="item_removed" msgid="851119963877842327">"Kendu da elementua"</string>
+    <string name="action_move" msgid="4339390619886385032">"Mugitu elementua"</string>
+    <string name="move_to_empty_cell" msgid="2833711483015685619">"Eraman <xliff:g id="NUMBER_0">%1$s</xliff:g>. errenkadara, <xliff:g id="NUMBER_1">%2$s</xliff:g>. zutabera"</string>
+    <string name="move_to_position" msgid="6750008980455459790">"Eraman <xliff:g id="NUMBER">%1$s</xliff:g>. postura"</string>
+    <string name="move_to_hotseat_position" msgid="6295412897075147808">"Eraman gogokoen <xliff:g id="NUMBER">%1$s</xliff:g>. postura"</string>
+    <string name="item_moved" msgid="4606538322571412879">"Elementua mugitu da"</string>
+    <string name="add_to_folder" msgid="9040534766770853243">"Gehitu <xliff:g id="NAME">%1$s</xliff:g> karpetan"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Gehitu <xliff:g id="NAME">%1$s</xliff:g> duen karpetan"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Elementua karpetan gehitu da"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Sortu karpeta <xliff:g id="NAME">%1$s</xliff:g> elementuarekin"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Karpeta sortu da"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Eraman hasierako pantailara"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Eraman pantaila ezkerrera"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Eraman pantaila eskuinera"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Mugitu da pantaila"</string>
+    <string name="action_resize" msgid="1802976324781771067">"Aldatu tamaina"</string>
+    <string name="action_increase_width" msgid="8773715375078513326">"Handitu zabalera"</string>
+    <string name="action_increase_height" msgid="459390020612501122">"Handitu altuera"</string>
+    <string name="action_decrease_width" msgid="1374549771083094654">"Txikitu zabalera"</string>
+    <string name="action_decrease_height" msgid="282377193880900022">"Txikitu altuera"</string>
+    <string name="widget_resized" msgid="9130327887929620">"Aldatu da widgetaren tamaina. Zabalera: <xliff:g id="NUMBER_0">%1$s</xliff:g>. Altuera: <xliff:g id="NUMBER_1">%2$s</xliff:g>."</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"Lasterbideak"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioaren <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> lasterbide"</string>
+</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index e66ea80..7da80a4 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"پوشه: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ابزارک‌ها"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"کاغذدیواری‌ها"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"تنظیمات"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"تنظیمات صفحه اصلی"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"توسط سرپرست سیستم غیرفعال شده است"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"نمای کلی"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"امکان دادن به چرخش صفحه اصلی"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"نامشخص"</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index a7db232..b125d45 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Kansio: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgetit"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Taustakuvat"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Asetukset"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Kotiasetukset"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Järjestelmänvalvoja on poistanut toiminnon käytöstä."</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Yleiskatsaus"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Salli aloitusnäytön kiertäminen"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Tuntematon"</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 03757e0..3b7a1ae 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Dossier : <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Paramètres"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Paramètres d\'accueil"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Cette fonction est désactivée par votre administrateur"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Présentation"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 75a693c..ca4c7e7 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Dossier \"<xliff:g id="NAME">%1$s</xliff:g>\""</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Fonds d\'écran"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Paramètres"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Paramètres du domicile"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Désactivé par votre administrateur"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Vue d\'ensemble"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Autoriser la rotation de l\'écran d\'accueil"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Inconnu"</string>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index 4bff56f..c1d2536 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Configuración"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Configuración de inicio"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Función desactivada polo administrador"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Visión xeral"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir xirar a pantalla de inicio"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Descoñecido"</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
new file mode 100644
index 0000000..e8213b5
--- /dev/null
+++ b/res/values-gl/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="app_name" msgid="649227358658669779">"Launcher3"</string>
+    <string name="folder_name" msgid="7371454440695724752"></string>
+    <string name="work_folder_name" msgid="3753320833950115786">"Traballo"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"A aplicación non está instalada"</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"A aplicación non está dispoñible"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"A aplicación que descargaches está desactivada no modo seguro"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Os widgets están desactivados no modo seguro"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"O atallo non está dispoñible"</string>
+    <string name="home_screen" msgid="806512411299847073">"Pantalla de inicio"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Accións personalizadas"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén premido un widget para seleccionalo."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toca dúas veces e mantén premido para seleccionar un widget ou utiliza accións personalizadas."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largo por %2$d de alto"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén premido o elemento para colocalo manualmente"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Engadir automaticamente"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Aplicacións de busca"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Cargando aplicacións..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"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="notifications_header" msgid="1404149926117359025">"Notificacións"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Non hai máis espazo nesta pantalla de inicio."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Non hai máis espazo na bandexa de favoritos"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Lista de aplicacións"</string>
+    <string name="all_apps_home_button_label" msgid="252062713717058851">"Inicio"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Eliminar"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Desinstalar"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Info. da aplicación"</string>
+    <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atallos"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite a unha aplicación engadir atallos sen intervención do usuario."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"ler a configuración e os atallos da pantalla de inicio"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite a unha aplicación ler a configuración e os atallos da páxina de inicio."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"modificar a configuración e os atallos da pantalla de inicio"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite a unha aplicación cambiar a configuración e os atallos da pantalla de inicio."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> non ten permiso para facer chamadas telefónicas"</string>
+    <string name="gadget_error_text" msgid="6081085226050792095">"Produciuse un problema ao cargar o widget"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Configuración"</string>
+    <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>
+    <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>
+    <string name="workspace_new_page" msgid="257366611030256142">"Nova páxina da pantalla de inicio"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Abriuse o cartafol, <xliff:g id="WIDTH">%1$d</xliff:g> por <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+    <string name="folder_tap_to_close" msgid="4625795376335528256">"Toca fóra para pechar o cartafol"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Toca fóra para cambiar o nome do cartafol"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"Pechouse o cartafol"</string>
+    <string name="folder_renamed" msgid="1794088362165669656">"O cartafol cambiou o nome a <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_name_format" msgid="6629239338071103179">"Cartafol: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Fondos de pantalla"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Configuración"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Función desactivada polo administrador"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Visión xeral"</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="allow_rotation_blocked_desc" msgid="3212602545192996253">"A configuración de visualización actual non permite xirar a pantalla"</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>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"Esta aplicación non está instalada"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"A aplicación para esta icona non está instalada. Podes eliminala ou buscar a aplicación e instalala manualmente."</string>
+    <string name="app_downloading_title" msgid="8336702962104482644">"Descargando <xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="PROGRESS">%2$s</xliff:g> completado)"</string>
+    <string name="app_waiting_download_title" msgid="7053938513995617849">"Esperando para instalar <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widgets de: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"Engadir á pantalla de inicio"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Mover elemento aquí"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"Engadiuse o elemento á pantalla de inicio"</string>
+    <string name="item_removed" msgid="851119963877842327">"Eliminouse o elemento"</string>
+    <string name="action_move" msgid="4339390619886385032">"Mover elemento"</string>
+    <string name="move_to_empty_cell" msgid="2833711483015685619">"Mover á fila <xliff:g id="NUMBER_0">%1$s</xliff:g> columna <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="move_to_position" msgid="6750008980455459790">"Mover á posición <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+    <string name="move_to_hotseat_position" msgid="6295412897075147808">"Mover á posición dos favoritos <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+    <string name="item_moved" msgid="4606538322571412879">"Moveuse o elemento"</string>
+    <string name="add_to_folder" msgid="9040534766770853243">"Engadir ao cartafol: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Engadir ao cartafol con <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Engadiuse o elemento ao cartafol"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Crear cartafol con: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Creouse o cartafol"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Mover á pantalla de inicio"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Mover pantalla á esquerda"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Mover pantalla á dereita"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Moveuse a pantalla"</string>
+    <string name="action_resize" msgid="1802976324781771067">"Cambiar tamaño"</string>
+    <string name="action_increase_width" msgid="8773715375078513326">"Aumentar ancho"</string>
+    <string name="action_increase_height" msgid="459390020612501122">"Aumentar altura"</string>
+    <string name="action_decrease_width" msgid="1374549771083094654">"Reducir ancho"</string>
+    <string name="action_decrease_height" msgid="282377193880900022">"Reducir altura"</string>
+    <string name="widget_resized" msgid="9130327887929620">"Cambiouse o tamaño do widget polo ancho <xliff:g id="NUMBER_0">%1$s</xliff:g> e a altura <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"Atallos"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> atallos para <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml
index b243da7..31d92b0 100644
--- a/res/values-gu-rIN/strings.xml
+++ b/res/values-gu-rIN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"ફોલ્ડર: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"વિજેટ્સ"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર્સ"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"સેટિંગ્સ"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"હોમ સેટિંગ્સ"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"વિહંગાવલોકન"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
@@ -83,6 +83,10 @@
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"નવી ઍપ્લિકેશનો માટે"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"આઇકનનો આકાર બદલો"</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>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
new file mode 100644
index 0000000..aa4992d
--- /dev/null
+++ b/res/values-gu/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"વિજેટ ચૂંટવા માટે ટચ કરો અને પકડી રાખો."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"વિજેટ ચૂંટવા અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટેપ કરો અને પકડી રાખો."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d પહોળાઈ X %2$d ઊંચાઈ"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"મેન્યુઅલી મૂકવા માટે ટચ કરી દબાવી રાખો"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"આપમેળે ઉમેરો"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"શોધ ઍપ્લિકેશનો"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"વધુ ઍપ્લિકેશનો શોધો"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"સૂચનાઓ"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"આ હોમ સ્ક્રીન પર વધુ જગ્યા નથી."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"મનપસંદ ટ્રે પર વધુ જગ્યા નથી"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"ઍપ્લિકેશનોની સૂચિ"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"શોર્ટકટ્સ ઇન્સ્ટોલ કરો"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"એપ્લિકેશનને વપરાશકર્તા હસ્તક્ષેપ વગર શોર્ટકટ્સ ઉમેરવાની મંજૂરી આપે છે."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"હોમ સેટિંગ્સ અને શોર્ટકટ્સ વાંચો"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"એપ્લિકેશનને હોમમાં સેટિંગ્સ અને શોર્ટકટ્સ વાંચવાની મંજૂરી આપે છે."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"હોમ સેટિંગ્સ અને શોર્ટકટ્સ લખો"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"એપ્લિકેશનને હોમમાં સેટિંગ્સ અને શોર્ટકટ્સ બદલવાની મંજૂરી આપે છે."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ને ફોન કૉલ્સ કરવાની મંજૂરી નથી"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"અનામી ફોલ્ડર"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> અક્ષમ કરી"</string>
+    <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> બાય <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર્સ"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"સેટિંગ્સ"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"વિહંગાવલોકન"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"જ્યારે ફોન ફેરવવામાં આવે ત્યારે"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"વર્તમાન પ્રદર્શન સેટિંગ ફેરવવાની પરવાનગી આપતી નથી"</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_no_override" msgid="3678524428085518367">"બદલશો નહીં"</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_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="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="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="add_to_folder" msgid="9040534766770853243">"ફોલ્ડરમાં ઉમેરો: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> સાથે ફોલ્ડરમાં ઉમેરો"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"ફોલ્ડરમાં આઇટમ ઉમેરી"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"આની સાથે ફોલ્ડર બનાવો: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ફોલ્ડર બનાવ્યું"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"હોમ સ્ક્રીન પર ખસેડો"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"સ્ક્રીનને ડાબી બાજુ ખસેડો"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"સ્ક્રીનને જમણી બાજુ ખસેડો"</string>
+    <string name="screen_moved" msgid="266230079505650577">"સ્ક્રીન ખસેડી"</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="action_deep_shortcut" msgid="2864038805849372848">"શૉર્ટકટ્સ"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> માટે <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> શૉર્ટકટ"</string>
+</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 9a14ae0..e5b316c 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"फ़ोल्डर: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"शॉर्टकट"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"सेटिंग"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"होम सेटिंग"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपके व्यवस्थापक द्वारा अक्षम"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"अवलोकन"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"होमस्क्रीन घुमाने की अनुमति दें"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"अज्ञात"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 4b6a0bd..de5f9ae 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgeti"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Pozadine"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Postavke"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Postavke Homea"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogućio administrator"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Pregled"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Dopusti zakretanje početnog zaslona"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Nepoznato"</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index c5ac907..f0f597c 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Modulok"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Háttérképek"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Beállítások"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"A Home beállításai"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"A rendszergazda letiltotta"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Áttekintés"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"A kezdőképernyő elforgatásának engedélyezése"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Ismeretlen"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 46e5682..f9fa337 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Պանակ՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Վիջեթներ"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Պաստառներ"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Կարգավորումներ"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Գլխավոր էջի կարգավորումներ"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Անջատվել է ձեր ադմինիստրատորի կողմից"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Համատեսք"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Թույլ տալ հիմնական էկրանի պտտումը"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Անհայտ է"</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
new file mode 100644
index 0000000..7c39a3f
--- /dev/null
+++ b/res/values-hy/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Հպեք և պահեք՝ վիջեթն ընտրելու համար:"</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Կրկնակի հպեք և պահեք՝ վիջեթ ավելացնելու համար կամ օգտվեք հարմարեցրած գործողություններից:"</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Լայնությունը՝ %1$d, բարձրությունը՝ %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Հպեք և պահեք՝ ձեռքով տեղադրելու համար"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Ավելացնել ավտոմատ կերպով"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Հավելվածների որոնում"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Հավելվածների բեռնում…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"«<xliff:g id="QUERY">%1$s</xliff:g>» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Որոնել այլ հավելվածներ"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Ծանուցումներ"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Այլևս տեղ չկա այս հիմնական էկրանին:"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ընտրյալների ցուցակում այլևս ազատ տեղ չկա"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Հավելվածների ցանկ"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"տեղադրել դյուրանցումներ"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Ծրագրին թույլ է տալիս ավելացնել դյուրանցումներ՝ առանց օգտագործողի միջամտության:"</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"կարդալ հիմնաէջի կարգավորումներն ու դյուրանցումները"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Ծրագրին թույլ է տալիս կարդալ հիմնաէջի կարգավորումներն ու դյուրանցումները:"</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"ստեղծել հիմնաէջի կարգավորումներ ու դյուրանցումներ"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Ծրագրին թույլ է տալիս փոփոխել հիմնաէջի կարգավորումներն ու դյուրանցումները:"</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածին չի թույլատրվում հեռախոսազանգեր կատարել"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"Անանուն պանակ"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածն անջատված է"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"Էջ %1$d՝ %2$d-ից"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"Հիմնական էկրան %1$d` %2$d-ից"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"Հիմնական էկրանի նոր էջ"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Պանակը բաց է, <xliff:g id="WIDTH">%1$d</xliff:g>-ից <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Պաստառներ"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Կարգավորումներ"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Անջատվել է ձեր ադմինիստրատորի կողմից"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Համատեսք"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"Թույլ տալ հիմնական էկրանի պտտումը"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"Հեռախոսը պտտելու դեպքում"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Ցուցադրման ընթացիկ կարգավորումներն արգելում են պտտումը"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Ավելացնել պատկերակը Հիմնական էկրանին"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Նոր հավելվածների համար"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"Ավելացնել թղթապանակում՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Ավելացնել «<xliff:g id="NAME">%1$s</xliff:g>» պանակին"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Տարրն ավելացվեց թղթապանակում"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Ստեղծել թղթապանակ, օգտագործելով՝ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Պանակը ստեղծվեց"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Տեղափոխել Հիմնական էկրան"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Տեղափոխել էկրանը ձախ"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Տեղափոխել էկրանը աջ"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Էկրանը տեղափոխվեց"</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="action_deep_shortcut" msgid="2864038805849372848">"Դյուրանցումներ"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> դյուրանցումներ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածի համար"</string>
+</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index fa7b878..3aff82b 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Wallpaper"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Setelan"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Setelan layar Utama"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dinonaktifkan oleh admin"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Ringkasan"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Izinkan layar Utama diputar"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Tidak dikenal"</string>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index 1d7a511..b672245 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Græjur"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Veggfóður"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Stillingar"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Heimastillingar"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gert óvirkt af kerfisstjóra"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Yfirlit"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Leyfa snúning fyrir heimaskjá"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Óþekkt"</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
new file mode 100644
index 0000000..3694a10
--- /dev/null
+++ b/res/values-is/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="app_name" msgid="649227358658669779">"Launcher3"</string>
+    <string name="folder_name" msgid="7371454440695724752"></string>
+    <string name="work_folder_name" msgid="3753320833950115786">"Vinna"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"Forritið er ekki uppsett."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Forritið er ekki í boði"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Sótt forrit er óvirkt í öryggisstillingu"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Græjur eru óvirkar í öruggri stillingu"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"Flýtileið er ekki tiltæk"</string>
+    <string name="home_screen" msgid="806512411299847073">"Heimaskjár"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Sérsniðnar aðgerðir"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Haltu fingri á græju til að grípa hana."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ýttu tvisvar og haltu fingri á græju til að grípa hana eða notaðu sérsniðnar aðgerðir."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d á breidd og %2$d á hæð"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Haltu inni til að staðsetja handvirkt"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Bæta sjálfkrafa við"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Leita í forritum"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Hleður forrit…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"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="notifications_header" msgid="1404149926117359025">"Tilkynningar"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Ekki meira pláss á þessum heimaskjá."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ekki meira pláss í bakka fyrir uppáhald"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Forritalisti"</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="uninstall_drop_target_label" msgid="4722034217958379417">"Fjarlægja"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Forritsupplýsingar"</string>
+    <string name="permlab_install_shortcut" msgid="5632423390354674437">"setja upp flýtileiðir"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Leyfir forriti að bæta við flýtileiðum án íhlutunar notanda."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"lesa stillingar og flýtileiðir heimaskjás"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Leyfir forriti að lesa stillingar og flýtileiðir heimaskjás."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"skrifa stillingar og flýtileiðir heimaskjás"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Leyfir forriti að breyta stillingum og flýtileiðum heimaskjás."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> hefur ekki leyfi til að hringja símtöl"</string>
+    <string name="gadget_error_text" msgid="6081085226050792095">"Vandamál við að hlaða græju"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Uppsetning"</string>
+    <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>
+    <string name="default_scroll_format" msgid="7475544710230993317">"Síða %1$d af %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"Heimaskjár %1$d af %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"Ný síða á heimaskjá"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Mappa opnuð, <xliff:g id="WIDTH">%1$d</xliff:g> sinnum <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+    <string name="folder_tap_to_close" msgid="4625795376335528256">"Ýttu til að loka möppunni"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Ýttu til að vista breytt heiti"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"Möppu lokað"</string>
+    <string name="folder_renamed" msgid="1794088362165669656">"Heiti möppu breytt í <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_name_format" msgid="6629239338071103179">"Mappa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"Græjur"</string>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Veggfóður"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Stillingar"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Gert óvirkt af kerfisstjóra"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Yfirlit"</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="allow_rotation_blocked_desc" msgid="3212602545192996253">"Núverandi skjástilling leyfir ekki snúning"</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>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <string name="package_state_unknown" msgid="7592128424511031410">"Óþekkt"</string>
+    <string name="abandoned_clean_this" msgid="7610119707847920412">"Fjarlægja"</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>
+    <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> í niðurhali, <xliff:g id="PROGRESS">%2$s</xliff:g> lokið"</string>
+    <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> bíður uppsetningar"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g>-græjur"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"Bæta á heimaskjá"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Færa atriði hingað"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"Atriði bætt á heimaskjáinn"</string>
+    <string name="item_removed" msgid="851119963877842327">"Atriði fjarlægt"</string>
+    <string name="action_move" msgid="4339390619886385032">"Færa atriði"</string>
+    <string name="move_to_empty_cell" msgid="2833711483015685619">"Færa í línu <xliff:g id="NUMBER_0">%1$s</xliff:g>, dálk <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="move_to_position" msgid="6750008980455459790">"Færa í stöðu <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+    <string name="move_to_hotseat_position" msgid="6295412897075147808">"Færa í stöðu <xliff:g id="NUMBER">%1$s</xliff:g> á festisvæði"</string>
+    <string name="item_moved" msgid="4606538322571412879">"Atriði fært"</string>
+    <string name="add_to_folder" msgid="9040534766770853243">"Setja í möppu: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Setja í möppu með <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Atriði sett í möppu"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Búa til möppu með: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Mappa búin til"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Færa á heimaskjá"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Færa skjá til vinstri"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Færa skjá til hægri"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Skjár færður"</string>
+    <string name="action_resize" msgid="1802976324781771067">"Breyta stærð"</string>
+    <string name="action_increase_width" msgid="8773715375078513326">"Auka breidd"</string>
+    <string name="action_increase_height" msgid="459390020612501122">"Auka hæð"</string>
+    <string name="action_decrease_width" msgid="1374549771083094654">"Minnka breidd"</string>
+    <string name="action_decrease_height" msgid="282377193880900022">"Minnka hæð"</string>
+    <string name="widget_resized" msgid="9130327887929620">"Stærð græju breytt í <xliff:g id="NUMBER_0">%1$s</xliff:g> á breidd og <xliff:g id="NUMBER_1">%2$s</xliff:g> á hæð"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"Flýtileiðir"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> flýtileiðir fyrir <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index a63d495..9e3fd93 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Cartella: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Sfondi"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Impostazioni"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Impostazioni Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Disattivata dall\'amministratore"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Panoramica"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Consenti rotazione della schermata Home"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Sconosciuto"</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 7f960f2..f02d156 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"תיקיה: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"רכיבי ווידג\'ט"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"טפטים"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"הגדרות"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"הגדרות דף הבית"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"הושבת על ידי מנהל המערכת שלך"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"סקירה"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"אפשרות סיבוב של מסך דף הבית"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"לא ידוע"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 6182eb5..dc6f9bc 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"フォルダ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ウィジェット"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"壁紙"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"設定"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"ホームの設定"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"管理者により無効にされています"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"概要"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ホーム画面の回転を許可"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 7ab510e..5544ee1 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"საქაღალდე: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ვიჯეტები"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"ფონები"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"პარამეტრები"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"მთავარი გვერდის პარამეტრები"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"გათიშულია თქვენი ადმინისტრატორის მიერ"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"მიმოხილვა"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"მთავარი ეკრანის შეტრიალების დაშვება"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"უცნობი"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
new file mode 100644
index 0000000..1979449
--- /dev/null
+++ b/res/values-ka/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"შეეხეთ და დააყოვნეთ ვიჯეტის ასარჩევად."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ორმაგად შეეხეთ და გეჭიროთ ვიჯეტის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"სიგრძე: %1$d, სიგანე: %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ხანგრძლივად შეეხეთ ხელით განსათავსებლად"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"ავტომატურად დამატება"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"აპების ძიება"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"აპები იტვირთება..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"„<xliff:g id="QUERY">%1$s</xliff:g>“-ის თანხვედრი აპები არ მოიძებნა"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"მეტი აპის პოვნა"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"შეტყობინებები"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"ამ მთავარ ეკრანზე ადგილი აღარ არის."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"რჩეულების თაროზე ადგილი არ არის"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"აპების სია"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"მალსახმობების დაყენება"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"აპისთვის მალსახმობების დამოუკიდებლად დამატების უფლების მიცემა."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვა"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების წაკითხვის უფლების მიცემა."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"მთავარი ეკრანის პარამეტრებისა და მალსახმობების ჩაწერა"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"აპისთვის მთავარი ეკრანის პარამეტრებისა და მალსახმობების შეცვლის უფლების მიცემა."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ს არ აქვს სატელეფონო ზარების განხორციელების უფლება"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"უსახელო საქაღალდე"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> გაითიშა"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"გვერდი %1$d %2$d-დან"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"მთავარი ეკრანი %1$d, %2$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_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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"ფონები"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"პარამეტრები"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"გათიშულია თქვენი ადმინისტრატორის მიერ"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"მიმოხილვა"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"მთავარი ეკრანის შეტრიალების დაშვება"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"ტელეფონის შეტრიალებისას"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ბრუნვა დაუშვებელია ჩვენების მიმდინარე პარამეტრებით"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ხატულას მთავარ ეკრანზე დამატება"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ახალი აპებისთვის"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"საქაღალდეში დამატება: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"საქაღალდეში დამატება <xliff:g id="NAME">%1$s</xliff:g>-ით"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"ერთეული დაემატა საქაღალდეს"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"საქაღალდის შექმნა ერთეულით: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"საქაღალდე შექმნილია"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"მთავარ ეკრანზე გადატანა"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"ეკრანის გადატანა მარცხნივ"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"ეკრანის გადატანა მარჯვნით"</string>
+    <string name="screen_moved" msgid="266230079505650577">"ეკრანი გადაადგილდა"</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="action_deep_shortcut" msgid="2864038805849372848">"მალსახმობები"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>-ს აქვს <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> მალსახმობი"</string>
+</resources>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index c49ef3b..1507a58 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Қалта: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Виджеттер"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Тұсқағаздар"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Параметрлер"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Негізгі экран параметрлері"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Әкімші өшірді"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Шолу"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Негізгі экранның бұрылуына рұқсат ету"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Белгісіз"</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
new file mode 100644
index 0000000..5df503a
--- /dev/null
+++ b/res/values-kk/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетті таңдау үшін түртіп, мықтап ұстаңыз."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Виджетті таңдау немесе арнаулы әрекеттерді таңдау үшін екі рет түртіп, ұстап тұрыңыз."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ені: %1$d, биіктігі: %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Қолмен қою үшін басып тұрыңыз"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Автоматты енгізу"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Қолданбаларды іздеу"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Қолданбалар жүктелуде…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"«<xliff:g id="QUERY">%1$s</xliff:g>» сұрауына сәйкес келетін қолданбалар жоқ"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Қосымша қолданбалар іздеу"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Хабарландырулар"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Бұл Негізгі экранда орын қалмады."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Қалаулылар науасында орын қалмады"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Қолданбалар тізімі"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"төте пернелерді орнату"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Қолданбаға пайдаланушының қатысуынсыз төте пернелерді қосу мүмкіндігін береді."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"Негізгі экрандағы параметрлер мен төте пернелерді оқу"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді оқу мүмкіндігін береді."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"Негізгі экран параметрлері мен төте пернелерін жазу"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді өзгерту мүмкіндігін береді."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> арқылы телефон қоңырауларын соғуға рұқсат етілмеген"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"Атауы жоқ қалта"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> өшірілді"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"%1$d бет, барлығы %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"%1$d негізгі экран, барлығы %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"Жаңа негізгі экран беті"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Қалта ашылды, <xliff:g id="WIDTH">%1$d</xliff:g> және <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Тұсқағаздар"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Параметрлер"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Әкімші өшірді"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Шолу"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"Негізгі экранның бұрылуына рұқсат ету"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон бұрылғанда"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Экранның ағымдағы параметрі айналуға рұқсат бермейді"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Негізгі экранға белгіше енгізу"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңа қолданбаларға арналған"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"Қалтаға қосу: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> бар қалтаға қосу"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Элемент қалтаға қосылды"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Мына бар қалтаны жасау: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Қалта жасалды"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Негізгі экранға жылжыту"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Экранды солға жылжыту"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Экранды оңға жылжыту"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Экран жылжытылды"</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="action_deep_shortcut" msgid="2864038805849372848">"Таңбашалар"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасына арналған <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> таңбаша"</string>
+</resources>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 82bf4bb..9f0e72d 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"ថត៖ <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ធាតុ​ក្រាហ្វិក"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"ផ្ទាំង​រូបភាព"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"ការកំណត់"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"ការកំណត់​ទំព័រដើម"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"សង្ខេប"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"មិន​ស្គាល់"</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
new file mode 100644
index 0000000..a64b604
--- /dev/null
+++ b/res/values-km/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"ប៉ះ &amp; សង្កត់ ដើម្បី​ជ្រើស​ធាតុ​ក្រាហ្វិក។"</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ប៉ះពីរដង ហើយចុចឲ្យជាប់ដើម្បីជ្រើសយកធាតុក្រាហ្វិក ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។"</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"ទទឺង %1$d គុណនឹងកម្ពស់ %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ចុច​ឲ្យជាប់​ដើម្បី​បញ្ចូលវា​ដោយផ្ទាល់"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"បញ្ចូល​ដោយ​ស្វ័យ​ប្រវត្តិ"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ស្វែងរកកម្មវិធី"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"កំពុងដំណើរការកម្មវិធី..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"គ្មានកម្មវិធីដែលត្រូវជាមួយ \"<xliff:g id="QUERY">%1$s</xliff:g>\" ទេ"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ស្វែងរកកម្មវិធីច្រើនទៀត"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"ការ​ជូនដំណឹង"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"គ្មាន​បន្ទប់​នៅ​លើ​អេក្រង់​ដើម​នេះ​ទៀត​ទេ។"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"គ្មាន​បន្ទប់​​ក្នុង​ថាស​និយម​ប្រើ"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"បញ្ជីកម្មវិធី"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"ដំឡើង​ផ្លូវកាត់"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​បន្ថែម​ផ្លូវកាត់​ ដោយ​មិន​ចាំបាច់​​អំពើ​ពី​អ្នក​ប្រើ។"</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"អាន​ការ​កំណត់​ និង​ផ្លូវកាត់​​អេក្រង់​ដើម"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​អាន​ការ​កំណត់ និង​ផ្លូវកាត់​ក្នុង​អេក្រង់​ដើម។"</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"សរសេរ​ការ​កំណត់ ​និង​ផ្លូវកាត់​​លើ​អេក្រង់​ដើម"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"អនុញ្ញាត​ឲ្យ​កម្មវិធី​ប្ដូរ​ការ​កំណត់ និង​ផ្លូវ​កាត់​ក្នុង​អេក្រង់​ដើម។"</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> មិនត្រូវបានអនុញ្ញាតឲ្យធ្វើការហៅទូរស័ព្ទទេ"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"ថត​គ្មាន​ឈ្មោះ"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"បានបិទដំណើរការ <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"ទំព័រ %1$d នៃ %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"អេក្រង់​ដើម %1$d នៃ %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"ទំព័រអេក្រង់ដើមថ្មី"</string>
+    <string name="folder_opened" msgid="94695026776264709">"បាន​បើក​ថត <xliff:g id="WIDTH">%1$d</xliff:g> ដោយ <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"ផ្ទាំង​រូបភាព"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"ការកំណត់"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"បានបិទដំណើរការដោយអ្នកគ្រប់គ្រងរបស់អ្នក"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"សង្ខេប"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"អនុញ្ញាតការបងិ្វលអេក្រង់ដើម"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"នៅពេលដែលបង្វិលទូរស័ព្ទរបស់អ្នក"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ការកំណត់អេក្រង់បច្ចុប្បន្នមិនអនុញ្ញាតការបង្វិលទេ"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"បញ្ចូល​រូបតំណាង​ទៅ​អេក្រង់​ដើម"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"សម្រាប់កម្មវិធីថ្មី"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"បន្ថែមទៅថតឯកសារ៖ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"បន្ថែមទៅថតឯកសារដែលមានឈ្មោះ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"បានបន្ថែមធាតុទៅថតឯកសារ"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"បង្កើតថតឯកសារជាមួយ៖ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"បានបង្កើតថតឯកសារ"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"ផ្លាស់ទៅអេក្រង់ដើម"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"រំកិលអេក្រង់ទៅខាងឆ្វេង"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"រំកិលអេក្រង់ទៅខាងស្តាំ"</string>
+    <string name="screen_moved" msgid="266230079505650577">"អេក្រង់ដែលបានផ្លាស់ទី"</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="action_deep_shortcut" msgid="2864038805849372848">"ផ្លូវកាត់"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ផ្លូវកាត់សម្រាប់ <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index 6e61af5..2785ad8 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"ಫೋಲ್ಡರ್: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ವಿಜೆಟ್‌ಗಳು"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"ವಾಲ್‌ಪೇಪರ್‌ಗಳು"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"ಮುಖಪುಟ ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"ಅವಲೋಕನ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
@@ -83,6 +83,10 @@
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ಹೊಸ ಅಪ್ಲಿಕೇಶನ್‌ಗಳಿಗೆ"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"ಐಕಾನ್ ಆಕಾರವನ್ನು ಬದಲಿಸಿ"</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>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
new file mode 100644
index 0000000..b22af0d
--- /dev/null
+++ b/res/values-kn/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"ವಿಜೆಟ್ ಅನ್ನು ಆರಿಸಿಕೊಳ್ಳಲು ಸ್ಪರ್ಶಿಸಿ &amp; ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ವಿಜೆಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ"</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ಅಗಲ ಮತ್ತು %2$d ಎತ್ತರ"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ಹಸ್ತಚಾಲಿತವಾಗಿ ಸೇರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸೇರಿಸಿ"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ಅಪ್ಲಿಕೇಷನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"ಅಧಿಸೂಚನೆಗಳು"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"ಈ ಮುಖಪುಟದ ಪರದೆಯಲ್ಲಿ ಹೆಚ್ಚು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"ಮೆಚ್ಚಿನವುಗಳ ಟ್ರೇನಲ್ಲಿ ಹೆಚ್ಚಿನ ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳ ಪಟ್ಟಿ"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸ್ಥಾಪಿಸಿ"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"ಬಳಕೆದಾರರ ಹಸ್ತಕ್ಷೇಪವಿಲ್ಲದೆ ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಓದಿ"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"ಮುಖಪುಟದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬರೆಯಿರಿ"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"ಮುಖಪುಟದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಲು <xliff:g id="APP_NAME">%1$s</xliff:g> ಅಪ್ಲಿಕೇಶನ್‌‌ಗೆ ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"ಹೆಸರಿಲ್ಲದ ಫೋಲ್ಡರ್"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+    <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> ಬೈ <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"ವಾಲ್‌ಪೇಪರ್‌ಗಳು"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ನಿಮ್ಮ ನಿರ್ವಾಹಕರು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದ್ದಾರೆ"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"ಅವಲೋಕನ"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"ಮುಖಪುಟ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸಿ"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"ಫೋನ್‌ ತಿರುಗಿಸಿದಾಗ"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ಪ್ರಸ್ತುತ ಪ್ರದರ್ಶನ ಸೆಟ್ಟಿಂಗ್ ತಿರುಗುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ"</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_no_override" msgid="3678524428085518367">"ಬದಲಿಸಬೇಡಿ"</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_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="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="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="add_to_folder" msgid="9040534766770853243">"ಫೋಲ್ಡರ್‌ಗೆ ಸೇರಿಸಿ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> ಮೂಲಕ ಫೋಲ್ಡರ್‌ಗೆ ಸೇರಿಸಿ"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"ಐಟಂ ಅನ್ನು ಫೋಲ್ಡರ್‌ಗೆ ಸೇರಿಸಲಾಗಿದೆ"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"ಇದನ್ನು ಬಳಸಿಕೊಂಡು ಫೋಲ್ಡರ್ ರಚಿಸಿ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ಫೋಲ್ಡರ್ ರಚಿಸಲಾಗಿದೆ"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"ಮುಖಪುಟಕ್ಕೆ ಸರಿಸಿ"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"ಪರದೆಯನ್ನು ಎಡಕ್ಕೆ ಸರಿಸಿ"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"ಪರದೆಯನ್ನು ಬಲಕ್ಕೆ ಸರಿಸಿ"</string>
+    <string name="screen_moved" msgid="266230079505650577">"ಪರದೆ ಸರಿಸಲಾಗಿದೆ"</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="action_deep_shortcut" msgid="2864038805849372848">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
+</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index d6226d6..f9185e8 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"폴더: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"위젯"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"배경화면"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"설정"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"홈 설정"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"관리자가 사용 중지함"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"개요"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"홈 화면 회전 허용"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"알 수 없음"</string>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index bdfd15c..87d98c5 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Виджеттер"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Тушкагаздар"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Жөндөөлөр"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Башкы беттин жөндөөлөрү"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Көз жүгүртүү"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Башкы экранды айлантууга уруксат берүү"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Белгисиз"</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
new file mode 100644
index 0000000..2162292
--- /dev/null
+++ b/res/values-ky/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетти тандаш үчүн, басып туруңуз"</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Виджет тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Туурасы: %1$d, бийиктиги: %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Кол менен жайгаштыруу үчүн басып туруп, таштаңыз"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Автоматтык түрдө кошуу"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Колдонмолорду издөө"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Колдонмолор жүктөлүүдө…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" дал келген колдонмолор табылган жок"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Көбүрөөк колдонмолорду издөө"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Эскертмелер"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Бул Үй экранында бош орун жок."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Тандамалдар тайпасында орун калган жок"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Колдонмолор тизмеси"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"тез чакырмаларды орнотуу"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Колдонмого колдонуучуга кайрылбастан тез чакырма кошууга уруксат берет."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"Үйдүн тууралоолорун жана тез чакырмаларын окуу"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Колдонмого Үйдүн тууралоолорун жана тез чакырмаларын окууга уруксат берет."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"Үйдүн тууралоолорун жана тез чакырмаларын жазуу"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Колдонмого Үйдүн тууралоолорун жана тез чакырмаларын өзгөртүүгө уруксат берет."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> телефон чалууларды аткарууга уруксаты жок"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"Аты жок фолдер"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> өчүрүлгөн"</string>
+    <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>, бийиктиги <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Тушкагаздар"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Тууралоолор"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администраторуңуз өчүрүп койгон"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Көз жүгүртүү"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"Башкы экранды айлантууга уруксат берүү"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"Телефон айланганда"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Экранды айлантуу параметри өчүрүлгөн"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Башкы экранга сүрөтчө кошуу"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Жаңы колдонмолор үчүн"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"Куржунга кошуу: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> куржунуна кошуу"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Нерсе куржунга кошулду"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Төмөнкү менен куржун түзүү: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Куржун түзүлдү"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Башкы экранга жылдыруу"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Экранды солго жылдыруу"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Экранды оңго жылдыруу"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Экран жылдырылды"</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="action_deep_shortcut" msgid="2864038805849372848">"Кыска жолдор"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> колдонмосуна <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> кыска жол бар"</string>
+</resources>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 799db3c..9530aef 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"ໂຟນເດີ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ວິດເຈັດ"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"ພາບພື້ນຫຼັງ"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"ການຕັ້ງຄ່າ"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"ການຕັ້ງຄ່າ Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"ພາບຮວມ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍທຳອິດໄດ້"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"​ບໍ່​ຮູ້​ຈັກ"</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
new file mode 100644
index 0000000..334305a
--- /dev/null
+++ b/res/values-lo/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="safemode_shortcut_error" msgid="9160126848219158407">"ແອັບຯ​ທີ່​ດາວ​ໂຫລດ​ແລ້ວ​ຖືກ​ປິດ​ການ​ນຳ​ໃຊ້​ໃນ Safe mode"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"​ວິດ​ເຈັດ​ຖືກ​ປິດ​ໃນ Safe mode"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"ບໍ່ສາມາດໃຊ້ທາງລັດໄດ້"</string>
+    <string name="home_screen" msgid="806512411299847073">"ໜ້າຈໍຫຼັກ"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"ຄຳສັ່ງແບບກຳນົດເອງ"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"ສຳພັດຄ້າງໄວ້ ເພື່ອຈັບວິດເຈັດ."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ແຕະ​ຄ້າງ​ໄວ້ ເພື່ອ​ເລືອກວິດ​ເຈັດ ຫຼື ໃຊ້​ການ​ດຳ​ເນີນ​ການ​ກຳ​ນົດ​ເອງ."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"ກວ້າງ %1$d ຄູນສູງ %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ແຕະຄ້າງໄວ້ເພື່ອວາງດ້ວຍຕົນເອງ"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"ເພີ່ມໂດຍອັດຕະໂນມັດ"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ຊອກຫາແອັບ"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"​ກຳ​ລັງ​ໂຫລດ​ແອັບ..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"ບໍ່​ພົບ​ແອັບ​ໃດ​ທີ່​ກົງ​ກັນ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ຊອກຫາແອັບເພີ່ມເຕີມ"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"ການແຈ້ງເຕືອນ"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"ບໍ່ມີຫ້ອງເຫຼືອໃນໜ້າຈໍຫຼັກນີ້."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"ບໍ່ມີບ່ອນຫວ່າງໃນຖາດສຳລັບເກັບສິ່ງທີ່ໃຊ້ເປັນປະຈຳ"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"ລາຍຊື່ແອັບ"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"ຕິດຕັ້ງທາງລັດ"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"ອະນຸຍາດໃຫ້ແອັບຯ ເພີ່ມທາງລັດໂດຍບໍ່ຕ້ອງຮັບການຢືນຢັນຈາກຜູ່ໃຊ້."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"ອ່ານການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວອ່ານການຕັ້ງຄ່າ ແລະທາງລັດໃນໜ້າຫຼັກ."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"ຂຽນການຕັ້ງຄ່າໜ້າຫຼັກ ແລະທາງລັດ"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"ອະນຸຍາດໃຫ້ແອັບຯດັ່ງກ່າວ ປ່ຽນການຕັ້ງຄ່າ ແລະທາງລັດໃນໜ້າຫຼັກ."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ່​ໄດ້​ຮັບ​ອະ​ນຸ​ຍາດ​ໃຫ້​ໂທ"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"ໂຟນເດີຍັງບໍ່ຖືກຕັ້ງຊື່"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"ປິດການນຳໃຊ້ <xliff:g id="APP_NAME">%1$s</xliff:g> ແລ້ວ"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"ໜ້າ %1$d ຈາກ %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"ໜ້າຈໍຫຼັກ %1$d ໃນ %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"ໜ້າ​ຂອງ​ໜ້າ​ຈໍ​ຫຼັກ​ໃໝ່"</string>
+    <string name="folder_opened" msgid="94695026776264709">"ເປີດໂຟນເດີແລ້ວ, <xliff:g id="WIDTH">%1$d</xliff:g> ຄູນ <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"ພາບພື້ນຫຼັງ"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"ການຕັ້ງຄ່າ"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ຖືກປິດການນຳໃຊ້ໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"ພາບຮວມ"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"ອະນຸຍາດໃຫ້ໝຸນໜ້າຈໍທຳອິດໄດ້"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"ເມື່ອໝຸນໂທລະສັບ"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ການຕັ້ງຄ່າສະແດງຜົນປັດຈຸບັນບໍ່ອະນຸຍາດໃຫ້ໝຸນໄດ້"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ເພີ່ມໄອຄອນໃສ່ໜ້າຈໍຫຼັກ"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ສຳລັບແອັບໃໝ່"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="action_add_to_workspace" msgid="8902165848117513641">"ເພີ່ມໃສ່ໜ້າຈໍຫຼັກ"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Move item here"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"ເພີ່ມ​ລາຍ​ການ​ໃສ່​ໜ້າ​ຈໍ​ຫຼັກ​ແລ້ວ"</string>
+    <string name="item_removed" msgid="851119963877842327">"ເອົາ​ລາຍ​ການ​ອອກ​ໄປ​ແລ້ວ"</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="add_to_folder" msgid="9040534766770853243">"ເພີ່ມ​ໃສ່​ໂຟ​ລ​ເດີ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"ເພີ່ມ​ໃສ່​ໂຟ​ລ​ເດີ​ດ້ວຍ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"ເພີ່ມ​ລາຍ​ການ​ໃສ່​ໂຟ​ລ​ເດີ​ແລ້ວ"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"ສ້າງ​ໂຟ​ລ​ເດີ​ກັບ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ສ້າງ​ໂຟ​ລ​ເດີ​ແລ້ວ"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"ຍ້າຍ​ໄປ​ໃສ່​ໜ້າ​ຈໍ​ຫຼັກ"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"ຍ້າຍ​ໜ້າ​ຈໍ​ໄປ​ທາງ​ຊ້າຍ"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"ຍ້າຍ​ໜ້າ​ຈໍ​ໄປ​ທາງ​ຂວາ"</string>
+    <string name="screen_moved" msgid="266230079505650577">"ຍ້າຍ​ໜ້າ​ຈໍ​ແລ້ວ"</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="action_deep_shortcut" msgid="2864038805849372848">"ທາງລັດ"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ທາງລັດສຳລັບ <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index bbf7f1a..517e611 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Aplankas: „<xliff:g id="NAME">%1$s</xliff:g>“"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Valdikliai"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Ekrano fonai"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Nustatymai"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"„Home“ nustatymai"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Išjungė administratorius"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Apžvalga"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Leisti pasukti pagrindinį ekraną"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Nežinoma"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 75e1bef..0c00bda 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Mape: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Logrīki"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Fona tapetes"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Iestatījumi"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Sākumlapas iestatījumi"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Atspējojis administrators"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Kopsavilkums"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Atļaut sākuma ekrāna pagriešanu"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Nezināma"</string>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index f0c1b64..f994892 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Папка: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Додатоци"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Позадини"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Поставки"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Поставки за Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Оневозможено од администраторот"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Краток преглед"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Дозволете ротација на Почетниот екран"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
new file mode 100644
index 0000000..267e75b
--- /dev/null
+++ b/res/values-mk/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="app_name" msgid="649227358658669779">"Стартер3"</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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Допри и задржи за да се избере виџетот."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Допрете двапати и задржете за да изберете додаток или да користите приспособени дејства."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d широк на %2$d висок"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Допрете и задржете за рачно поставување"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Додај автоматски"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Пребарување апликации"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Се вчитуваат апликации…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Не се најдени апликации што одговараат на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Пребарај други апликации"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Известувања"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Нема повеќе простор на овој екран на почетната страница."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Нема повеќе простор на лентата „Омилени“"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Список со апликации"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"инсталирај кратенки"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Овозможува апликацијата да додава кратенки без интервенција на корисникот."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"чита поставки и кратенки на почетна страница"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Овозможува апликацијата да ги менува подесувањата и кратенките на почетната страница."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"пишува поставки и кратенки на почетна страница"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Овозможува апликацијата да ги менува подесувањата и кратенките на почетната страница."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> нема дозвола за телефонски повици"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"Неименувана папка"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> е оневозможена"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"Страница %1$d од %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"Екран на почетна страница %1$d од %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"Нова страница на почетен екран"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Отворена е папка, <xliff:g id="WIDTH">%1$d</xliff:g> на <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Позадини"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Поставки"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Оневозможено од администраторот"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Краток преглед"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"Дозволете ротација на Почетниот екран"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"Кога телефонот се ротира"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Тековната поставка на Екранот не дозволува ротација"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Додајте икона на почетниот екран"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"За нови апликации"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"Додај во папката: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Додај во папка со <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Ставката е додадена во папката"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Создај папка со: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Папката е создадена"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Премести на Почетен екран"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Движи го екранот налево"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Движи го екранот надесно"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Екранот е преместен"</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="action_deep_shortcut" msgid="2864038805849372848">"Кратенки"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> кратенки за <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index 9dc4bb1..5995c5c 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"ഫോൾഡർ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"വിജറ്റുകൾ"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"വാൾപേപ്പർ"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"ക്രമീകരണം"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"ഹോം ക്രമീകരണം"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"കാഴ്ച"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"</string>
@@ -83,6 +83,10 @@
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"പുതിയ ആപ്പുകൾക്ക്"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"ഐക്കണിന്റെ ആകാരം മാറ്റുക"</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>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
new file mode 100644
index 0000000..a92fc03
--- /dev/null
+++ b/res/values-ml/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="app_name" msgid="649227358658669779">"ലോഞ്ചർ3"</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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"ഒരു വിജറ്റ് ചേർക്കുന്നതിന് അത് സ്‌പർശിച്ച് പിടിക്കുക."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"വിജറ്റ് തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ രണ്ടുതവണ ടാപ്പുചെയ്ത് പിടിക്കുക."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d വീതിയും %2$d ഉയരവും"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"സ്വമേധയാ സ്ഥാപിക്കുന്നതിന് സ്‌പർശിച്ചുപിടിക്കുക"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"സ്വയമേവ ചേർക്കുക"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ആപ്പുകളെ തിരയുക"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"ആപ്പ്‌സ് ലോഡുചെയ്യുന്നു..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പ്‌സൊന്നും കണ്ടെത്തിയില്ല"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"കൂടുതൽ ആപ്പുകൾക്ക് തിരയുക"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"അറിയിപ്പുകൾ"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"ഈ ഹോം സ്‌ക്രീനിൽ ഒഴിവൊന്നുമില്ല."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"പ്രിയപ്പെട്ടവയുടെ ട്രേയിൽ ഒഴിവൊന്നുമില്ല"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"അപ്ലിക്കേഷനുകളുടെ ലിസ്‌റ്റ്"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"കുറുക്കുവഴികൾ ഇൻസ്റ്റാളുചെയ്യുക"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"ഉപയോക്തൃ ഇടപെടൽ ഇല്ലാതെ കുറുക്കുവഴികൾ ചേർക്കാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റീഡുചെയ്യുക"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റൈറ്റുചെയ്യുക"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും മാറ്റാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"ഫോൺ കോൾ ചെയ്യാൻ <xliff:g id="APP_NAME">%1$s</xliff:g> എന്നതിനെ അനുവദിച്ചിട്ടില്ല"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"പേരുനൽകാത്ത ഫോൾഡർ"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> പ്രവർത്തനരഹിതമാക്കി"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"പേജ് %1$d / %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"ഹോം സ്‌ക്രീൻ %1$d / %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"പുതിയ ഹോം സ്ക്രീൻ പേജ്"</string>
+    <string name="folder_opened" msgid="94695026776264709">"ഫോൾഡർ തുറന്നു, <xliff:g id="WIDTH">%1$d</xliff:g> / <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"വാൾപേപ്പർ"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"ക്രമീകരണം"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"കാഴ്ച"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"ഫോൺ തിരിച്ച നിലയിലായിരിക്കുമ്പോൾ"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"നിലവിലെ ഡിസ്പ്ലേ ക്രമീകരണം തിരിക്കൽ അനുവദിക്കുന്നില്ല"</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_no_override" msgid="3678524428085518367">"മാറ്റരുത്"</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_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="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="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="add_to_folder" msgid="9040534766770853243">"ഫോൾഡറിൽ ചേർക്കുക: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> ഉള്ള ഫോൾഡറിൽ ചേർക്കുക"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"ഫോൾഡറിൽ ഇനം ചേർത്തു"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"ഇതുപയോഗിച്ച് ഫോൾഡർ സൃഷ്‌ടിക്കുക: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ഫോൾഡർ സൃഷ്‌ടിച്ചു"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"ഹോം സ്‌ക്രീനിലേക്ക് നീക്കുക"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"സ്‌ക്രീൻ ഇടത്തേക്ക് നീക്കുക"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"സ്‌ക്രീൻ വലത്തേക്ക് നീക്കുക"</string>
+    <string name="screen_moved" msgid="266230079505650577">"സ്‌ക്രീൻ നീക്കി"</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="action_deep_shortcut" msgid="2864038805849372848">"കുറുക്കുവഴികൾ"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ആപ്പിനുള്ള <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> കുറുക്കുവഴികൾ"</string>
+</resources>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index c1accc5..11e7959 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Фолдер: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Виджет"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Ханын зураг"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Тохиргоо"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Нүүр хуудасны тохиргоо"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Таны админ идэвхгүй болгосон"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Тойм"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Нүүр дэлгэцийг эргүүлэхийг зөвшөөрөх"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Тодорхойгүй"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
new file mode 100644
index 0000000..5b74fd2
--- /dev/null
+++ b/res/values-mn/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="safemode_shortcut_error" msgid="9160126848219158407">"Татаж авсан апп-г Аюулгүй горим дотроос идэвхгүйжүүлсэн"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Safe горимд виджетүүдийг идэвхгүйжүүлсэн"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"Товчлол алга"</string>
+    <string name="home_screen" msgid="806512411299847073">"Үндсэн нүүр"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Захиалгат үйлдэл"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетийг авах бол хүрээд барина уу."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Жижиг хэрэгсэл авах болон тохируулсан үйлдлийг ашиглахын тулд 2 удаа товшоод барина уу."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d өргөн %2$d өндөр"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Гараар байршуулахын тулд дараад хүлээнэ үү"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Автоматаар нэмэх"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Апп хайх"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Аппликейшныг ачаалж байна..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"-д нийцэх апп олдсонгүй"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Бусад апп-г хайх"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Мэдэгдэл"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Энэ Нүүр дэлгэц зайгүй."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"\"Дуртай\" трей дээр өөр зай байхгүй байна"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Апп-н жагсаалт"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"товчлол суулгах"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Апп нь хэрэглэгчийн оролцоогүйгээр товчлолыг нэмэж чадна"</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"Нүүрний тохиргоо болон товчлолыг унших"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Апп нь Нүүрэндэх товчлол болон тохиргоог уншиж чадна."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"Нүүрний тохиргоо болон товчлолыг бичих"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Апп нь Нүүрэндэх товчлол болон тохиргоог өөрчилж чадна."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> утасны дуудлага хийх боломжгүй"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"Нэргүй фолдер"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g>-г идэвхгүй болгосон"</string>
+    <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> <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Ханын зураг"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Тохиргоо"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Таны админ идэвхгүй болгосон"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Тойм"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"Нүүр дэлгэцийг эргүүлэхийг зөвшөөрөх"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"Утсыг эргүүлсэн үед"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Дэлгэцийн одоогийн тохиргоогоор эргүүлэх боломжгүй"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Нүүр хуудаст дүрс тэмдэг нэмэх"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Шинэ аппад зориулсан"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"Хавтас: <xliff:g id="NAME">%1$s</xliff:g> руу нэм"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g>-тай хавтас нэмэх"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Хавтсанд нэмэгдсэн зүйл"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Хавтсыг: <xliff:g id="NAME">%1$s</xliff:g> нэрээр үүсгэ"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Үүсгэсэн хавтас"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Нүүр дэлгэц рүү зөөх"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Дэлгэцийг зүүн тийш зөөх"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Дэлгэцийг баруун тийш зөөх"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Дэлгэцийг зөөсөн"</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="action_deep_shortcut" msgid="2864038805849372848">"Товчлол"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>-н <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> товчлол"</string>
+</resources>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index a7a8c80..f9443a1 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"विजेट"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"सेटिंग्ज"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"होम सेटिंग्‍ज"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपल्या प्रशासकाने अक्षम केले"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"विहंगावलोकन"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"मुख्यस्क्रीन फिरविण्‍यास अनुमती द्या"</string>
@@ -83,6 +83,10 @@
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नवीन अॅप्ससाठी"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"चिन्हाचा आकार बदला"</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>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
new file mode 100644
index 0000000..1a10e4b
--- /dev/null
+++ b/res/values-mr/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"विजेट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"एक विजेट निवडण्यासाठी दोनदा टॅप करा आणि धरून ठेवा किंवा सानुकूल क्रिया वापरा."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d रूंद बाय %2$d उंच"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"स्वयंचलितपणे जोडा"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"अॅप्स शोधा"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"अॅप्स लोड करीत आहे..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक अॅप्स शोधा"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"सूचना"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"या मुख्य स्क्रीनवर आणखी जागा नाही."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"आवडीच्या ट्रे मध्ये आणखी जागा नाही"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"अॅप्स सूची"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट स्‍थापित करा"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"वापरकर्ता हस्तक्षेपाशिवाय शॉर्टकट जोडण्यास अॅप ला अनुमती देते."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"मुख्यपृष्ठ सेटिंग्ज आणि शॉर्टकट वाचा"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट वाचण्यास अॅप ला अनुमती देते."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"मुख्यपृष्ठ सेटिंग्ज आणि शॉर्टकट लिहा"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अॅप ला अनुमती देते."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ला फोन कॉल करण्याची अनुमती नाही"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"अनामित फोल्डर"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> अक्षम केला आहे"</string>
+    <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> बाय <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"सेटिंग्ज"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपल्या प्रशासकाने अक्षम केले"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"विहंगावलोकन"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"मुख्यस्क्रीन फिरविण्‍यास अनुमती द्या"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"फोन फिरविला जातो तेव्हा"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"वर्तमान प्रदर्शन सेटिंग फिरविण्यास परवानगी देत नाही"</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_no_override" msgid="3678524428085518367">"बदलू नका"</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_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="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="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="add_to_folder" msgid="9040534766770853243">"फोल्‍डरवर जोडा: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> सह फोल्डरमध्ये जोडा"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"फोल्‍डरमध्‍ये आयटम जोडले"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"यासह फोल्‍डर तयार करा: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"फोल्‍डर तयार केले"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"मुख्य स्क्रीनवर हलवा"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"स्क्रीन डावीकडे हलवा"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"स्क्रीन उजवीकडे हलवा"</string>
+    <string name="screen_moved" msgid="266230079505650577">"स्क्रीन हलविली"</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="action_deep_shortcut" msgid="2864038805849372848">"शॉर्टकट"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> साठी <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> शॉर्टकट"</string>
+</resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index b94b8c7..385a943 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Kertas dinding"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Tetapan"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Tetapan laman utama"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dilumpuhkan oleh pentadbir anda"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Ikhtisar"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Benarkan putaran Skrin Utama"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Tidak diketahui"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 7335605..756a2cf 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -19,35 +19,103 @@
 
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="application_name" msgid="8424725141379931883">"Pelancar"</string>
-    <string name="folder_name" msgid="8551881338202938211"></string>
-    <string name="wallpaper_instructions" msgid="4215640646180727542">"Tetapkan kertas dinding"</string>
-    <string name="pick_wallpaper" msgid="5630222540525626723">"Kertas dinding"</string>
-    <string name="activity_not_found" msgid="217823393239365967">"Aplikasi tidak dipasang."</string>
-    <string name="long_press_widget_to_add" msgid="7395697462851217506">"Sentuh &amp; tahan untuk mengambil widget."</string>
-    <string name="widget_dims_format" msgid="1386418557719032947">"%1$d × %2$d"</string>
-    <string name="out_of_space" msgid="8365249326091984698">"Tiada lagi ruang pada skrin Utama ini"</string>
-    <string name="hotseat_out_of_space" msgid="6304886797358479361">"Tiada lagi ruang pada kerusi panas."</string>
-    <string name="all_apps_button_label" msgid="2578400570124163469">"Apl"</string>
-    <string name="all_apps_home_button_label" msgid="1022222300329398558">"Laman Utama"</string>
-    <string name="delete_target_label" msgid="665300185123139530">"Alih keluar"</string>
-    <string name="delete_target_uninstall_label" msgid="748894921183769150">"Nyahpasang"</string>
-    <string name="info_target_label" msgid="4019495079517426980">"Maklumat apl"</string>
-    <string name="permlab_install_shortcut" msgid="1201690825493376489">"pasang pintasan"</string>
-    <string name="permdesc_install_shortcut" msgid="8634424803272077038">"Membenarkan aplikasi menambah pintasan tanpa campur tangan pengguna."</string>
-    <string name="permlab_read_settings" msgid="3452408290738106747">"membaca tetapan dan pintasan Laman Utama"</string>
-    <string name="permdesc_read_settings" msgid="5788109303585403679">"Membenarkan apl membaca tetapan dan pintasan di Laman Utama."</string>
-    <string name="permlab_write_settings" msgid="1360567537236705628">"menulis tetapan dan pintasan Laman Utama"</string>
-    <string name="permdesc_write_settings" msgid="8530105489115785531">"Membenarkan apl menukar tetapan dan pintasan di Laman Utama."</string>
-    <string name="gadget_error_text" msgid="8359351016167075858">"Masalah memuatkan widget"</string>
-    <string name="uninstall_system_app_text" msgid="6429814133777046491">"Ini adalah aplikasi sistem dan tidak boleh dinyahpasang."</string>
-    <string name="folder_hint_text" msgid="8633351560105748141">"Folder Tanpa Nama"</string>
-    <string name="default_scroll_format" msgid="4057140866420001240">"Halaman %1$d dari %2$d"</string>
-    <string name="workspace_scroll_format" msgid="1704767047951143301">"Skrin utama %1$d dari %2$d"</string>
-    <string name="folder_opened" msgid="1262064100943801533">"Folder dibuka, <xliff:g id="WIDTH">%1$d</xliff:g> kali <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
-    <string name="folder_tap_to_close" msgid="1335478160661137579">"Sentuh untuk menutup folder"</string>
-    <string name="folder_tap_to_rename" msgid="5201612989905472442">"Sentuh untuk menyimpan penamaan semula"</string>
-    <string name="folder_closed" msgid="3130534551370511932">"Folder ditutup"</string>
-    <string name="folder_renamed" msgid="7951233572858053642">"Folder dinamakan semula kepada <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="folder_name_format" msgid="3051680259794759037">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
+    <string name="folder_name" msgid="7371454440695724752"></string>
+    <string name="work_folder_name" msgid="3753320833950115786">"Kerja"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"Apl tidak dipasang."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Apl tidak tersedia"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Apl yang dimuat turun dilumpuhkan dalam mod Selamat"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widget dilumpuhkan dalam mod Selamat"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"Pintasan tidak tersedia"</string>
+    <string name="home_screen" msgid="806512411299847073">"Skrin utama"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Tindakan tersuai"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Sentuh &amp; tahan untuk mengambil widget."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ketik dua kali &amp; tahan untuk mengambil widget atau menggunakan tindakan tersuai"</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Lebar %1$d kali tinggi %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh &amp; tahan untuk meletakkan widget/ikon secara manual"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Tambahkan secara automatik"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Cari Apl"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Memuatkan Apl…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"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="notifications_header" msgid="1404149926117359025">"Pemberitahuan"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Tiada lagi ruang pada skrin Laman Utama ini."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Tiada ruang dalam dulang Kegemaran lagi"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Senarai apl"</string>
+    <string name="all_apps_home_button_label" msgid="252062713717058851">"Laman Utama"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Alih keluar"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Nyahpasang"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Maklumat apl"</string>
+    <string name="permlab_install_shortcut" msgid="5632423390354674437">"pasang pintasan"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Membenarkan apl menambah pintasan tanpa campur tangan pengguna."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"baca tetapan dan pintasan Laman Utama"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Membenarkan apl membaca tetapan dan pintasan di Laman Utama."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"tulis tetapan dan pintasan Laman Utama"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Membenarkan apl menukar tetapan dan pintasan di Laman Utama."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> tidak dibenarkan membuat panggilan telefon"</string>
+    <string name="gadget_error_text" msgid="6081085226050792095">"Masalah memuatkan widget"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Persediaan"</string>
+    <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>
+    <string name="default_scroll_format" msgid="7475544710230993317">"Halaman %1$d daripada %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"Skrin Laman Utama %1$d daripada %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"Halaman skrin utama baharu"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Folder dibuka, <xliff:g id="WIDTH">%1$d</xliff:g> kali <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+    <string name="folder_tap_to_close" msgid="4625795376335528256">"Ketik untuk menutup folder"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Ketik untuk menyimpan penamaan semula"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"Folder ditutup"</string>
+    <string name="folder_renamed" msgid="1794088362165669656">"Folder dinamakan semula kepada <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Kertas dinding"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Tetapan"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dilumpuhkan oleh pentadbir anda"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Ikhtisar"</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="allow_rotation_blocked_desc" msgid="3212602545192996253">"Tetapan Paparan semasa tidak membenarkan putaran"</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>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"Apl ini tidak dipasang"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Apl untuk ikon ini tidak dipasang. Anda boleh mengalih keluar atau mencari dan memasang apl itu secara manual."</string>
+    <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> memuat turun, <xliff:g id="PROGRESS">%2$s</xliff:g> selesai"</string>
+    <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> menunggu untuk dipasang"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Widget <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"Tambahkan pada Skrin Utama"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Alihkan item ke sini"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"Item ditambahkan pada skrin utama"</string>
+    <string name="item_removed" msgid="851119963877842327">"Item dialih keluar"</string>
+    <string name="action_move" msgid="4339390619886385032">"Alihkan Item"</string>
+    <string name="move_to_empty_cell" msgid="2833711483015685619">"Alihkan ke baris <xliff:g id="NUMBER_0">%1$s</xliff:g> lajur <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="move_to_position" msgid="6750008980455459790">"Alihkan ke kedudukan <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+    <string name="move_to_hotseat_position" msgid="6295412897075147808">"Alihkan ke kedudukan kegemaran <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+    <string name="item_moved" msgid="4606538322571412879">"Item dialihkan"</string>
+    <string name="add_to_folder" msgid="9040534766770853243">"Tambahkan pada folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Tambahkan pada folder dengan <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Item ditambahkan pada folder"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Buat folder dengan: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Folder dibuat"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Alihkan ke Skrin Utama"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Alihkan skrin ke kiri"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Alihkan skrin ke kanan"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Skrin dialihkan"</string>
+    <string name="action_resize" msgid="1802976324781771067">"Ubah saiz"</string>
+    <string name="action_increase_width" msgid="8773715375078513326">"Tambahkan kelebaran"</string>
+    <string name="action_increase_height" msgid="459390020612501122">"Tambahkan ketinggian"</string>
+    <string name="action_decrease_width" msgid="1374549771083094654">"Kurangkan kelebaran"</string>
+    <string name="action_decrease_height" msgid="282377193880900022">"Kurangkan ketinggian"</string>
+    <string name="widget_resized" msgid="9130327887929620">"Saiz widget diubah menjadi <xliff:g id="NUMBER_0">%1$s</xliff:g> lebar <xliff:g id="NUMBER_1">%2$s</xliff:g> tinggi"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"Pintasan"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> pintasan untuk <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
 </resources>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index c8bad18..0588aaa 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"အကန့်အမည်: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ဝိဂျက်များ"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"နောက်ခံများ"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"ဆက်တင်များ"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"ပင်မဆက်တင်များ"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"ခြုံငုံသုံးသပ်ချက်"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုပါ"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"မသိရ"</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
new file mode 100644
index 0000000..449aae8
--- /dev/null
+++ b/res/values-my/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="app_name" msgid="649227358658669779">"ဖွင့်တင်စက်၃"</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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"ဝဒ်ဂျက်တစ်ခုကို ကောက်ယူရန် ဖိနှိပ်ထားပါ"</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ဝစ်ဂျက်တစ်ခုကိုရယူရန် သို့မဟုတ် စိတ်ကြိုက်လုပ်ဆောင်မှုများကို အသုံးပြုရန် နှစ်ချက်တို့ပြီး ကိုင်ထားပါ။"</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"အလျား %1$d နှင့် အမြင့် %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ကိုယ်တိုင်ထည့်ရန် ထိထားပါ"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"အလိုအလျောက် ထည့်ရန်"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ရှာဖွေမှု အက်ပ်များ"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"အက်ပ်များ ရယူနေစဉ်..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" နှင့်ကိုက်ညီသည့် အပ်ဖ်များမတွေ့ပါ"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"နောက်ထပ် အက်ပ်များကို ရှာပါ"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"အကြောင်းကြားချက်များ"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"ဤပင်မမျက်နှာစာတွင် နေရာလွတ် မကျန်တော့ပါ"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"အနှစ်သက်ဆုံးများ ထားရာတွင် နေရာလွတ် မကျန်တော့ပါ"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"အက်ပ်စာရင်း"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"အတိုကောက်မှတ်သားမှုများအား ထည့်သွင်းခြင်း"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"အသုံးပြုသူ လုပ်ဆောင်မှုမရှိပဲ အပ်ပလီကေးရှင်းကို အတိုကောက်မှတ်သားမှုများ ပြုလုပ်ခွင့် ပေးခြင်း"</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ဖတ်ခြင်း"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"ပင်မမျက်နှာစာတွင်ရှိသော အပြင်အဆင်နှင့် အတိုကောက်မှတ်သားမှုများကို အပ်ပလီကေးရှင်းအား ဖတ်ခွင့်ပြုခြင်း"</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ရေးသားခြင်း"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"ပင်မမျက်နှာစာတွင် ရှိသော အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများ ကို အပ်ပလီကေးရှင်းအား ပြောင်းခွင့်ပြုခြင်း"</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g>သည် ဖုန်းခေါ်ဆိုခွင့် မရှိပါ"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"အမည်မရှိအကန့်"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ကို ပိတ်ထားသည်"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"စာမျက်နှာ %1$d မှ %2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"ပင်မစာမျက်နှာ %1$d မှ %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"ပင်မမျက်နှာပြင် စာမျက်နှာသစ်"</string>
+    <string name="folder_opened" msgid="94695026776264709">"ဖွင့်ထားသောအကန့်, <xliff:g id="WIDTH">%1$d</xliff:g> နှင့် <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"နောက်ခံများ"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"ဆက်တင်များ"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"သင့်စီမံခန့်ခွဲသူက ပိတ်လိုက်ပါသည်"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"ခြုံငုံသုံးသပ်ချက်"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"ပင်မစာမျက်နှာလှည့်ခြင်းကို ခွင့်ပြုပါ"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"ဖုန်းကိုလှည့်ထားစဉ်"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"လက်ရှိ မြင်ကွင်းဆက်တင်တွင် မြင်ကွင်းကို လှည့်ခွင့်မပေးပါ"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"ပင်မစာမျက်နှာသို့ သင်္ကေတပုံ ထည့်ရန်"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"အက်ပ်အသစ်များအတွက်"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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">"ဤအိုင်ကွန်အတွက် အက်ပ်အားမထည့်သွင်းထားပါ။ You can remove it, or search for the အက်ပ်and install it manually."</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="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="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="add_to_folder" msgid="9040534766770853243">"ဖိုလ်ဒါသို့ ထည့်ရန်- <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> အမည်ရှိ ဖိုလ်ဒါသို့ ထည့်ပြီး၏"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"ဖိုလ်ဒါသို့ ထည့်ပြီး"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"ဖိုလ်ဒါ ပြုလုပ်ရန်- <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ဖိုလ်ဒါ ပြုလုပ်ပြီး"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"ပင်မမျက်နှာပြင်သို့ ရွှေ့ပါ"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"မျက်နှာပြင် ဘယ်ဘက်သို့ ရွှေ့ပါ"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"မျက်နှာပြင် ညာဘက်သို့ ရွှေ့ပါ"</string>
+    <string name="screen_moved" msgid="266230079505650577">"ဖန်မျက်နှာပြင် ပြောင်းရွှေ့ပြီး၏"</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">"Widget အား အကျယ် <xliff:g id="NUMBER_0">%1$s</xliff:g> အမြင့် <xliff:g id="NUMBER_1">%2$s</xliff:g> အရွယ်အစားပြန်လည်ချိန်ညှိပြီး၏"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"ဖြတ်လမ်းများ"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> အတွက် အမြန်နည်း <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ခု"</string>
+</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index e75e831..fb7eecd 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Mappe: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Moduler"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunner"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Innstillinger"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Startsideinnstillinger"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administratoren har slått av funksjonen"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Oversikt"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Tillat rotasjon av startskjermen"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Ukjent"</string>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index dee84e6..524e9c6 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"विजेटहरू"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"वालपेपरहरु"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"सेटिंङहरू"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"गृहपृष्ठका सेटिङहरू"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"तपाईँको प्रशासकद्वारा असक्षम गरिएको"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"परिदृश्य"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"गृह स्क्रिनलाई घुम्ने अनुमति दिनुहोस्"</string>
@@ -83,6 +83,10 @@
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नयाँ अनुप्रयोगका लागि"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"आइकनको आकार परिवर्तन गर्नुहोस्"</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>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
new file mode 100644
index 0000000..46c8f9c
--- /dev/null
+++ b/res/values-ne/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"एउटा विजेटलाई टिप्नको लागि टच गरेर होल्ड गर्नुहोस्।"</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"विजेटलाई छान्न वा आफू अनुकूल कार्यहरू प्रयोग गर्न डबल ट्याप गरी होल्ड गर्नुहोस्।"</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौडाइ गुणा %2$d उचाइ"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"म्यानुअल तरिकाले थप्न छुनुहोस् र थिची राख्नुहोस्‌"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"स्वतः थप्नुहोस्"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"अनुप्रयोगहरू खोज्नुहोस्"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"अनुप्रयोगहरू लोड गरिँदै..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै अनुप्रयोगहरू फेला परेनन्"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"थप अनुप्रयोगहरू खोज्नुहोस्"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"सूचनाहरू"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"यो गृह स्क्रिनमा कुनै थप ठाउँ छैन।"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"मनपर्ने ट्रे अब कुनै ठाँउ छैन"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"अनुप्रयोगको सूची"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"सर्टकट स्थापना गर्नेहोस्"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"प्रयोगकर्ताको हस्तक्षेप बिना एउटा अनुप्रयोगलाई सर्टकटमा थप्नको लागि अनुमति दिनुहोस्।"</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"गृह सेटिङहरू र सर्टकटहरू पढ्नुहोस्"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"गृहमा एउटा अनुप्रयोगलाई सेटिङहरू र सर्टकटहरू पढ्न अनुमति दिनुहोस्।"</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"गृह सेटिङहरू र सर्टकटहरू लेख्नुहोस्"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"गृहमा एउटा अनुप्रयोगलाई सेटिङ र सर्टकट बदल्न अनुमति दिनुहोस्।"</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले फोन कलहरू गर्न अनुमति छैन"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"बेनाम फोल्डर"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"असक्षम पारिएको <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"पृष्ठ %2$d को %1$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"गृह स्क्रिन %1$d को %2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"नयाँ गृह स्क्रिन पृष्ठ"</string>
+    <string name="folder_opened" msgid="94695026776264709">"फोल्डर खुल्यो <xliff:g id="WIDTH">%1$d</xliff:g> बाट <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"वालपेपरहरु"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"सेटिंङहरू"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"तपाईँको प्रशासकद्वारा असक्षम गरिएको"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"परिदृश्य"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"गृह स्क्रिनलाई घुम्ने अनुमति दिनुहोस्"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"फोनलाई घुमाइँदा"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"हालको प्रदर्शन सम्बन्धी सेटिङले घुमाउने सुविधालाई अनुमति दिँदैन"</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_no_override" msgid="3678524428085518367">"परिवर्तन नगर्नुहोस्"</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_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="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="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="add_to_folder" msgid="9040534766770853243">"फोल्डर: <xliff:g id="NAME">%1$s</xliff:g> मा थप्नुहोस्"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"फोल्डरमा <xliff:g id="NAME">%1$s</xliff:g> सँग थप्नुहोस्"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"वस्तु फोल्डरमा थपियो"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"<xliff:g id="NAME">%1$s</xliff:g>: मार्फत फोल्डर सिर्जना गर्नुहोस्"</string>
+    <string name="folder_created" msgid="6409794597405184510">"फोल्डर सिर्जना गरियो"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"गृह स्क्रिनमा सार्नुहोस्"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"स्क्रिनलाई बायाँ सार्नुहोस्"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"स्क्रिनलाई दायाँ सार्नुहोस्"</string>
+    <string name="screen_moved" msgid="266230079505650577">"स्क्रिन सारियो"</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="action_deep_shortcut" msgid="2864038805849372848">"सर्टकटहरू"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> का <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> सर्टकटहरू"</string>
+</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index a712d48..bd99a5c 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Map: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Achtergrond"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Instellingen"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Instellingen voor homepage"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Uitgeschakeld door je beheerder"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Overzicht"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Draaien van startscherm toestaan"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Onbekend"</string>
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml
index 8e51bd3..97add38 100644
--- a/res/values-pa-rIN/strings.xml
+++ b/res/values-pa-rIN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ਵਿਜਿਟ"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"ਵਾਲਪੇਪਰ"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"ਸੈਟਿੰਗਾਂ"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"ਹੋਮ ਸੈਟਿੰਗਾਂ"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"ਰੂਪ-ਰੇਖਾ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ਮੁੱਖ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁੰਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
@@ -83,6 +83,10 @@
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"ਨਵੀਆਂ ਐਪਾਂ ਲਈ"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"ਆਈਕਨ ਦੀ ਆਕ੍ਰਿਤੀ ਬਦਲੋ"</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>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
new file mode 100644
index 0000000..c4c11ce
--- /dev/null
+++ b/res/values-pa/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਛੋਹਵੋT &amp; ਹੋਲਡ ਕਰੋ।"</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ਡਬਲ-ਟੈਪ &amp; ਇੱਕ ਵਿਜੇਟ ਚੁਣਨ ਲਈ ਹੋਲਡ ਕਰੋ ਅਤੇ ਕਸਟਮ ਕਿਰਿਆਵਾਂ ਵਰਤੋ।"</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ਚੌੜਾਈ ਅਤੇ %2$d ਲੰਬਾਈ"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ਹੱਥੀਂ ਰੱਖਣ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"ਸਵੈਚਲਿਤ ਤਰੀਕੇ ਨਾਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ਐਪਸ ਖੋਜੋ"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ਨਾਲ ਮਿਲਦੀਆਂ ਕੋਈ ਵੀ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"ਹੋਰ ਐਪਾਂ ਖੋਜੋ"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"ਸੂਚਨਾਵਾਂ"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"ਇਸ ਹੋਮ ਸਕ੍ਰੀਨ ਲਈ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ ਹੈ।"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"ਮਨਪਸੰਦ ਟ੍ਰੇ ਵਿੱਚ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ।"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"ਐਪ ਸੂਚੀ"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"ਸ਼ਾਰਟਕੱਟ ਇੰਸਟੌਲ ਕਰੋ"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"ਇੱਕ ਐਪ ਨੂੰ ਉਪਭੋਗਤਾ ਦੇ ਦਖ਼ਲ ਤੋਂ ਬਿਨਾਂ ਸ਼ਾਰਟਕੱਟ ਜੋੜਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹੋ"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਪੜ੍ਹਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"ਹੋਮ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਲਿਖੋ"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"ਐਪ ਨੂੰ ਹੋਮ ਵਿੱਚ ਸੈਟਿੰਗਾਂ ਅਤੇ ਸ਼ਾਰਟਕੱਟ ਬਦਲਣ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।"</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਫੋਨ ਕਾਲਾਂ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"ਬਿਨਾਂ ਨਾਮ ਦਿੱਤਾ ਫੋਲਡਰ"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੂੰ ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
+    <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> ਬਾਇ <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"ਵਾਲਪੇਪਰ"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"ਸੈਟਿੰਗਾਂ"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"ਰੂਪ-ਰੇਖਾ"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"ਮੁੱਖ ਸਕ੍ਰੀਨ ਨੂੰ ਘੁੰਮਾਉਣ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"ਜਦੋਂ ਫ਼ੋਨ ਘੁੰਮਾਇਆ ਜਾਂਦਾ ਹੈ"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ਵਰਤਮਾਨ ਡਿਸਪਲੇ ਸੈਟਿੰਗ ਘੁੰਮਾਉਣ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਦਿੰਦੀ ਹੈ"</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_no_override" msgid="3678524428085518367">"ਨਾ ਬਦਲੋ"</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_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="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="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="add_to_folder" msgid="9040534766770853243">"ਇਸ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜੋ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> ਦੇ ਨਾਲ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜੋ"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"ਆਈਟਮ ਨੂੰ ਫੋਲਡਰ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"ਇਸਦੇ ਨਾਲ ਫੋਲਡਰ ਬਣਾਓ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ਫੋਲਡਰ ਬਣਾਇਆ ਗਿਆ"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"ਮੁੱਖ ਸਕ੍ਰੀਨ ਵਿੱਚ ਮੂਵ ਕਰੋ"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"ਸਕ੍ਰੀਨ ਨੂੰ ਖੱਬੇ ਮੂਵ ਕਰੋ"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"ਸਕ੍ਰੀਨ ਨੂੰ ਸੱਜੇ ਮੂਵ ਕਰੋ"</string>
+    <string name="screen_moved" msgid="266230079505650577">"ਸਕ੍ਰੀਨ ਨੂੰ ਮੂਵ ਕੀਤਾ ਗਿਆ"</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="action_deep_shortcut" msgid="2864038805849372848">"ਸ਼ਾਰਟਕੱਟ"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ਲਈ <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ਸ਼ਾਰਟਕੱਟ"</string>
+</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 9192732..0955d13 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widżety"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Ustawienia"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Ustawienia strony głównej"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Funkcja wyłączona przez administratora"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Przegląd"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Zezwalaj na obrót ekranu głównego"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Brak informacji"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 605dff2..e9e56cc 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Imagens de fundo"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Definições"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Definições da página inicial"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativada pelo administrador"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Vista geral"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação do ecrã principal"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 7945b07..4e17807 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Pasta: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Planos de fundo"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Configurações"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Configurações da página inicial"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Desativado pelo administrador"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Visão geral"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permitir rotação da tela inicial"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Desconhecido"</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index b433029..953b2c8 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Dosar: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgeturi"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Imagini de fundal"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Setări"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Setări pentru ecranul de pornire"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Dezactivată de administrator"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Prezentare generală"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Permiteți rotirea ecranului de pornire"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Necunoscut"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 6c87042..60296ae 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Папка: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Виджеты"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Обои"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Настройки"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Настройки главного экрана"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Функция отключена администратором"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Обзор"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Разрешить поворачивать главный экран"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Неизвестно"</string>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index f8f8e85..ff6416f 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"ෆෝල්ඩරය: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"විජට්"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"වෝල්පේපර"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"සැකසීම්"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Home සැකසීම්"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ඔබගේ පරිපාලක විසින් අබල කරන ලදී"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"දළ විශ්ලේෂණය"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"නොදනී"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
new file mode 100644
index 0000000..569a77f
--- /dev/null
+++ b/res/values-si/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"විජට් එක ස්පර්ශ කර අහුලා ගැනීමට අල්ලාගෙන සිටින්න."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"විජට් එකක් අහුලා ගැනීමට හෝ අභිරුචි ක්‍රියා කිරීමට ඩබල් ටැප් කර අල්ලා ගෙන සිටින්න."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"පළල %1$d උස %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"අතින් ස්ථානගත කිරීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"ස්වයංක්‍රියව එක් කරන්න"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"යෙදුම් සෙවීම"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"යෙදුම් පූරණය වෙමින්…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"තව යෙදුම් සඳහා සොයන්න"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"දැනුම්දීම්"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"මෙම මුල් පිටු තිරය මත තවත් අවසර නැත."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"ප්‍රියතම දෑ ඇති තැටියේ තවත් ඉඩ නොමැත"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"යෙදුම් ලැයිස්තුව"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"කෙටිමං ස්ථාපනය කරන්න"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"පරිශීලක මැදිහත්වීමෙන් තොරව කෙටිමං එක් කිරීමට යෙදුමකට අවසර දෙයි."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"මුල් පිටු සැකසීම් සහ කෙටිමං කියවන්න"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"මුල් පිටුවේ ඇති සැකසීම් සහ කෙටිමං කියවීමට යෙදුමකට අවසර දෙයි."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"මුල් පිටු සැකසීම් සහ කෙටිමං ලියන්න"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"මුල් පිටුවේ සැකසීම් සහ කෙටිමං ඉවත් කිරීමට යෙදුමට අවසර දෙයි."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> හට දුරකථන ඇමතුම් සිදු කිරීමට ඉඩ නොදේ"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"නම් නොකළ ෆෝල්ඩරය"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> අබල කෙරිණි"</string>
+    <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> හි <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"වෝල්පේපර"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"සැකසීම්"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ඔබගේ පරිපාලක විසින් අබල කරන ලදී"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"දළ විශ්ලේෂණය"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"මුල් පිටු තිරය කරකැවීමට ඉඩ දෙන්න"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"දුරකථනය කරකවන විට"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"වත්මන් සංදර්ශක සැකසීම් කරකැවීමට සහාය නොදක්වයි"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"මුල් පිටු තිරය වෙත අයිකනය එක් කරන්න"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"නව යෙදුම් සඳහා"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"ෆෝල්ඩරය එක් කරන්න: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> සමඟ ෆෝල්ඩරය වෙත එක් කරන්න"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"අයිතමය ෆෝඩරය වෙතට එක් කරන ලදි"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"මේ සමග ෆෝල්ඩරය සාදන්න: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ෆෝල්ඩරය සාදන ලදි"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"මුල් තිරය වෙත ගෙන යන්න"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"තිරය වම් පැත්තට ගෙනයන්න"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"තිරය දකුණු පැත්තට ගෙනයන්න"</string>
+    <string name="screen_moved" msgid="266230079505650577">"තිරය ගෙන යන ලදි"</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="action_deep_shortcut" msgid="2864038805849372848">"කෙටිමං"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> සඳහා කෙටි මං <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g>"</string>
+</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 3d754b2..1a49d7d 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Priečinok: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Miniaplikácie"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Tapety"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Nastavenia"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Nastavenia služby Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Zakázané vaším správcom"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Prehľad"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Povoliť otáčanie plochy"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Neznáme"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index fddb445..16cb58c 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Mapa: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Pripomočki"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Ozadja"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Nastavitve"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Nastavitve začetnega zaslona"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Onemogočil skrbnik."</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Pregled"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Omogočanje sukanja začetnega zaslona"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Neznano"</string>
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml
index f300d03..1ad19ce 100644
--- a/res/values-sq-rAL/strings.xml
+++ b/res/values-sq-rAL/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Miniaplikacionet"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Imazhet e sfondit"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Cilësimet"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Cilësimet e Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Çaktivizuar nga administratori"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Përmbledhje"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Lejo rrotullimin e ekranit kryesor"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <string name="icon_shape_system_default" msgid="1709762974822753030">"Përdor parazgjedhjen e sisteit"</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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"I panjohur"</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
new file mode 100644
index 0000000..2b65684
--- /dev/null
+++ b/res/values-sq/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="app_name" msgid="649227358658669779">"Nisësi3"</string>
+    <string name="folder_name" msgid="7371454440695724752"></string>
+    <string name="work_folder_name" msgid="3753320833950115786">"Puna"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"Aplikacioni nuk është i instaluar."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Aplikacioni nuk mundësohet"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplikacioni i shkarkuar është i çaktivizuar në modalitetin e sigurt"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Miniaplikacionet janë të çaktivizuara në modalitetin e sigurt"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"Shkurtorja nuk është e disponueshme"</string>
+    <string name="home_screen" msgid="806512411299847073">"Ekrani bazë"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Veprimet e personalizuara"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Prek dhe mbaj shtypur për të zgjedhur një miniaplikacion."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Prek dy herë dhe mbaj shtypur për të zgjedhur një miniaplikacion ose për të përdorur veprimet e personalizuara."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i gjerë me %2$d i lartë"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Prek dhe mbaj të shtypur për të vendosur në mënyrë manuale"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Shto automatikisht"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Kërko për aplikacione"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Po ngarkon aplikacionet..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"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="notifications_header" msgid="1404149926117359025">"Njoftimet"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Nuk ka më hapësirë në këtë ekran bazë."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Nuk ka më hapësirë në tabakanë \"Të preferuarat\""</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Lista e aplikacioneve"</string>
+    <string name="all_apps_home_button_label" msgid="252062713717058851">"Faqja kryesore"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Hiqe"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"Çinstalo"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Informacion mbi aplikacionin"</string>
+    <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalo shkurtore"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Lejon një aplikacion të shtojë shkurtore pa ndërhyrjen e përdoruesit."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"lexo cilësimet dhe shkurtoret e ekranit bazë"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Lejon aplikacionin të lexojë cilësimet dhe shkurtoret në ekranin bazë."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"shkruaj cilësimet dhe shkurtoret e ekranit bazë"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Lejon aplikacionin të ndryshojë cilësimet dhe shkurtoret në ekranin bazë."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> nuk lejohet të kryejë telefonata"</string>
+    <string name="gadget_error_text" msgid="6081085226050792095">"Problem në ngarkimin e miniaplikacionit"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Konfiguro"</string>
+    <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>
+    <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>
+    <string name="workspace_new_page" msgid="257366611030256142">"Faqja e ekranit të ri kryesor"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Dosja u hap, <xliff:g id="WIDTH">%1$d</xliff:g> me <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+    <string name="folder_tap_to_close" msgid="4625795376335528256">"Trokit për të mbyllur dosjen"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"Trokit për të ruajtur riemërtimin"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"Dosja u mbyll"</string>
+    <string name="folder_renamed" msgid="1794088362165669656">"Dosja u riemërtua në <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_name_format" msgid="6629239338071103179">"Dosja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"Miniaplikacionet"</string>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Imazhet e sfondit"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Cilësimet"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Çaktivizuar nga administratori"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Përmbledhje"</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="allow_rotation_blocked_desc" msgid="3212602545192996253">"Cilësimi aktuali i afishimit nuk lejon rrotullimin"</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>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"Aplikacioni nuk është i instaluar"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Aplikacioni për këtë ikonë nuk është i instaluar. Mund ta heqësh ose të kërkosh aplikacionin dhe ta instalosh atë në mënyrë manuale."</string>
+    <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> po shkarkohet, <xliff:g id="PROGRESS">%2$s</xliff:g> të përfunduara"</string>
+    <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> po pret të instalohet"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"Miniaplikacionet e <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"Shto në Ekranin bazë"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Zhvendose artikullin këtu"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"Artikulli u shtua tek ekrani bazë"</string>
+    <string name="item_removed" msgid="851119963877842327">"Artikulli u hoq"</string>
+    <string name="action_move" msgid="4339390619886385032">"Zhvendose artikullin"</string>
+    <string name="move_to_empty_cell" msgid="2833711483015685619">"Zhvendos te rreshti <xliff:g id="NUMBER_0">%1$s</xliff:g>, kolona <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="move_to_position" msgid="6750008980455459790">"Zhvendos te pozicioni <xliff:g id="NUMBER">%1$s</xliff:g>"</string>
+    <string name="move_to_hotseat_position" msgid="6295412897075147808">"Zhvendos te pozicioni <xliff:g id="NUMBER">%1$s</xliff:g> i preferencave"</string>
+    <string name="item_moved" msgid="4606538322571412879">"Artikulli u zhvendos"</string>
+    <string name="add_to_folder" msgid="9040534766770853243">"Shto te dosja: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"Shto te dosja me <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Artikulli u shtua te dosja"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"Krijo një dosje me: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Dosja u krijua"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Zhvendose në Ekranin bazë"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Zhvendose ekranin në të majtë"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Zhvendose ekranin në të djathtë"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Ekrani u zhvendos"</string>
+    <string name="action_resize" msgid="1802976324781771067">"Ndrysho madhësinë"</string>
+    <string name="action_increase_width" msgid="8773715375078513326">"Rrit gjerësinë"</string>
+    <string name="action_increase_height" msgid="459390020612501122">"Rrit lartësinë"</string>
+    <string name="action_decrease_width" msgid="1374549771083094654">"Zvogëlo gjerësinë"</string>
+    <string name="action_decrease_height" msgid="282377193880900022">"Zvogëlo lartësinë"</string>
+    <string name="widget_resized" msgid="9130327887929620">"Madhësia e miniaplikacionit u ndryshua me gjerësinë <xliff:g id="NUMBER_0">%1$s</xliff:g> dhe lartësinë <xliff:g id="NUMBER_1">%2$s</xliff:g>"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"Shkurtoret"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> shkurtesa për <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
+</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 68cb442..f02a829 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Директоријум: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Виџети"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Позадине"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Подешавања"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Подешавања почетног екрана"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Администратор је онемогућио"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Преглед"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Дозволи ротацију почетног екрана"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Непознато"</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 4dd6f48..6778bdc 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Mapp: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widgetar"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Bakgrunder"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Inställningar"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Inställningar för startsidan"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Inaktiverat av administratören"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Översikt"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Tillåt rotering av startskärmen"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Okänt"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index ce06bdb..48e8a32 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -72,7 +72,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Folda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Wijeti"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Mandhari"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Mipangilio"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Mipangilio ya ukurasa wa mwanzo"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Imezimwa na msimamizi wako"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Muhtasari"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Ruhusu kuzungusha skrini ya Kwanza"</string>
@@ -86,6 +86,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <string name="icon_shape_system_default" msgid="1709762974822753030">"Tumia umbo chaguo-msingi 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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Yasiyojulikana"</string>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index de809b1..bb0dbc2 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -26,13 +26,13 @@
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowActionModeOverlay">true</item>
         <item name="android:colorEdgeEffect">?android:attr/textColorSecondary</item>
+        <item name="android:keyboardLayout">@layout/all_apps_search_container</item>
     </style>
 
     <!-- Workspace -->
     <style name="DropTargetButton" parent="DropTargetButtonBase">
         <item name="android:paddingLeft">60dp</item>
         <item name="android:paddingRight">60dp</item>
-        <item name="android:shadowColor">#393939</item>
         <item name="android:shadowDx">0.0</item>
         <item name="android:shadowDy">0.0</item>
         <item name="android:shadowRadius">2.0</item>
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index eae471c..eca34ce 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"கோப்புறை: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ஷார்ட்கட்ஸ்"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"வால்பேப்பர்கள்"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"அமைப்பு"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"முகப்பு அமைப்புகள்"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"உங்கள் நிர்வாகி முடக்கியுள்ளார்"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"மேலோட்டப் பார்வை"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"முகப்புத் திரை சுழற்சியை அனுமதி"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"தெரியாதது"</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
new file mode 100644
index 0000000..a1e00a1
--- /dev/null
+++ b/res/values-ta/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"விட்ஜெட்டைத் தேர்வுசெய்ய தொட்டுப் பிடிக்கவும்."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"விட்ஜெட்டைத் தேர்ந்தெடுக்க இருமுறை தட்டிப் பிடிக்கவும் அல்லது தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d அகலத்திற்கு %2$d உயரம்"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"நீங்களே சேர்க்க, தொட்டுப் பிடித்திருக்கவும்"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"தானாகவே சேர்"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"பயன்பாடுகளில் தேடுக"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"பயன்பாடுகளை ஏற்றுகிறது..."</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் பயன்பாடுகள் இல்லை"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"கூடுதல் பயன்பாடுகளைத் தேடு"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"அறிவிப்புகள்"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"முகப்புத் திரையில் இடமில்லை."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"பிடித்தவை ட்ரேயில் இடமில்லை"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"பயன்பாடுகளின் பட்டியல்"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"குறுக்குவழிகளை நிறுவுதல்"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் பயன்பாட்டை அனுமதிக்கிறது."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளைப் படித்தல்"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளை எழுதுதல்"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"ஃபோன் அழைப்புகள் செய்ய, <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதிக்கப்படவில்லை"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"பெயரிடப்படாத கோப்புறை"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> முடக்கப்பட்டது"</string>
+    <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>
+    <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_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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"வால்பேப்பர்கள்"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"அமைப்பு"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"உங்கள் நிர்வாகி முடக்கியுள்ளார்"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"மேலோட்டப் பார்வை"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"முகப்புத் திரை சுழற்சியை அனுமதி"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"மொபைலைச் சுழற்றும் போது"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"தற்போதைய திரை அமைப்பு சுழற்றுவதை அனுமதிக்கவில்லை"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"முகப்புத் திரையில் ஐகானைச் சேர்"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"புதிய பயன்பாடுகளுக்கு"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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_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="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="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="add_to_folder" msgid="9040534766770853243">"இந்தக் கோப்புறையில் சேர்க்கும்: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> உள்ள கோப்புறையில் சேர்க்கும்"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"கோப்புறையில் உருப்படி சேர்க்கப்பட்டது"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"இதனுடன் கோப்புறையை உருவாக்கும்: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"கோப்புறை உருவாக்கப்பட்டது"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"முகப்புத் திரைக்கு நகர்த்து"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"திரையை இடப்புறம் நகர்த்து"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"திரையை வலப்புறம் நகர்த்து"</string>
+    <string name="screen_moved" msgid="266230079505650577">"திரை நகர்த்தப்பட்டது"</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="action_deep_shortcut" msgid="2864038805849372848">"குறுக்குவழிகள்"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g>க்கான <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> குறுக்குவழிகள்"</string>
+</resources>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index 338c158..e79512e 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"ఫోల్డర్: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"విడ్జెట్‌లు"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"వాల్‌పేపర్‌లు"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"సెట్టింగ్‌లు"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"హోమ్ సెట్టింగ్‌లు"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"మీ నిర్వాహకులు నిలిపివేసారు"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"స్థూలదృష్టి"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి"</string>
@@ -83,6 +83,10 @@
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"కొత్త అనువర్తనాల కోసం"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"చిహ్న ఆకారాన్ని మార్చు"</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>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
new file mode 100644
index 0000000..65ca927
--- /dev/null
+++ b/res/values-te/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"విడ్జెట్‌ను ఎంచుకోవడానికి తాకి &amp; నొక్కి పెట్టండి."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"విడ్జెట్‌ను ఎంచుకోవడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కి, ఉంచండి."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d వెడల్పు X %2$d ఎత్తు"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"మాన్యువల్‌గా ఉంచడానికి నొక్కి &amp;amp పట్టుకోండి"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"స్వయంచాలకంగా జోడించు"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"అనువర్తనాలను శోధించండి"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"అనువర్తనాలను లోడ్ చేస్తోంది…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అనువర్తనాలేవీ కనుగొనబడలేదు"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"మరిన్ని అనువర్తనాల కోసం శోధించు"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"నోటిఫికేషన్‌లు"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"ఈ హోమ్ స్క్రీన్‌లో ఖాళీ లేదు."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"ఇష్టమైనవి ట్రేలో ఖాళీ లేదు"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"అనువర్తనాల జాబితా"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"సత్వరమార్గాలను ఇన్‌స్టాల్ చేయడం"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"వినియోగదారు ప్రమేయం లేకుండా సత్వరమార్గాలను జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడం"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను వ్రాయడం"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"ఫోన్ కాల్‌లను చేసేందుకు <xliff:g id="APP_NAME">%1$s</xliff:g>కి అనుమతి లేదు"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"పేరు లేని ఫోల్డర్"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> నిలిపివేయబడింది"</string>
+    <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_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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"వాల్‌పేపర్‌లు"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"సెట్టింగ్‌లు"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"మీ నిర్వాహకులు నిలిపివేసారు"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"స్థూలదృష్టి"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"హోమ్ స్క్రీన్ భ్రమణాన్ని అనుమతించండి"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"ఫోన్‌‌ను తిప్పినప్పుడు"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"ప్రస్తుత డిస్‌ప్లే సెట్టింగ్ భ్రమణాన్ని అనుమతించలేదు"</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_no_override" msgid="3678524428085518367">"మార్చవద్దు"</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_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="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="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="add_to_folder" msgid="9040534766770853243">"ఈ ఫోల్డర్‌కి జోడించండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> గల ఫోల్డర్‌కు జోడించు"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"అంశం ఫోల్డర్‌కు జోడించబడింది"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"ఈ పేరుతో ఫోల్డర్‌ను సృష్టించండి: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"ఫోల్డర్ సృష్టించబడింది"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"హోమ్‌స్క్రీన్‌కు తరలించు"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"స్క్రీన్‌ను ఎడమవైపుకి జరుపు"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"స్క్రీన్‌ను కుడివైపుకి జరుపు"</string>
+    <string name="screen_moved" msgid="266230079505650577">"స్క్రీన్ జరపబడింది"</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="action_deep_shortcut" msgid="2864038805849372848">"సత్వరమార్గాలు"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> కోసం <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> సత్వరమార్గాలు"</string>
+</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 65702a0..2adf4b9 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"โฟลเดอร์: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"วิดเจ็ต"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"วอลเปเปอร์"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"การตั้งค่า"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"การตั้งค่าหน้าแรก"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ปิดใช้โดยผู้ดูแลระบบ"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"ภาพรวม"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"อนุญาตให้หมุนหน้าจอหลัก"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"ไม่รู้จัก"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 8270708..4390a3a 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Folder: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Mga Widget"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Mga Wallpaper"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Mga Setting"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Mga setting ng Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Na-disable ng iyong admin"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Pangkalahatang-ideya"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Payagan ang pag-rotate ng Home screen"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Hindi kilala"</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index da0aa28..cb03f51 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Klasör: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Widget\'lar"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Duvar Kağıtları"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Ayarlar"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Ana ekran ayarları"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Yöneticiniz tarafından devre dışı bırakıldı"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Genel bakış"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Ana ekranı döndürmeye izin ver"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Bilinmiyor"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index a9cefaf..70a742f 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Папка <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Віджети"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Фонові малюнки"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Налаштування"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Налаштування Home"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Вимкнув адміністратор"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Огляд"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Дозволити обертання головного екрана"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Невідомо"</string>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index 195a107..0a747e6 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"فولڈر: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"ویجیٹس"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"وال پیپرز"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"ترتیبات"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"ہوم ترتیبات"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"مجموعی جائزہ"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ہوم اسکرین گھمانے کی اجازت دیں"</string>
@@ -83,6 +83,10 @@
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"نئی ایپس کیلئے"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"آئیکن کی شکل تبدیل کریں"</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>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
new file mode 100644
index 0000000..29d1cd5
--- /dev/null
+++ b/res/values-ur/strings.xml
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="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="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>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"کوئی ویجیٹ منتخب کرنے کیلئے ٹچ کریں اور پکڑے رہیں۔"</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"کوئی ویجٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور پکڑے رکھیں۔"</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏%1$d چوڑا اور ‎%2$d اونچا"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"‏دستی طور پر رکھنے کیلئے ‎&amp; ٹچ کرکے ہولڈ کریں"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"خود کار طور پر شامل کریں"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ایپس تلاش کریں"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"ایپس لوڈ ہو رہی ہیں…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" سے مماثل کوئی ایپس نہیں ملیں"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"مزید ایپس تلاش کریں"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"اطلاعات"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"اس ہوم اسکرین پر مزید کوئی گنجائش نہیں ہے۔"</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"پسندیدہ ٹرے میں مزید کوئی گنجائش نہیں ہے"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"ایپس کی فہرست"</string>
+    <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="permlab_install_shortcut" msgid="5632423390354674437">"شارٹ کٹس انسٹال کریں"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"کسی ایپ کو صارف کی مداخلت کے بغیر شارٹ کٹس شامل کرنے کی اجازت دیتا ہے۔"</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"ہوم ترتیبات اور شارٹ کٹس کو پڑھیں"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"ایپ کو ہوم میں ترتیبات اور شارٹ کٹس کو پڑھنے کی اجازت دیتا ہے۔"</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"ہوم ترتیبات اور شارٹ کٹس کو لکھیں"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"ایپ کو ہوم میں ترتیبات اور شارٹ کٹس کو تبدیل کرنے کی اجازت دیتا ہے۔"</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> کو فون کالیں کرنے کی اجازت نہیں ہے"</string>
+    <string name="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="folder_hint_text" msgid="6617836969016293992">"بلا نام فولڈر"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> غیر فعال ہے"</string>
+    <string name="default_scroll_format" msgid="7475544710230993317">"‏صفحہ ‎%1$d از ‎%2$d"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"‏ہوم اسکرین ‎%1$d از ‎%2$d"</string>
+    <string name="workspace_new_page" msgid="257366611030256142">"نیا ہوم اسکرین صفحہ"</string>
+    <string name="folder_opened" msgid="94695026776264709">"فولڈر کھولا گیا، <xliff:g id="WIDTH">%1$d</xliff:g> × <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_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>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"وال پیپرز"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"ترتیبات"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"آپ کے منتظم کی طرف سے غیر فعال کر دیا گیا"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"مجموعی جائزہ"</string>
+    <string name="allow_rotation_title" msgid="7728578836261442095">"ہوم اسکرین گھمانے کی اجازت دیں"</string>
+    <string name="allow_rotation_desc" msgid="8662546029078692509">"جب فون گھمایا جاتا ہے"</string>
+    <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"موجودہ ڈسپلے ترتیب گھمانے کی اجازت نہیں دیتی"</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_no_override" msgid="3678524428085518367">"تبدیل نہ کریں"</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_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="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="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="add_to_folder" msgid="9040534766770853243">"فولڈر میں شامل کریں: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> کے فولڈر میں شامل کریں"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"آئٹم فولڈر میں شامل کر دیا گیا"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"اس کے ساتھ فولڈر بنائیں: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="folder_created" msgid="6409794597405184510">"فولڈر بنا دیا گیا"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"ہوم اسکرین میں منتقل کریں"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"اسکرین کو بائیں منتقل کریں"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"اسکرین کو دائیں منتقل کریں"</string>
+    <string name="screen_moved" msgid="266230079505650577">"اسکرین منتقل کر دی گئی"</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="action_deep_shortcut" msgid="2864038805849372848">"شارٹ کٹس"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> کیلئے <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> شارٹ کٹس"</string>
+</resources>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index fbd153b..d11a60d 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Jild: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Vidjetlar"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Fon rasmlari"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Sozlamalar"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Home sozlamalari"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator tomonidan o‘chirilgan"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Umumiy ko‘rinish"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Asosiy ekranni aylantirishga ruxsat berish"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Noma’lum"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
new file mode 100644
index 0000000..81be979
--- /dev/null
+++ b/res/values-uz/strings.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2008 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT 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="app_name" msgid="649227358658669779">"Launcher3"</string>
+    <string name="folder_name" msgid="7371454440695724752"></string>
+    <string name="work_folder_name" msgid="3753320833950115786">"Ishga oid"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"Ilova o‘rnatilmadi."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Ilova mavjud emas"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Yuklab olingan ilova xavfsiz rejimda o‘chirib qo‘yildi"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Xavfsiz rejimda vidjetlar o‘chirib qo‘yilgan"</string>
+    <string name="shortcut_not_available" msgid="2536503539825726397">"Tezkor tugmadan foydalanib bo‘lmaydi"</string>
+    <string name="home_screen" msgid="806512411299847073">"Bosh ekran"</string>
+    <string name="custom_actions" msgid="3747508247759093328">"Maxsus amallar"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidjetni tanlash uchun bosib turing."</string>
+    <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ikki marta bosib va bosib turgan holatda vidjetni tanlang yoki maxsus amaldan foydalaning."</string>
+    <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
+    <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Eni %1$d, bo‘yi %2$d"</string>
+    <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Qo‘lda joylashtirish uchun bosib turing"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"Avtomatik chiqarish"</string>
+    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Ilovalar ichidan qidirish"</string>
+    <string name="all_apps_loading_message" msgid="7557140873644765180">"Ilovalar yuklanmoqda…"</string>
+    <string name="all_apps_no_search_results" msgid="6332185285860416787">"“<xliff:g id="QUERY">%1$s</xliff:g>” so‘rovi bo‘yicha hech narsa topilmadi"</string>
+    <string name="all_apps_search_market_message" msgid="1366263386197059176">"Boshqa ilovalarni qidirish"</string>
+    <string name="notifications_header" msgid="1404149926117359025">"Bildirishnomalar"</string>
+    <string name="out_of_space" msgid="4691004494942118364">"Uy ekranida bitta ham xona yo‘q."</string>
+    <string name="hotseat_out_of_space" msgid="7448809638125333693">"Ajratilganlarda birorta ham xona yo‘q"</string>
+    <string name="all_apps_button_label" msgid="8130441508702294465">"Ilovalar ro‘yxati"</string>
+    <string name="all_apps_home_button_label" msgid="252062713717058851">"Bosh sahifa"</string>
+    <string name="remove_drop_target_label" msgid="7812859488053230776">"Olib tashlash"</string>
+    <string name="uninstall_drop_target_label" msgid="4722034217958379417">"O‘chirib tashlash"</string>
+    <string name="app_info_drop_target_label" msgid="692894985365717661">"Ilova haqida"</string>
+    <string name="permlab_install_shortcut" msgid="5632423390354674437">"yorliqlar yaratish"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Ilovalarga foydalanuvchidan so‘ramasdan yorliqlar qo‘shishga ruxsat beradi."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"Uy sozlamalari va yorliqlarini o‘qish"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalarni o‘qish uchun ruxsat beradi."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"Uy sozlamalari va yorliqlarini yozish"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalrni o‘zgartirish uchun ruxsat beradi."</string>
+    <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasiga qo‘ng‘iroqlarni amalga oshirishga ruxsat berilmagan"</string>
+    <string name="gadget_error_text" msgid="6081085226050792095">"Vidjetni yuklashda muammo"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Sozlash"</string>
+    <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>
+    <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>
+    <string name="workspace_new_page" msgid="257366611030256142">"Yangi bosh ekran sahifasi"</string>
+    <string name="folder_opened" msgid="94695026776264709">"Jild ochildi, <xliff:g id="WIDTH">%1$d</xliff:g> ga <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
+    <string name="folder_tap_to_close" msgid="4625795376335528256">"Jildni yopish uchun ustiga bosing"</string>
+    <string name="folder_tap_to_rename" msgid="4017685068016979677">"O‘zgarishni saqlash uchun ustiga bosing"</string>
+    <string name="folder_closed" msgid="4100806530910930934">"Jild yopildi"</string>
+    <string name="folder_renamed" msgid="1794088362165669656">"Jild nomi <xliff:g id="NAME">%1$s</xliff:g>ga o‘zgartirildi"</string>
+    <string name="folder_name_format" msgid="6629239338071103179">"Jild: <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"Vidjetlar"</string>
+    <string name="wallpaper_button_text" msgid="8404103075899945851">"Fon rasmlari"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"Sozlamalar"</string>
+    <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Administrator tomonidan o‘chirilgan"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"Umumiy ko‘rinish"</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="allow_rotation_blocked_desc" msgid="3212602545192996253">"Ekran sozlamalariga ko‘ra uni aylantirib bo‘lmaydi"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Bosh ekranga ikonka qo‘shish"</string>
+    <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Yangi o‘rnatilgan ilovalar ikonkasini bosh ekranga chiqarish"</string>
+    <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
+    <skip />
+    <!-- no translation found for icon_shape_no_override (3678524428085518367) -->
+    <skip />
+    <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
+    <skip />
+    <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>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"Ushbu ilova o‘rnatilmagan"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"Ilova o‘rnatilmagan. Belgini o‘chirib tashlashingiz yoki ilovani topib, uni qo‘lda o‘rnatishingiz mumkin."</string>
+    <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> yuklab olinmoqda, <xliff:g id="PROGRESS">%2$s</xliff:g> bajarildi"</string>
+    <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi o‘rnatilishi kutilmoqda"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> vidjetlari"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"Bosh ekranga qo‘shish"</string>
+    <string name="action_move_here" msgid="2170188780612570250">"Obyektni bu yerga ko‘chirish"</string>
+    <string name="item_added_to_workspace" msgid="4211073925752213539">"Obyekt bosh ekranga qo‘shildi"</string>
+    <string name="item_removed" msgid="851119963877842327">"Obyekt o‘chirib tashlandi"</string>
+    <string name="action_move" msgid="4339390619886385032">"Obyektni ko‘chirib o‘tkazish"</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> katakka ko‘chirib o‘tkazish"</string>
+    <string name="move_to_position" msgid="6750008980455459790">"<xliff:g id="NUMBER">%1$s</xliff:g>-joyga ko‘chirib o‘tkazish"</string>
+    <string name="move_to_hotseat_position" msgid="6295412897075147808">"Sevimlilarga (<xliff:g id="NUMBER">%1$s</xliff:g>) ko‘chirib o‘tkazish"</string>
+    <string name="item_moved" msgid="4606538322571412879">"Element ko‘chirib o‘tkazildi"</string>
+    <string name="add_to_folder" msgid="9040534766770853243">"<xliff:g id="NAME">%1$s</xliff:g> jildiga qo‘shish"</string>
+    <string name="add_to_folder_with_app" msgid="4534929978967147231">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi bor jildga qo‘shish"</string>
+    <string name="added_to_folder" msgid="4793259502305558003">"Element jildga qo‘shildi"</string>
+    <string name="create_folder_with" msgid="4050141361160214248">"<xliff:g id="NAME">%1$s</xliff:g> bilan jild yaratish"</string>
+    <string name="folder_created" msgid="6409794597405184510">"Jild yaratildi"</string>
+    <string name="action_move_to_workspace" msgid="1603837886334246317">"Bosh ekranga ko‘chirish"</string>
+    <string name="action_move_screen_left" msgid="8854216831569401665">"Ekranni chapga siljitish"</string>
+    <string name="action_move_screen_right" msgid="329334910274311123">"Ekranni o‘ngga siljitish"</string>
+    <string name="screen_moved" msgid="266230079505650577">"Ekran siljitildi"</string>
+    <string name="action_resize" msgid="1802976324781771067">"O‘lchamini o‘zgartirish"</string>
+    <string name="action_increase_width" msgid="8773715375078513326">"Enini uzaytirish"</string>
+    <string name="action_increase_height" msgid="459390020612501122">"Bo‘yini uzaytirish"</string>
+    <string name="action_decrease_width" msgid="1374549771083094654">"Enini kichraytirish"</string>
+    <string name="action_decrease_height" msgid="282377193880900022">"Bo‘yini kichraytirish"</string>
+    <string name="widget_resized" msgid="9130327887929620">"Vidjetning eni <xliff:g id="NUMBER_0">%1$s</xliff:g>, bo‘yi <xliff:g id="NUMBER_1">%2$s</xliff:g> qilib o‘zgartirildi"</string>
+    <string name="action_deep_shortcut" msgid="2864038805849372848">"Tezkor tugmalar"</string>
+    <string name="shortcuts_menu_description" msgid="406159963824238648">"<xliff:g id="APP_NAME">%2$s</xliff:g> ilovasi uchun <xliff:g id="NUMBER_OF_SHORTCUTS">%1$d</xliff:g> ta tezkor tugma"</string>
+</resources>
diff --git a/res/values-v19/styles.xml b/res/values-v19/styles.xml
index cfc7c0f..36c0971 100644
--- a/res/values-v19/styles.xml
+++ b/res/values-v19/styles.xml
@@ -18,7 +18,7 @@
 -->
 <resources>
 
-    <style name="LauncherTheme" parent="@style/BaseLauncherTheme">
+    <style name="LauncherTheme" parent="@style/BaseLauncherThemeWithCustomAttrs">
         <item name="android:windowTranslucentStatus">true</item>
         <item name="android:windowTranslucentNavigation">true</item>
     </style>
diff --git a/res/values-v21/styles.xml b/res/values-v21/styles.xml
index 8d3de01..927719c 100644
--- a/res/values-v21/styles.xml
+++ b/res/values-v21/styles.xml
@@ -18,7 +18,7 @@
 -->
 <resources>
 
-    <style name="LauncherTheme" parent="@style/BaseLauncherTheme">
+    <style name="LauncherTheme" parent="@style/BaseLauncherThemeWithCustomAttrs">
         <item name="android:windowTranslucentStatus">false</item>
         <item name="android:windowTranslucentNavigation">false</item>
         <item name="android:windowDrawsSystemBarBackgrounds">true</item>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 626ea99..bd7fc45 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Thư mục: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Tiện ích con"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Hình nền"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Cài đặt"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Cài đặt trang chủ"</string>
     <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="accessibility_action_overview" msgid="6257665857640347026">"Tổng quan"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Cho phép xoay Màn hình chính"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Không xác định"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index fde1986..3ac74fd 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"文件夹:<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"微件"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"壁纸"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"设置"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"主屏幕设置"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"已被您的管理员停用"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"概览"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"允许旋转主屏幕"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"未知"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index d5cf997..97cee97 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"設定"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Home 設定"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由您的管理員停用"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"概覽"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"允許主畫面旋轉"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 276ddec..6a75cce 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"資料夾:<xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"小工具"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"桌布"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"設定"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Home 設定"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"已由你的管理員停用"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"總覽"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"允許旋轉主螢幕"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"不明"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 82fd4cf..56d9985 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -70,7 +70,7 @@
     <string name="folder_name_format" msgid="6629239338071103179">"Ifolda: <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="widget_button_text" msgid="2880537293434387943">"Amawijethi"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"Izithombe zangemuva"</string>
-    <string name="settings_button_text" msgid="8119458837558863227">"Izilungiselelo"</string>
+    <string name="settings_button_text" msgid="8873672322605444408">"Izilungiselelo zasekhaya"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"Kukhutshazwe umlawuli wakho"</string>
     <string name="accessibility_action_overview" msgid="6257665857640347026">"Ukubuka konke"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"Vumela ukuphendukiswa kwesikrini sasekhaya"</string>
@@ -84,6 +84,10 @@
     <!-- no translation found for icon_shape_override_label (2977264953998281004) -->
     <skip />
     <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>
     <!-- no translation found for icon_shape_override_progress (3461735694970239908) -->
     <skip />
     <string name="package_state_unknown" msgid="7592128424511031410">"Akwaziwa"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 18f409f..b7189d1 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -16,7 +16,20 @@
 */
 -->
 
-<resources>
+<resources xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <!-- Attributes used for launcher theme -->
+    <attr name="allAppsScrimColor" format="color" />
+    <attr name="popupColorPrimary" format="color" />
+    <attr name="popupColorSecondary" format="color" />
+    <attr name="popupColorTertiary" format="color" />
+    <attr name="isMainColorDark" format="boolean" />
+    <attr name="isWorkspaceDarkText" format="boolean" />
+    <attr name="workspaceTextColor" format="color" />
+    <attr name="workspaceShadowColor" format="color" />
+    <attr name="workspaceAmbientShadowColor" format="color"/>
+    <attr name="workspaceKeyShadowColor" format="color" />
+    <attr name="workspaceStatusBarScrim" format="reference" />
 
     <!-- BubbleTextView specific attributes. -->
     <declare-styleable name="BubbleTextView">
@@ -32,6 +45,8 @@
         <attr name="deferShadowGeneration" format="boolean" />
         <attr name="customShadows" format="boolean" />
         <attr name="centerVertically" format="boolean" />
+        <attr name="ambientShadowColor" format="color" />
+        <attr name="keyShadowColor" format="color" />
     </declare-styleable>
 
     <!-- PagedView specific attributes. These attributes are used to customize
@@ -111,4 +126,10 @@
         </attr>
     </declare-styleable>
 
+    <declare-styleable name="ShadowDrawable">
+        <attr name="android:src" />
+        <attr name="android:shadowColor" />
+        <attr name="android:elevation" />
+        <attr name="android:tint" />
+    </declare-styleable>
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 67a7544..4f7c1a7 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -25,28 +25,18 @@
 
     <color name="focused_background">#80c6c5c5</color>
 
-    <color name="workspace_icon_text_color">#FFF</color>
-    <color name="workspace_edge_effect_color">#FFFFFFFF</color>
-
     <color name="default_shadow_color_no_alpha">#FF000000</color>
 
-    <color name="outline_color">#FFFFFFFF</color>
-
     <color name="spring_loaded_panel_color">#40FFFFFF</color>
     <color name="spring_loaded_highlighted_panel_border_color">#FFF</color>
 
     <!-- Popup container -->
-    <color name="popup_header_background_color">#EEEEEE</color> <!-- Gray 200 -->
-    <color name="popup_background_color">#FFF</color>
     <color name="notification_icon_default_color">#757575</color> <!-- Gray 600 -->
-    <color name="notification_color_beneath">#E0E0E0</color> <!-- Gray 300 -->
-
     <color name="badge_color">#1DE9B6</color> <!-- Teal A400 -->
     <color name="folder_badge_color">#1DE9B6</color> <!-- Teal A400 -->
 
-    <!-- System shortcuts -->
-    <color name="system_shortcuts_icon_color">@android:color/tertiary_text_light</color>
-
-    <color name="legacy_icon_background">#FFFFFF</color>
     <color name="icon_background">#E0E0E0</color> <!-- Gray 300 -->
+    <color name="legacy_icon_background">#FFFFFF</color>
+
+    <color name="all_apps_bg_hand_fill">#E5E5E5</color>
 </resources>
diff --git a/res/values/config.xml b/res/values/config.xml
index 5a8da76..db1a75d 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -13,6 +13,10 @@
      easily override the app name without providing all translations -->
     <string name="derived_app_name" translatable="false">@string/app_name</string>
 
+    <!-- String representing the intent for search on the apps market. To specify a query, add
+    q=<query> to the data to the intent -->
+    <string name="market_search_intent" translatable="false">market://search?c=apps</string>
+
     <!-- 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">
@@ -26,11 +30,12 @@
     <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>Square</item>
-        <item>Squircle</item>
-        <item>Circle</item>
-        <item>Teardrop</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" />
 
@@ -59,6 +64,9 @@
     <!-- The duration of the animation from search hint to text entry -->
     <integer name="config_searchHintAnimationDuration">50</integer>
 
+    <!-- View tag key used to store SpringAnimation data. -->
+    <item type="id" name="spring_animation_tag" />
+
 <!-- Workspace -->
     <!-- The duration (in ms) of the fade animation on the object outlines, used when
          we are dragging objects around on the home screen. -->
@@ -76,6 +84,7 @@
     <integer name="config_folderExpandDuration">120</integer>
     <integer name="config_materialFolderExpandDuration">200</integer>
     <integer name="config_materialFolderExpandStagger">60</integer>
+    <integer name="config_folderDelay">30</integer>
 
     <!-- The distance at which the animation should take the max duration -->
     <integer name="config_dropAnimMaxDist">800</integer>
@@ -99,15 +108,15 @@
     <!-- Name of a user event dispatcher class. -->
     <string name="user_event_dispatcher_class" translatable="false"></string>
 
+    <!-- Name of a color extraction implementation class. -->
+    <string name="color_extraction_impl_class" translatable="false"></string>
+
     <!-- Package name of the default wallpaper picker. -->
     <string name="wallpaper_picker_package" translatable="false"></string>
 
     <!-- View ID to use for QSB widget -->
     <item type="id" name="qsb_widget" />
 
-    <!-- View ID to use for blocked area on the first screen -->
-    <item type="id" name="workspace_blocked_row" />
-
     <!-- View ID used by cell layout to jail its content -->
     <item type="id" name="cell_layout_jail_id" />
 
@@ -115,11 +124,8 @@
     <item type="id" name="preview_image_id" />
 
 <!-- Popup items -->
-    <integer name="config_deepShortcutOpenDuration">220</integer>
-    <integer name="config_deepShortcutArrowOpenDuration">80</integer>
-    <integer name="config_deepShortcutOpenStagger">40</integer>
-    <integer name="config_deepShortcutCloseDuration">150</integer>
-    <integer name="config_deepShortcutCloseStagger">20</integer>
+    <integer name="config_popupOpenCloseDuration">220</integer>
+    <integer name="config_popupArrowOpenDuration">80</integer>
     <integer name="config_removeNotificationViewDuration">300</integer>
 
 <!-- Accessibility actions -->
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index bd6466b..3a531b0 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -26,14 +26,17 @@
     <dimen name="dynamic_grid_overview_max_icon_zone_height">120dp</dimen>
     <dimen name="dynamic_grid_overview_bar_item_width">80dp</dimen>
     <dimen name="dynamic_grid_overview_bar_spacer_width">25dp</dimen>
-    <dimen name="dynamic_grid_hotseat_height">88dp</dimen>
-    <dimen name="dynamic_grid_hotseat_top_padding">8dp</dimen>
-    <dimen name="dynamic_grid_hotseat_gutter_width">24dp</dimen>
     <dimen name="dynamic_grid_workspace_top_padding">12dp</dimen>
     <dimen name="dynamic_grid_workspace_page_spacing">8dp</dimen>
     <!-- Minimum space between workspace and hotseat in spring loaded mode -->
     <dimen name="dynamic_grid_min_spring_loaded_space">8dp</dimen>
 
+    <!-- Hotseat -->
+    <dimen name="dynamic_grid_hotseat_top_padding">8dp</dimen>
+    <dimen name="dynamic_grid_hotseat_bottom_padding">0dp</dimen>
+    <dimen name="dynamic_grid_hotseat_height">80dp</dimen>
+    <dimen name="dynamic_grid_hotseat_land_gutter_width">24dp</dimen>
+
 <!-- Drop target bar -->
     <dimen name="dynamic_grid_drop_target_size">48dp</dimen>
     <dimen name="vert_drop_target_vertical_gap">20dp</dimen>
@@ -45,11 +48,6 @@
     <dimen name="resize_frame_background_padding">24dp</dimen>
 
 <!-- Container -->
-    <!-- Note: This needs to match the fixed insets for the search box. -->
-    <dimen name="container_bounds_inset">8dp</dimen>
-    <!-- Notes: container_bounds_inset - quantum_panel_outer_padding -->
-    <dimen name="container_bounds_minus_quantum_panel_padding_inset">4dp</dimen>
-
     <dimen name="container_fastscroll_thumb_min_width">5dp</dimen>
     <dimen name="container_fastscroll_thumb_max_width">9dp</dimen>
     <dimen name="container_fastscroll_popup_margin">18dp</dimen>
@@ -62,9 +60,6 @@
     <dimen name="all_apps_button_scale_down">0dp</dimen>
     <dimen name="all_apps_search_bar_field_height">48dp</dimen>
     <dimen name="all_apps_search_bar_height">60dp</dimen>
-    <dimen name="all_apps_search_bar_icon_margin_right">4dp</dimen>
-    <dimen name="all_apps_search_bar_icon_margin_top">1dp</dimen>
-    <dimen name="all_apps_list_bottom_padding">8dp</dimen>
     <dimen name="all_apps_empty_search_message_top_offset">40dp</dimen>
     <dimen name="all_apps_empty_search_bg_top_offset">144dp</dimen>
     <dimen name="all_apps_background_canvas_width">700dp</dimen>
@@ -109,6 +104,7 @@
     <!-- Drag padding to add to the bottom of drop targets -->
     <dimen name="drop_target_drag_padding">14dp</dimen>
     <dimen name="drop_target_text_size">14sp</dimen>
+    <dimen name="drop_target_shadow_elevation">2dp</dimen>
 
     <!-- the distance an icon must be dragged before button drop targets accept it -->
     <dimen name="drag_distanceThreshold">30dp</dimen>
@@ -123,7 +119,7 @@
 
 <!-- Folders -->
     <!-- The size of the padding on the preview background drawable -->
-    <dimen name="folder_preview_padding">6dp</dimen>
+    <dimen name="folder_preview_padding">10dp</dimen>
     <dimen name="page_indicator_dot_size">8dp</dimen>
 
     <dimen name="folder_cell_x_padding">9dp</dimen>
@@ -152,7 +148,6 @@
     <dimen name="deep_shortcuts_elevation">9dp</dimen>
     <dimen name="bg_popup_item_width">220dp</dimen>
     <dimen name="bg_popup_item_height">56dp</dimen>
-    <dimen name="popup_items_spacing">4dp</dimen>
     <dimen name="pre_drag_view_scale">6dp</dimen>
     <!-- an icon with shortcuts must be dragged this far before the container is removed. -->
     <dimen name="deep_shortcuts_start_drag_threshold">16dp</dimen>
diff --git a/res/drawable/bg_white_round_rect.xml b/res/values/drawables.xml
similarity index 65%
copy from res/drawable/bg_white_round_rect.xml
copy to res/values/drawables.xml
index c7f786f..fea17b1 100644
--- a/res/drawable/bg_white_round_rect.xml
+++ b/res/values/drawables.xml
@@ -5,7 +5,7 @@
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
 
-          http://www.apache.org/licenses/LICENSE-2.0
+        http://www.apache.org/licenses/LICENSE-2.0
 
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
@@ -13,9 +13,8 @@
      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="#FFFFFF" />
-    <corners android:radius="@dimen/bg_round_rect_radius" />
-</shape>
\ No newline at end of file
+<resources>
+    <drawable name="ic_info_shadow">@drawable/ic_info_no_shadow</drawable>
+    <drawable name="ic_remove_shadow">@drawable/ic_remove_no_shadow</drawable>
+    <drawable name="ic_uninstall_shadow">@drawable/ic_uninstall_no_shadow</drawable>
+</resources>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ecc537d..da6da04 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -159,7 +159,7 @@
     <!-- Text for wallpaper change button -->
     <string name="wallpaper_button_text">Wallpapers</string>
     <!-- Text for settings button -->
-    <string name="settings_button_text">Settings</string>
+    <string name="settings_button_text">Home settings</string>
     <!-- Message shown when a feature is disabled by the administrator -->
     <string name="msg_disabled_by_admin">Disabled by your admin</string>
     <!-- Text for custom accessibility action to go to the overview mode, where users can look and change the overall UI of the launcher. -->
@@ -188,6 +188,15 @@
     <string name="icon_shape_override_label">Change icon shape</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>
 
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 8a46e83..8af6968 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -25,9 +25,58 @@
         <item name="android:windowShowWallpaper">true</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:colorEdgeEffect">#FF757575</item>
+        <item name="android:keyboardLayout">@layout/all_apps_search_container</item>
     </style>
 
-    <style name="LauncherTheme" parent="@style/BaseLauncherTheme"></style>
+    <style name="BaseLauncherThemeWithCustomAttrs" parent="@style/BaseLauncherTheme">
+        <item name="allAppsScrimColor">#DDFFFFFF</item>
+        <item name="popupColorPrimary">#FFF</item>
+        <item name="popupColorSecondary">#F5F5F5</item> <!-- Gray 100 -->
+        <item name="popupColorTertiary">#E0E0E0</item> <!-- Gray 300 -->
+        <item name="isMainColorDark">false</item>
+        <item name="isWorkspaceDarkText">false</item>
+        <item name="workspaceTextColor">@android:color/white</item>
+        <item name="workspaceShadowColor">#B0000000</item>
+        <item name="workspaceAmbientShadowColor">#33000000</item>
+        <item name="workspaceKeyShadowColor">#44000000</item>
+        <item name="workspaceStatusBarScrim">@drawable/workspace_bg</item>
+    </style>
+
+    <style name="LauncherTheme" parent="@style/BaseLauncherThemeWithCustomAttrs"></style>
+
+    <style name="LauncherThemeDarkText" parent="@style/LauncherTheme">
+        <item name="workspaceTextColor">#FF212121</item>
+        <item name="workspaceShadowColor">@android:color/transparent</item>
+        <item name="workspaceAmbientShadowColor">@android:color/transparent</item>
+        <item name="workspaceKeyShadowColor">@android:color/transparent</item>
+        <item name="isWorkspaceDarkText">true</item>
+        <item name="workspaceStatusBarScrim">@null</item>
+    </style>
+
+    <style name="LauncherThemeDark" parent="@style/LauncherTheme">
+        <item name="android:textColorPrimary">#FFFFFFFF</item>
+        <item name="android:textColorSecondary">#FFFFFFFF</item>
+        <item name="android:textColorTertiary">#CCFFFFFF</item>
+        <item name="android:textColorHint">#A0FFFFFF</item>
+        <item name="android:colorControlHighlight">#A0FFFFFF</item>
+        <item name="android:colorPrimary">#FF333333</item>
+        <item name="allAppsScrimColor">#33000000</item>
+        <item name="popupColorPrimary">?android:attr/colorPrimary</item>
+        <item name="popupColorSecondary">#424242</item> <!-- Gray 800 -->
+        <item name="popupColorTertiary">#757575</item> <!-- Gray 600 -->
+        <item name="isMainColorDark">true</item>
+    </style>
+
+    <!--
+    Theme overrides to element on homescreen, i.e., which are drawn on top on wallpaper.
+    Various foreground colors are overridden to be workspaceTextColor so that they are properly
+    visible on various wallpapers.
+    -->
+    <style name="HomeScreenElementTheme">
+        <item name="android:colorEdgeEffect">?attr/workspaceTextColor</item>
+        <item name="android:textColorPrimary">?attr/workspaceTextColor</item>
+        <item name="android:textColorSecondary">?attr/workspaceTextColor</item>
+    </style>
 
     <!-- Theme for the widget container. Overridden on API 26. -->
     <style name="WidgetContainerTheme" parent="@android:style/Theme.DeviceDefault.Settings">
@@ -76,9 +125,15 @@
     <!-- Icon displayed on the worksapce -->
     <style name="BaseIcon.Workspace">
         <item name="customShadows">true</item>
-        <item name="android:textColor">@color/workspace_icon_text_color</item>
         <item name="android:shadowRadius">2.0</item>
-        <item name="android:shadowColor">#B0000000</item>
+        <item name="android:shadowColor">?attr/workspaceShadowColor</item>
+        <item name="keyShadowColor">?attr/workspaceKeyShadowColor</item>
+        <item name="ambientShadowColor">?attr/workspaceAmbientShadowColor</item>
+    </style>
+
+    <!-- Theme for the popup container -->
+    <style name="PopupItem">
+        <item name="android:colorControlHighlight">?attr/popupColorTertiary</item>
     </style>
 
     <!-- Drop targets -->
@@ -86,15 +141,19 @@
         <item name="android:drawablePadding">7.5dp</item>
         <item name="android:paddingLeft">16dp</item>
         <item name="android:paddingRight">16dp</item>
-        <item name="android:textColor">@color/workspace_icon_text_color</item>
+        <item name="android:textColor">?attr/workspaceTextColor</item>
         <item name="android:textSize">@dimen/drop_target_text_size</item>
         <item name="android:singleLine">true</item>
         <item name="android:ellipsize">end</item>
-        <item name="android:shadowColor">@color/default_shadow_color_no_alpha</item>
+        <item name="android:shadowColor">?attr/workspaceShadowColor</item>
         <item name="android:shadowDx">0.0</item>
         <item name="android:shadowDy">1.0</item>
         <item name="android:shadowRadius">4.0</item>
     </style>
 
     <style name="DropTargetButton" parent="DropTargetButtonBase" />
+
+    <style name="TextTitle">
+        <item name="android:fontFamily">sans-serif</item>
+    </style>
 </resources>
diff --git a/res/xml/backupscheme.xml b/res/xml/backupscheme.xml
index 7e833a0..299e92e 100644
--- a/res/xml/backupscheme.xml
+++ b/res/xml/backupscheme.xml
@@ -3,5 +3,6 @@
 
     <include domain="database" path="launcher.db" />
     <include domain="sharedpref" path="com.android.launcher3.prefs.xml" />
+    <include domain="file" path="downgrade_schema.json" />
 
 </full-backup-content>
\ No newline at end of file
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 5b42cad..8ac8570 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -18,10 +18,16 @@
 
 import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
+import android.os.Process;
 import android.os.UserHandle;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.Log;
 
 import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.util.FlagOp;
 import com.android.launcher3.util.ItemInfoMatcher;
 
@@ -34,18 +40,18 @@
  * Stores the list of all applications for the all apps view.
  */
 public class AllAppsList {
+    private static final String TAG = "AllAppsList";
+
     public static final int DEFAULT_APPLICATIONS_NUMBER = 42;
 
     /** The list off all apps. */
-    public ArrayList<AppInfo> data =
-            new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
+    public final ArrayList<AppInfo> data = new ArrayList<>(DEFAULT_APPLICATIONS_NUMBER);
     /** The list of apps that have been added since the last notify() call. */
-    public ArrayList<AppInfo> added =
-            new ArrayList<AppInfo>(DEFAULT_APPLICATIONS_NUMBER);
+    public ArrayList<AppInfo> added = new ArrayList<>(DEFAULT_APPLICATIONS_NUMBER);
     /** The list of apps that have been removed since the last notify() call. */
-    public ArrayList<AppInfo> removed = new ArrayList<AppInfo>();
+    public ArrayList<AppInfo> removed = new ArrayList<>();
     /** The list of apps that have been modified since the last notify() call. */
-    public ArrayList<AppInfo> modified = new ArrayList<AppInfo>();
+    public ArrayList<AppInfo> modified = new ArrayList<>();
 
     private IconCache mIconCache;
 
@@ -69,7 +75,7 @@
         if (!mAppFilter.shouldShowApp(info.componentName)) {
             return;
         }
-        if (findActivity(data, info.componentName, info.user)) {
+        if (findAppInfo(info.componentName, info.user) != null) {
             return;
         }
         mIconCache.getTitleAndIcon(info, activityInfo, true /* useLowResIcon */);
@@ -78,6 +84,25 @@
         added.add(info);
     }
 
+    public void addPromiseApp(Context context,
+                              PackageInstallerCompat.PackageInstallInfo installInfo) {
+        ApplicationInfo applicationInfo = LauncherAppsCompat.getInstance(context)
+                .getApplicationInfo(installInfo.packageName, 0, Process.myUserHandle());
+        // only if not yet installed
+        if (applicationInfo == null) {
+            PromiseAppInfo info = new PromiseAppInfo(installInfo);
+            mIconCache.getTitleAndIcon(info, info.usingLowResIcon);
+            data.add(info);
+            added.add(info);
+        }
+    }
+
+    public void removePromiseApp(AppInfo appInfo) {
+        // the <em>removed</em> list is handled by the caller
+        // so not adding it here
+        data.remove(appInfo);
+    }
+
     public void clear() {
         data.clear();
         // TODO: do we clear these too?
@@ -160,6 +185,7 @@
                 if (user.equals(applicationInfo.user)
                         && packageName.equals(applicationInfo.componentName.getPackageName())) {
                     if (!findActivity(matches, applicationInfo.componentName)) {
+                        Log.w(TAG, "Shortcut will be removed due to app component name change.");
                         removed.add(applicationInfo);
                         data.remove(i);
                     }
@@ -169,9 +195,7 @@
             // Find enabled activities and add them to the adapter
             // Also updates existing activities with new labels/icons
             for (final LauncherActivityInfo info : matches) {
-                AppInfo applicationInfo = findApplicationInfoLocked(
-                        info.getComponentName().getPackageName(), user,
-                        info.getComponentName().getClassName());
+                AppInfo applicationInfo = findAppInfo(info.getComponentName(), user);
                 if (applicationInfo == null) {
                     add(new AppInfo(context, info, user), info);
                 } else {
@@ -208,28 +232,14 @@
     }
 
     /**
-     * Returns whether <em>apps</em> contains <em>component</em>.
+     * Find an AppInfo object for the given componentName
+     *
+     * @return the corresponding AppInfo or null
      */
-    private static boolean findActivity(ArrayList<AppInfo> apps, ComponentName component,
-            UserHandle user) {
-        final int N = apps.size();
-        for (int i = 0; i < N; i++) {
-            final AppInfo info = apps.get(i);
-            if (info.user.equals(user) && info.componentName.equals(component)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Find an ApplicationInfo object for the given packageName and className.
-     */
-    private AppInfo findApplicationInfoLocked(String packageName, UserHandle user,
-            String className) {
+    private @Nullable AppInfo findAppInfo(@NonNull ComponentName componentName,
+                                          @NonNull UserHandle user) {
         for (AppInfo info: data) {
-            if (user.equals(info.user) && packageName.equals(info.componentName.getPackageName())
-                    && className.equals(info.componentName.getClassName())) {
+            if (componentName.equals(info.componentName) && user.equals(info.user)) {
                 return info;
             }
         }
diff --git a/src/com/android/launcher3/AppFilter.java b/src/com/android/launcher3/AppFilter.java
index db8f5dd..923835a 100644
--- a/src/com/android/launcher3/AppFilter.java
+++ b/src/com/android/launcher3/AppFilter.java
@@ -1,9 +1,14 @@
 package com.android.launcher3;
 
 import android.content.ComponentName;
+import android.content.Context;
 
 public class AppFilter {
 
+    public static AppFilter newInstance(Context context) {
+        return Utilities.getOverrideObject(AppFilter.class, context, R.string.app_filter_class);
+    }
+
     public boolean shouldShowApp(ComponentName app) {
         return true;
     }
diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
index 84a8bce..70be7da 100644
--- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
+++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
@@ -12,6 +12,7 @@
 import android.util.Log;
 
 import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.model.LoaderTask;
 import com.android.launcher3.util.ContentWriter;
 
 public class AppWidgetsRestoredReceiver extends BroadcastReceiver {
@@ -52,7 +53,7 @@
 
             final AppWidgetProviderInfo provider = widgets.getAppWidgetInfo(newWidgetIds[i]);
             final int state;
-            if (LauncherModel.isValidProvider(provider)) {
+            if (LoaderTask.isValidProvider(provider)) {
                 // This will ensure that we show 'Click to setup' UI if required.
                 state = LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
             } else {
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index c4086a8..98eb208 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -393,7 +393,7 @@
                 return -1;
             }
 
-            mValues.put(Favorites.RESTORED, ShortcutInfo.FLAG_AUTOINTALL_ICON);
+            mValues.put(Favorites.RESTORED, ShortcutInfo.FLAG_AUTOINSTALL_ICON);
             final Intent intent = new Intent(Intent.ACTION_MAIN, null)
                 .addCategory(Intent.CATEGORY_LAUNCHER)
                 .setComponent(new ComponentName(packageName, className))
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 6fdf454..514cc07 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -48,6 +48,8 @@
     private int mDownY;
     private int mLastY;
 
+    private boolean mScrollBarVisible = true;
+
     public BaseRecyclerView(Context context) {
         this(context, null);
     }
@@ -82,10 +84,6 @@
         }
     }
 
-    public void reset() {
-        mScrollbar.reattachThumbToScroll();
-    }
-
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -117,6 +115,7 @@
      * it is already showing).
      */
     private boolean handleTouchEvent(MotionEvent ev) {
+        ev.offsetLocation(0, -getPaddingTop());
         int action = ev.getAction();
         int x = (int) ev.getX();
         int y = (int) ev.getY();
@@ -140,6 +139,7 @@
                 mScrollbar.handleTouchEvent(ev, mDownX, mDownY, mLastY);
                 break;
         }
+        ev.offsetLocation(0, getPaddingTop());
         return mScrollbar.isDraggingThumb();
     }
 
@@ -166,7 +166,7 @@
      * Returns the height of the fast scroll bar
      */
     protected int getScrollbarTrackHeight() {
-        return getHeight();
+        return getHeight() - getPaddingTop() - getPaddingBottom();
     }
 
     /**
@@ -201,8 +201,18 @@
     @Override
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
-        onUpdateScrollbar(0);
-        mScrollbar.draw(canvas);
+        if (mScrollBarVisible) {
+            onUpdateScrollbar(0);
+            mScrollbar.draw(canvas);
+        }
+    }
+
+    /**
+     * Sets the scrollbar visibility. The call does not refresh the UI, its the responsibility
+     * of the caller to call {@link #invalidate()}.
+     */
+    public void setScrollBarVisible(boolean visible) {
+        mScrollBarVisible = visible;
     }
 
     /**
diff --git a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
index 5feb42e..3039744 100644
--- a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
+++ b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
@@ -136,6 +136,7 @@
         mTmpRect.set(drawLeft, mThumbOffsetY, drawLeft + mMaxWidth, mThumbOffsetY + mThumbHeight);
         mThumbOffsetY = y;
         mTmpRect.union(drawLeft, mThumbOffsetY, drawLeft + mMaxWidth, mThumbOffsetY + mThumbHeight);
+        mTmpRect.offset(0, mRv.getPaddingTop());
         mRv.invalidate(mTmpRect);
     }
 
@@ -148,8 +149,9 @@
             return;
         }
         int left = getDrawLeft();
+        int top = mRv.getPaddingTop();
         // Invalidate the whole scroll bar area.
-        mRv.invalidate(left, 0, left + mMaxWidth, mRv.getScrollbarTrackHeight());
+        mRv.invalidate(left, top, left + mMaxWidth, top + mRv.getScrollbarTrackHeight());
 
         mWidth = width;
         updateThumbPath();
@@ -265,6 +267,7 @@
         if (!mIsRtl) {
             canvas.translate(mRv.getWidth(), 0);
         }
+        canvas.translate(0, mRv.getPaddingTop());
         // Draw the track
         int thumbWidth = mIsRtl ? mWidth : -mWidth;
         canvas.drawRect(0, 0, thumbWidth, mRv.getScrollbarTrackHeight(), mTrackPaint);
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 3c3e224..27e190e 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -23,10 +23,12 @@
 import android.content.res.TypedArray;
 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.graphics.Region;
+import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.util.Property;
@@ -43,7 +45,7 @@
 import com.android.launcher3.IconCache.ItemInfoUpdateReceiver;
 import com.android.launcher3.badge.BadgeInfo;
 import com.android.launcher3.badge.BadgeRenderer;
-import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.folder.FolderIconPreviewVerifier;
 import com.android.launcher3.graphics.DrawableFactory;
 import com.android.launcher3.graphics.HolographicOutlineHelper;
 import com.android.launcher3.graphics.IconPalette;
@@ -63,8 +65,6 @@
     private static final float AMBIENT_SHADOW_RADIUS = 2.5f;
     private static final float KEY_SHADOW_RADIUS = 1f;
     private static final float KEY_SHADOW_OFFSET = 0.5f;
-    private static final int AMBIENT_SHADOW_COLOR = 0x33000000;
-    private static final int KEY_SHADOW_COLOR = 0x66000000;
 
     private static final int DISPLAY_WORKSPACE = 0;
     private static final int DISPLAY_ALL_APPS = 1;
@@ -80,6 +80,8 @@
     private final CheckLongPressHelper mLongPressHelper;
     private final HolographicOutlineHelper mOutlineHelper;
     private final StylusEventHelper mStylusEventHelper;
+    private final int mAmbientShadowColor;
+    private final int mKeyShadowColor;
 
     private boolean mBackgroundSizeChanged;
 
@@ -93,6 +95,7 @@
     private final int mIconSize;
     @ViewDebug.ExportedProperty(category = "launcher")
     private int mTextColor;
+    private boolean mIsIconVisible = true;
 
     private BadgeInfo mBadgeInfo;
     private BadgeRenderer mBadgeRenderer;
@@ -144,6 +147,8 @@
         mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false);
         mDeferShadowGenerationOnTouch =
                 a.getBoolean(R.styleable.BubbleTextView_deferShadowGeneration, false);
+        mAmbientShadowColor = a.getColor(R.styleable.BubbleTextView_ambientShadowColor, 0x33000000);
+        mKeyShadowColor = a.getColor(R.styleable.BubbleTextView_keyShadowColor, 0x66000000);
 
         int display = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE);
         int defaultIconSize = grid.iconSizePx;
@@ -171,7 +176,7 @@
 
             // Set shadow layer as the larger shadow to that the textView does not clip the shadow.
             float density = getResources().getDisplayMetrics().density;
-            setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, AMBIENT_SHADOW_COLOR);
+            setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, mAmbientShadowColor);
         } else {
             mBackground = null;
         }
@@ -206,6 +211,10 @@
         // Verify high res immediately
         verifyHighRes();
 
+        if (info instanceof PromiseAppInfo) {
+            PromiseAppInfo promiseAppInfo = (PromiseAppInfo) info;
+            applyProgressLevel(promiseAppInfo.level);
+        }
         applyBadgeState(info, false /* animate */);
     }
 
@@ -428,14 +437,14 @@
 
         // We enhance the shadow by drawing the shadow twice
         float density = getResources().getDisplayMetrics().density;
-        getPaint().setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, AMBIENT_SHADOW_COLOR);
+        getPaint().setShadowLayer(density * AMBIENT_SHADOW_RADIUS, 0, 0, mAmbientShadowColor);
         super.draw(canvas);
         canvas.save(Canvas.CLIP_SAVE_FLAG);
         canvas.clipRect(getScrollX(), getScrollY() + getExtendedPaddingTop(),
                 getScrollX() + getWidth(),
                 getScrollY() + getHeight(), Region.Op.INTERSECT);
         getPaint().setShadowLayer(
-                density * KEY_SHADOW_RADIUS, 0.0f, density * KEY_SHADOW_OFFSET, KEY_SHADOW_COLOR);
+                density * KEY_SHADOW_RADIUS, 0.0f, density * KEY_SHADOW_OFFSET, mKeyShadowColor);
         super.draw(canvas);
         canvas.restore();
 
@@ -547,27 +556,36 @@
                     ((info.hasStatusFlag(ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE) ?
                             info.getInstallProgress() : 0)) : 100;
 
-            setContentDescription(progressLevel > 0 ?
-                    getContext().getString(R.string.app_downloading_title, info.title,
-                            NumberFormat.getPercentInstance().format(progressLevel * 0.01)) :
-                    getContext().getString(R.string.app_waiting_download_title, info.title));
+            PreloadIconDrawable preloadDrawable = applyProgressLevel(progressLevel);
+            if (preloadDrawable != null && promiseStateChanged) {
+                preloadDrawable.maybePerformFinishedAnimation();
+            }
+        }
+    }
+
+    public PreloadIconDrawable applyProgressLevel(int progressLevel) {
+        if (getTag() instanceof ItemInfoWithIcon) {
+            ItemInfoWithIcon info = (ItemInfoWithIcon) getTag();
+            setContentDescription(progressLevel > 0
+                    ? getContext().getString(R.string.app_downloading_title, info.title,
+                    NumberFormat.getPercentInstance().format(progressLevel * 0.01))
+                    : getContext().getString(R.string.app_waiting_download_title, info.title));
 
             if (mIcon != null) {
                 final PreloadIconDrawable preloadDrawable;
                 if (mIcon instanceof PreloadIconDrawable) {
                     preloadDrawable = (PreloadIconDrawable) mIcon;
+                    preloadDrawable.setLevel(progressLevel);
                 } else {
                     preloadDrawable = DrawableFactory.get(getContext())
                             .newPendingIcon(info.iconBitmap, getContext());
+                    preloadDrawable.setLevel(progressLevel);
                     setIcon(preloadDrawable);
                 }
-
-                preloadDrawable.setLevel(progressLevel);
-                if (promiseStateChanged) {
-                    preloadDrawable.maybePerformFinishedAnimation();
-                }
+                return preloadDrawable;
             }
         }
+        return null;
     }
 
     public void applyBadgeState(ItemInfo itemInfo, boolean animate) {
@@ -603,7 +621,21 @@
     private void setIcon(Drawable icon) {
         mIcon = icon;
         mIcon.setBounds(0, 0, mIconSize, mIconSize);
-        applyCompoundDrawables(mIcon);
+        if (mIsIconVisible) {
+            applyCompoundDrawables(mIcon);
+        }
+    }
+
+    public void setIconVisible(boolean visible) {
+        mIsIconVisible = visible;
+        mDisableRelayout = true;
+        Drawable icon = mIcon;
+        if (!visible) {
+            icon = new ColorDrawable(Color.TRANSPARENT);
+            icon.setBounds(0, 0, mIconSize, mIconSize);
+        }
+        applyCompoundDrawables(icon);
+        mDisableRelayout = false;
     }
 
     protected void applyCompoundDrawables(Drawable icon) {
@@ -634,7 +666,9 @@
                 applyFromApplicationInfo((AppInfo) info);
             } else if (info instanceof ShortcutInfo) {
                 applyFromShortcutInfo((ShortcutInfo) info);
-                if ((info.rank < FolderIcon.NUM_ITEMS_IN_PREVIEW) && (info.container >= 0)) {
+                FolderIconPreviewVerifier verifier =
+                        new FolderIconPreviewVerifier(mLauncher.getDeviceProfile().inv);
+                if (verifier.isItemInPreview(info.rank) && (info.container >= 0)) {
                     View folderIcon =
                             mLauncher.getWorkspace().getHomescreenIconByItemId(info.container);
                     if (folderIcon != null) {
@@ -666,6 +700,10 @@
         }
     }
 
+    public int getIconSize() {
+        return mIconSize;
+    }
+
     /**
      * Interface to be implemented by the grand parent to allow click shadow effect.
      */
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 8179dad..c2c5c27 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -51,12 +51,13 @@
 import com.android.launcher3.accessibility.FolderAccessibilityHelper;
 import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper;
 import com.android.launcher3.anim.PropertyListBuilder;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.graphics.DragPreviewProvider;
 import com.android.launcher3.util.CellAndSpan;
 import com.android.launcher3.util.GridOccupancy;
 import com.android.launcher3.util.ParcelableSparseArray;
+import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 
 import java.lang.annotation.Retention;
@@ -235,7 +236,7 @@
         for (int i = 0; i < mDragOutlines.length; i++) {
             mDragOutlines[i] = new Rect(-1, -1, -1, -1);
         }
-        mDragOutlinePaint.setColor(getResources().getColor(R.color.outline_color));
+        mDragOutlinePaint.setColor(Themes.getAttrColor(context, R.attr.workspaceTextColor));
 
         // When dragging things around the home screens, we show a green outline of
         // where the item will land. The outlines gradually fade out, leaving a trail
@@ -541,11 +542,8 @@
     }
 
     public void setFolderLeaveBehindCell(int x, int y) {
-
-        DeviceProfile grid = mLauncher.getDeviceProfile();
         View child = getChildAt(x, y);
-
-        mFolderLeaveBehind.setup(getResources().getDisplayMetrics(), grid, null,
+        mFolderLeaveBehind.setup(mLauncher, null,
                 child.getMeasuredWidth(), child.getPaddingTop());
 
         mFolderLeaveBehind.delegateCellX = x;
@@ -568,7 +566,7 @@
         try {
             dispatchRestoreInstanceState(states);
         } catch (IllegalArgumentException ex) {
-            if (ProviderConfig.IS_DOGFOOD_BUILD) {
+            if (FeatureFlags.IS_DOGFOOD_BUILD) {
                 throw ex;
             }
             // Mismatched viewId / viewType preventing restore. Skip restore on production builds.
diff --git a/src/com/android/launcher3/DeferredHandler.java b/src/com/android/launcher3/DeferredHandler.java
deleted file mode 100644
index a43ab67..0000000
--- a/src/com/android/launcher3/DeferredHandler.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.MessageQueue;
-
-import com.android.launcher3.util.Thunk;
-
-import java.util.LinkedList;
-
-/**
- * Queue of things to run on a looper thread.  Items posted with {@link #post} will not
- * be actually enqued on the handler until after the last one has run, to keep from
- * starving the thread.
- *
- * This class is fifo.
- */
-public class DeferredHandler {
-    @Thunk LinkedList<Runnable> mQueue = new LinkedList<>();
-    private MessageQueue mMessageQueue = Looper.myQueue();
-    private Impl mHandler = new Impl();
-
-    @Thunk class Impl extends Handler implements MessageQueue.IdleHandler {
-        public void handleMessage(Message msg) {
-            Runnable r;
-            synchronized (mQueue) {
-                if (mQueue.size() == 0) {
-                    return;
-                }
-                r = mQueue.removeFirst();
-            }
-            r.run();
-            synchronized (mQueue) {
-                scheduleNextLocked();
-            }
-        }
-
-        public boolean queueIdle() {
-            handleMessage(null);
-            return false;
-        }
-    }
-
-    private class IdleRunnable implements Runnable {
-        Runnable mRunnable;
-
-        IdleRunnable(Runnable r) {
-            mRunnable = r;
-        }
-
-        public void run() {
-            mRunnable.run();
-        }
-    }
-
-    public DeferredHandler() {
-    }
-
-    /** Schedule runnable to run after everything that's on the queue right now. */
-    public void post(Runnable runnable) {
-        synchronized (mQueue) {
-            mQueue.add(runnable);
-            if (mQueue.size() == 1) {
-                scheduleNextLocked();
-            }
-        }
-    }
-
-    /** Schedule runnable to run when the queue goes idle. */
-    public void postIdle(final Runnable runnable) {
-        post(new IdleRunnable(runnable));
-    }
-
-    public void cancelAll() {
-        synchronized (mQueue) {
-            mQueue.clear();
-        }
-    }
-
-    /** Runs all queued Runnables from the calling thread. */
-    public void flush() {
-        LinkedList<Runnable> queue = new LinkedList<>();
-        synchronized (mQueue) {
-            queue.addAll(mQueue);
-            mQueue.clear();
-        }
-        for (Runnable r : queue) {
-            r.run();
-        }
-    }
-
-    void scheduleNextLocked() {
-        if (mQueue.size() > 0) {
-            Runnable peek = mQueue.getFirst();
-            if (peek instanceof IdleRunnable) {
-                mMessageQueue.addIdleHandler(mHandler);
-            } else {
-                mHandler.sendEmptyMessage(1);
-            }
-        }
-    }
-}
-
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 9097ed2..975675a 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -40,7 +40,7 @@
         // Get the hover color
         mHoverColor = getResources().getColor(R.color.delete_target_hover_tint);
 
-        setDrawable(R.drawable.ic_remove_launcher);
+        setDrawable(R.drawable.ic_remove_shadow);
     }
 
     @Override
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index e47031a..9bb56d6 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -113,9 +113,9 @@
     public int hotseatCellHeightPx;
     public int hotseatIconSizePx;
     public int hotseatBarHeightPx;
-    private int hotseatBarTopPaddingPx;
-    private int hotseatBarBottomPaddingPx;
-    private int hotseatLandGutterPx;
+    public int hotseatBarTopPaddingPx;
+    public int hotseatBarBottomPaddingPx;
+    public int hotseatLandGutterPx;
 
     // All apps
     public int allAppsNumCols;
@@ -191,11 +191,14 @@
         dropTargetBarSizePx = res.getDimensionPixelSize(R.dimen.dynamic_grid_drop_target_size);
         workspaceSpringLoadedBottomSpace =
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space);
-        hotseatBarHeightPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_height);
+
         hotseatBarTopPaddingPx =
                 res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_top_padding);
-        hotseatBarBottomPaddingPx = 0;
-        hotseatLandGutterPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_gutter_width);
+        hotseatBarBottomPaddingPx =
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_bottom_padding);
+        hotseatBarHeightPx = hotseatBarTopPaddingPx + hotseatBarBottomPaddingPx +
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_height);
+        hotseatLandGutterPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_hotseat_land_gutter_width);
 
         // Determine sizes.
         widthPx = width;
@@ -228,9 +231,6 @@
         profile.cellHeightPx = profile.iconSizePx + profile.iconDrawablePaddingPx
                 + Utilities.calculateTextHeight(profile.iconTextSizePx);
 
-        // The nav bar is black so we add bottom padding to visually center hotseat icons.
-        profile.hotseatBarBottomPaddingPx = profile.hotseatBarTopPaddingPx;
-
         // We use these scales to measure and layout the widgets using their full invariant profile
         // sizes and then draw them scaled and centered to fit in their multi-window mode cellspans.
         float appWidgetScaleX = (float) profile.getCellSize().x / getCellSize().x;
@@ -532,14 +532,6 @@
                 workspacePadding.bottom);
         workspace.setPageSpacing(getWorkspacePageSpacing());
 
-        // Only display when enabled
-        if (FeatureFlags.QSB_ON_FIRST_SCREEN) {
-            View qsbContainer = launcher.getQsbContainer();
-            lp = (FrameLayout.LayoutParams) qsbContainer.getLayoutParams();
-            lp.topMargin = mInsets.top + workspacePadding.top;
-            qsbContainer.setLayoutParams(lp);
-        }
-
         // Layout the hotseat
         Hotseat hotseat = (Hotseat) launcher.findViewById(R.id.hotseat);
         lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams();
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index b36734b..fe7acda 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -22,7 +22,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderPagedView;
 import com.android.launcher3.util.FocusLogic;
@@ -93,7 +93,7 @@
             }
 
             if (!(v.getParent() instanceof ShortcutAndWidgetContainer)) {
-                if (ProviderConfig.IS_DOGFOOD_BUILD) {
+                if (FeatureFlags.IS_DOGFOOD_BUILD) {
                     throw new IllegalStateException("Parent of the focused item is not supported.");
                 } else {
                     return false;
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index 0041bb4..21254ab 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -65,9 +65,17 @@
      * @param item
      */
     public void add(ShortcutInfo item, boolean animate) {
-        contents.add(item);
+        add(item, contents.size(), animate);
+    }
+
+    /**
+     * Add an app or shortcut for a specified rank.
+     */
+    public void add(ShortcutInfo item, int rank, boolean animate) {
+        rank = Utilities.boundToRange(rank, 0, contents.size());
+        contents.add(rank, item);
         for (int i = 0; i < listeners.size(); i++) {
-            listeners.get(i).onAdd(item);
+            listeners.get(i).onAdd(item, rank);
         }
         itemsChanged(animate);
     }
@@ -121,7 +129,7 @@
     }
 
     public interface FolderListener {
-        public void onAdd(ShortcutInfo item);
+        public void onAdd(ShortcutInfo item, int rank);
         public void onRemove(ShortcutInfo item);
         public void onTitleChanged(CharSequence title);
         public void onItemsChanged(boolean animate);
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 47052a7..ab82c98 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -72,7 +72,9 @@
         mBackgroundColor = ColorUtils.setAlphaComponent(
                 Themes.getAttrColor(context, android.R.attr.colorPrimary), 0);
         mBackground = new ColorDrawable(mBackgroundColor);
-        setBackground(mBackground);
+        if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+            setBackground(mBackground);
+        }
     }
 
     public CellLayout getLayout() {
@@ -179,8 +181,12 @@
     }
 
     public void updateColor(ExtractedColors extractedColors, boolean animate) {
+        if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+            // not hotseat visible
+            return;
+        }
         if (!mHasVerticalHotseat) {
-            int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX, Color.TRANSPARENT);
+            int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX);
             if (mBackgroundColorAnimator != null) {
                 mBackgroundColorAnimator.cancel();
             }
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 1217030..ad816af 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -32,10 +32,6 @@
 import android.database.sqlite.SQLiteException;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.os.Handler;
@@ -55,7 +51,6 @@
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.SQLiteCacheHelper;
-import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 
 import java.util.Collections;
@@ -100,24 +95,14 @@
     @Thunk final UserManagerCompat mUserManager;
     private final LauncherAppsCompat mLauncherApps;
     private final HashMap<ComponentKey, CacheEntry> mCache =
-            new HashMap<ComponentKey, CacheEntry>(INITIAL_ICON_CACHE_CAPACITY);
+            new HashMap<>(INITIAL_ICON_CACHE_CAPACITY);
     private final int mIconDpi;
     @Thunk final IconDB mIconDb;
 
     @Thunk final Handler mWorkerHandler;
 
-    // The background color used for activity icons. Since these icons are displayed in all-apps
-    // and folders, this would be same as the light quantum panel background. This color
-    // is used to convert icons to RGB_565.
-    private final int mActivityBgColor;
-    // The background color used for package icons. These are displayed in widget tray, which
-    // has a dark quantum panel background.
-    private final int mPackageBgColor;
     private final BitmapFactory.Options mLowResOptions;
 
-    private Canvas mLowResCanvas;
-    private Paint mLowResPaint;
-
     public IconCache(Context context, InvariantDeviceProfile inv) {
         mContext = context;
         mPackageManager = context.getPackageManager();
@@ -125,16 +110,11 @@
         mLauncherApps = LauncherAppsCompat.getInstance(mContext);
         mIconDpi = inv.fillResIconDpi;
         mIconDb = new IconDB(context, inv.iconBitmapSize);
-        mLowResCanvas = new Canvas();
-        mLowResPaint = new Paint(Paint.FILTER_BITMAP_FLAG | Paint.ANTI_ALIAS_FLAG);
 
         mIconProvider = Utilities.getOverrideObject(
                 IconProvider.class, context, R.string.icon_provider_class);
         mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
 
-        mActivityBgColor = Themes.getColorPrimary(context, R.style.LauncherTheme);
-        mPackageBgColor = Themes.getColorPrimary(context, R.style.WidgetContainerTheme);
-
         mLowResOptions = new BitmapFactory.Options();
         // Always prefer RGB_565 config for low res. If the bitmap has transparency, it will
         // automatically be loaded as ALPHA_8888.
@@ -387,7 +367,7 @@
         entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, app.getUser());
         mCache.put(key, entry);
 
-        Bitmap lowResIcon = generateLowResIcon(entry.icon, mActivityBgColor);
+        Bitmap lowResIcon = generateLowResIcon(entry.icon);
         ContentValues values = newContentValues(entry.icon, lowResIcon, entry.title.toString(),
                 app.getApplicationInfo().packageName);
         addIconToDB(values, app.getComponentName(), info, userSerial);
@@ -637,7 +617,7 @@
                     // only keep the low resolution icon instead of the larger full-sized icon
                     Bitmap icon = LauncherIcons.createBadgedIconBitmap(
                             appInfo.loadIcon(mPackageManager), user, mContext, appInfo.targetSdkVersion);
-                    Bitmap lowResIcon =  generateLowResIcon(icon, mPackageBgColor);
+                    Bitmap lowResIcon =  generateLowResIcon(icon);
                     entry.title = appInfo.loadLabel(mPackageManager);
                     entry.contentDescription = mUserManager.getBadgedLabelForUser(entry.title, user);
                     entry.icon = useLowResIcon ? lowResIcon : icon;
@@ -769,7 +749,7 @@
     }
 
     private static final class IconDB extends SQLiteCacheHelper {
-        private final static int DB_VERSION = 13;
+        private final static int DB_VERSION = 14;
 
         private final static int RELEASE_VERSION = DB_VERSION +
                 (FeatureFlags.LAUNCHER3_DISABLE_ICON_NORMALIZATION ? 0 : 1);
@@ -822,24 +802,10 @@
     /**
      * Generates a new low-res icon given a high-res icon.
      */
-    private Bitmap generateLowResIcon(Bitmap icon, int lowResBackgroundColor) {
-        if (lowResBackgroundColor == Color.TRANSPARENT) {
-            return Bitmap.createScaledBitmap(icon,
-                            icon.getWidth() / LOW_RES_SCALE_FACTOR,
-                            icon.getHeight() / LOW_RES_SCALE_FACTOR, true);
-        } else {
-            Bitmap lowResIcon = Bitmap.createBitmap(icon.getWidth() / LOW_RES_SCALE_FACTOR,
-                    icon.getHeight() / LOW_RES_SCALE_FACTOR, Bitmap.Config.RGB_565);
-            synchronized (this) {
-                mLowResCanvas.setBitmap(lowResIcon);
-                mLowResCanvas.drawColor(lowResBackgroundColor);
-                mLowResCanvas.drawBitmap(icon, new Rect(0, 0, icon.getWidth(), icon.getHeight()),
-                        new Rect(0, 0, lowResIcon.getWidth(), lowResIcon.getHeight()),
-                        mLowResPaint);
-                mLowResCanvas.setBitmap(null);
-            }
-            return lowResIcon;
-        }
+    private Bitmap generateLowResIcon(Bitmap icon) {
+        return Bitmap.createScaledBitmap(icon,
+                icon.getWidth() / LOW_RES_SCALE_FACTOR,
+                icon.getHeight() / LOW_RES_SCALE_FACTOR, true);
     }
 
     private static Bitmap loadIconNoResize(Cursor c, int iconIndex, BitmapFactory.Options options) {
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index 0608fdd..f088d11 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -42,12 +42,10 @@
     }
 
     @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
+    protected void setupUi() {
         // Get the hover color
         mHoverColor = Themes.getColorAccent(getContext());
-
-        setDrawable(R.drawable.ic_info_launcher);
+        setDrawable(R.drawable.ic_info_shadow);
     }
 
     @Override
@@ -67,6 +65,11 @@
 
     public static boolean startDetailsActivityForInfo(ItemInfo info, Launcher launcher,
             DropTargetResultCallback callback, Rect sourceBounds, Bundle opts) {
+        if (info instanceof PromiseAppInfo) {
+            PromiseAppInfo promiseAppInfo = (PromiseAppInfo) info;
+            launcher.startActivity(promiseAppInfo.getMarketIntent());
+            return true;
+        }
         boolean result = false;
         ComponentName componentName = null;
         if (info instanceof AppInfo) {
diff --git a/src/com/android/launcher3/InsettableFrameLayout.java b/src/com/android/launcher3/InsettableFrameLayout.java
index 154641c..be76490 100644
--- a/src/com/android/launcher3/InsettableFrameLayout.java
+++ b/src/com/android/launcher3/InsettableFrameLayout.java
@@ -9,9 +9,6 @@
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
-import com.android.launcher3.allapps.AllAppsContainerView;
-import com.android.launcher3.config.FeatureFlags;
-
 public class InsettableFrameLayout extends FrameLayout implements
     ViewGroup.OnHierarchyChangeListener, Insettable {
 
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index ce85570..b136e7d 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -34,6 +34,7 @@
 import android.text.TextUtils;
 import android.util.Base64;
 import android.util.Log;
+import android.util.Pair;
 
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
@@ -59,6 +60,16 @@
 import java.util.Set;
 
 public class InstallShortcutReceiver extends BroadcastReceiver {
+
+    public static final int FLAG_ACTIVITY_PAUSED = 1;
+    public static final int FLAG_LOADER_RUNNING = 2;
+    public static final int FLAG_DRAG_AND_DROP = 4;
+    public static final int FLAG_BULK_ADD = 4;
+
+    // Determines whether to defer installing shortcuts immediately until
+    // processAllPendingInstalls() is called.
+    private static int sInstallQueueDisabledFlags = 0;
+
     private static final String TAG = "InstallShortcutReceiver";
     private static final boolean DBG = false;
 
@@ -151,10 +162,6 @@
         }
     }
 
-    // Determines whether to defer installing shortcuts immediately until
-    // processAllPendingInstalls() is called.
-    private static boolean mUseInstallQueue = false;
-
     public void onReceive(Context context, Intent data) {
         if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) {
             return;
@@ -207,7 +214,7 @@
 
     public static ShortcutInfo fromShortcutIntent(Context context, Intent data) {
         PendingInstallShortcutInfo info = createPendingInfo(context, data);
-        return info == null ? null : (ShortcutInfo) info.getItemInfo();
+        return info == null ? null : (ShortcutInfo) info.getItemInfo().first;
     }
 
     public static void queueShortcut(ShortcutInfoCompat info, Context context) {
@@ -245,27 +252,28 @@
 
     private static void queuePendingShortcutInfo(PendingInstallShortcutInfo info, Context context) {
         // Queue the item up for adding if launcher has not loaded properly yet
-        LauncherAppState app = LauncherAppState.getInstance(context);
-        boolean launcherNotLoaded = app.getModel().getCallback() == null;
-
         addToInstallQueue(Utilities.getPrefs(context), info);
-        if (!mUseInstallQueue && !launcherNotLoaded) {
-            flushInstallQueue(context);
-        }
+        flushInstallQueue(context);
     }
 
-    static void enableInstallQueue() {
-        mUseInstallQueue = true;
+    public static void enableInstallQueue(int flag) {
+        sInstallQueueDisabledFlags |= flag;
     }
-    static void disableAndFlushInstallQueue(Context context) {
-        mUseInstallQueue = false;
+    public static void disableAndFlushInstallQueue(int flag, Context context) {
+        sInstallQueueDisabledFlags &= ~flag;
         flushInstallQueue(context);
     }
 
     static void flushInstallQueue(Context context) {
+        LauncherModel model = LauncherAppState.getInstance(context).getModel();
+        boolean launcherNotLoaded = model.getCallback() == null;
+        if (sInstallQueueDisabledFlags != 0 || launcherNotLoaded) {
+            return;
+        }
+
         ArrayList<PendingInstallShortcutInfo> items = getAndClearInstallQueue(context);
         if (!items.isEmpty()) {
-            LauncherAppState.getInstance(context).getModel().addAndBindAddedWorkspaceItems(
+            model.addAndBindAddedWorkspaceItems(
                     new LazyShortcutsProvider(context.getApplicationContext(), items));
         }
     }
@@ -439,7 +447,7 @@
             }
         }
 
-        public ItemInfo getItemInfo() {
+        public Pair<ItemInfo, Object> getItemInfo() {
             if (activityInfo != null) {
                 AppInfo appInfo = new AppInfo(mContext, activityInfo, user);
                 final LauncherAppState app = LauncherAppState.getInstance(mContext);
@@ -459,11 +467,11 @@
                         }
                     });
                 }
-                return si;
+                return Pair.create((ItemInfo) si, (Object) activityInfo);
             } else if (shortcutInfo != null) {
                 ShortcutInfo si = new ShortcutInfo(shortcutInfo, mContext);
                 si.iconBitmap = LauncherIcons.createShortcutIcon(shortcutInfo, mContext);
-                return si;
+                return Pair.create((ItemInfo) si, (Object) shortcutInfo);
             } else if (providerInfo != null) {
                 LauncherAppWidgetProviderInfo info = LauncherAppWidgetProviderInfo
                         .fromProviderInfo(mContext, providerInfo);
@@ -475,9 +483,10 @@
                 widgetInfo.minSpanY = info.minSpanY;
                 widgetInfo.spanX = Math.min(info.spanX, idp.numColumns);
                 widgetInfo.spanY = Math.min(info.spanY, idp.numRows);
-                return widgetInfo;
+                return Pair.create((ItemInfo) widgetInfo, (Object) providerInfo);
             } else {
-                return createShortcutInfo(data, LauncherAppState.getInstance(mContext));
+                ShortcutInfo si = createShortcutInfo(data, LauncherAppState.getInstance(mContext));
+                return Pair.create((ItemInfo) si, null);
             }
         }
 
@@ -588,7 +597,7 @@
         return new PendingInstallShortcutInfo(info, original.mContext);
     }
 
-    private static class LazyShortcutsProvider extends Provider<List<ItemInfo>> {
+    private static class LazyShortcutsProvider extends Provider<List<Pair<ItemInfo, Object>>> {
 
         private final Context mContext;
         private final ArrayList<PendingInstallShortcutInfo> mPendingItems;
@@ -603,9 +612,9 @@
          * packageManager and icon cache.
          */
         @Override
-        public ArrayList<ItemInfo> get() {
+        public ArrayList<Pair<ItemInfo, Object>> get() {
             Preconditions.assertNonUiThread();
-            ArrayList<ItemInfo> installQueue = new ArrayList<>();
+            ArrayList<Pair<ItemInfo, Object>> installQueue = new ArrayList<>();
             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext);
             for (PendingInstallShortcutInfo pendingInfo : mPendingItems) {
                 // If the intent specifies a package, make sure the package exists
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 9e214d1..d224615 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -28,7 +28,6 @@
 import android.view.WindowManager;
 
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.util.Thunk;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -317,7 +316,7 @@
     }
 
     public int getAllAppsButtonRank() {
-        if (ProviderConfig.IS_DOGFOOD_BUILD && FeatureFlags.NO_ALL_APPS_ICON) {
+        if (FeatureFlags.IS_DOGFOOD_BUILD && FeatureFlags.NO_ALL_APPS_ICON) {
             throw new IllegalAccessError("Accessing all apps rank when all-apps is disabled");
         }
         return numHotseatIcons / 2;
diff --git a/src/com/android/launcher3/ItemInfo.java b/src/com/android/launcher3/ItemInfo.java
index 0779a3d..11c5309 100644
--- a/src/com/android/launcher3/ItemInfo.java
+++ b/src/com/android/launcher3/ItemInfo.java
@@ -39,8 +39,10 @@
     /**
      * One of {@link LauncherSettings.Favorites#ITEM_TYPE_APPLICATION},
      * {@link LauncherSettings.Favorites#ITEM_TYPE_SHORTCUT},
-     * {@link LauncherSettings.Favorites#ITEM_TYPE_FOLDER}, or
-     * {@link LauncherSettings.Favorites#ITEM_TYPE_APPWIDGET}.
+     * {@link LauncherSettings.Favorites#ITEM_TYPE_DEEP_SHORTCUT}
+     * {@link LauncherSettings.Favorites#ITEM_TYPE_FOLDER},
+     * {@link LauncherSettings.Favorites#ITEM_TYPE_APPWIDGET} or
+     * {@link LauncherSettings.Favorites#ITEM_TYPE_CUSTOM_APPWIDGET}.
      */
     public int itemType;
 
@@ -53,7 +55,9 @@
     public long container = NO_ID;
 
     /**
-     * Indicates the screen in which the shortcut appears.
+     * Indicates the screen in which the shortcut appears if the container types is
+     * {@link LauncherSettings.Favorites#CONTAINER_DESKTOP}. (i.e., ignore if the container type is
+     * {@link LauncherSettings.Favorites#CONTAINER_HOTSEAT})
      */
     public long screenId = -1;
 
@@ -178,15 +182,12 @@
 
     protected String dumpProperties() {
         return "id=" + id
-                + " type=" + itemType
-                + " container=" + container
+                + " type=" + LauncherSettings.Favorites.itemTypeToString(itemType)
+                + " container=" + LauncherSettings.Favorites.containerToString((int)container)
                 + " screen=" + screenId
-                + " cellX=" + cellX
-                + " cellY=" + cellY
-                + " spanX=" + spanX
-                + " spanY=" + spanY
-                + " minSpanX=" + minSpanX
-                + " minSpanY=" + minSpanY
+                + " cell(" + cellX + "," + cellY + ")"
+                + " span(" + spanX + "," + spanY + ")"
+                + " minSpan(" + minSpanX + "," + minSpanY + ")"
                 + " rank=" + rank
                 + " user=" + user
                 + " title=" + title;
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index ec345a7..dd0d2b8 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -18,7 +18,9 @@
 
 import android.Manifest;
 import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
@@ -65,6 +67,7 @@
 import android.view.KeyEvent;
 import android.view.KeyboardShortcutGroup;
 import android.view.KeyboardShortcutInfo;
+import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MotionEvent;
 import android.view.View;
@@ -81,22 +84,22 @@
 
 import com.android.launcher3.DropTarget.DragObject;
 import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.Workspace.ItemOperator;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.allapps.AllAppsContainerView;
 import com.android.launcher3.allapps.AllAppsTransitionController;
-import com.android.launcher3.allapps.DefaultAppSearchController;
 import com.android.launcher3.anim.AnimationLayerSet;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.PinItemRequestCompat;
+import com.android.launcher3.compat.LauncherAppsCompatVO;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.dragndrop.DragView;
 import com.android.launcher3.dragndrop.PinItemDragListener;
 import com.android.launcher3.dynamicui.ExtractedColors;
+import com.android.launcher3.dynamicui.WallpaperColorInfo;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.keyboard.CustomActionsPopup;
@@ -124,6 +127,7 @@
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.PendingRequestArgs;
 import com.android.launcher3.util.TestingUtils;
+import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.util.ViewOnDrawExecutor;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
@@ -147,7 +151,8 @@
 public class Launcher extends BaseActivity
         implements LauncherExterns, View.OnClickListener, OnLongClickListener,
                    LauncherModel.Callbacks, View.OnTouchListener, LauncherProviderChangeListener,
-                   AccessibilityManager.AccessibilityStateChangeListener {
+                   AccessibilityManager.AccessibilityStateChangeListener,
+                   WallpaperColorInfo.OnThemeChangeListener {
     public static final String TAG = "Launcher";
     static final boolean LOGD = false;
 
@@ -157,14 +162,15 @@
 
     private static final int REQUEST_CREATE_SHORTCUT = 1;
     private static final int REQUEST_CREATE_APPWIDGET = 5;
+
     private static final int REQUEST_PICK_APPWIDGET = 9;
     private static final int REQUEST_PICK_WALLPAPER = 10;
 
     private static final int REQUEST_BIND_APPWIDGET = 11;
-    private static final int REQUEST_BIND_PENDING_APPWIDGET = 14;
-    private static final int REQUEST_RECONFIGURE_APPWIDGET = 12;
+    private static final int REQUEST_BIND_PENDING_APPWIDGET = 12;
+    private static final int REQUEST_RECONFIGURE_APPWIDGET = 13;
 
-    private static final int REQUEST_PERMISSION_CALL_PHONE = 13;
+    private static final int REQUEST_PERMISSION_CALL_PHONE = 14;
 
     private static final float BOUNCE_ANIMATION_TENSION = 1.3f;
 
@@ -213,11 +219,12 @@
     private static int NEW_APPS_ANIMATION_INACTIVE_TIMEOUT_SECONDS = 5;
     @Thunk static int NEW_APPS_ANIMATION_DELAY = 500;
 
+    private final ExtractedColors mExtractedColors = new ExtractedColors();
+
     @Thunk Workspace mWorkspace;
     private View mLauncherView;
     @Thunk DragLayer mDragLayer;
     private DragController mDragController;
-    private View mQsbContainer;
 
     public View mWeightWatcher;
 
@@ -261,12 +268,13 @@
     private LauncherModel mModel;
     private ModelWriter mModelWriter;
     private IconCache mIconCache;
-    private ExtractedColors mExtractedColors;
     private LauncherAccessibilityDelegate mAccessibilityDelegate;
     private Handler mHandler = new Handler();
     private boolean mIsResumeFromActionScreenOff;
     private boolean mHasFocus = false;
 
+    private ObjectAnimator mScrimAnimator;
+
     private PopupDataProvider mPopupDataProvider;
 
     private View.OnTouchListener mHapticFeedbackTouchListener;
@@ -358,6 +366,10 @@
             mLauncherCallbacks.preOnCreate();
         }
 
+        WallpaperColorInfo wallpaperColorInfo = WallpaperColorInfo.getInstance(this);
+        wallpaperColorInfo.setOnThemeChangeListener(this);
+        overrideTheme(wallpaperColorInfo.isDark(), wallpaperColorInfo.supportsDarkText());
+
         super.onCreate(savedInstanceState);
 
         LauncherAppState app = LauncherAppState.getInstance(this);
@@ -392,11 +404,10 @@
         // LauncherModel load.
         mPaused = false;
 
-        mLauncherView = getLayoutInflater().inflate(R.layout.launcher, null);
+        mLauncherView = LayoutInflater.from(this).inflate(R.layout.launcher, null);
 
         setupViews();
         mDeviceProfile.layout(this, false /* notifyListeners */);
-        mExtractedColors = new ExtractedColors();
         loadExtractedColorsAndColorItems();
 
         mPopupDataProvider = new PopupDataProvider(this);
@@ -458,6 +469,23 @@
 
         // Listen for broadcasts screen off
         registerReceiver(mReceiver, new IntentFilter(Intent.ACTION_SCREEN_OFF));
+
+        if (Themes.getAttrBoolean(this, R.attr.isWorkspaceDarkText)) {
+            activateLightSystemBars(true, true, true);
+        }
+    }
+
+    @Override
+    public void onThemeChanged() {
+        recreate();
+    }
+
+    protected void overrideTheme(boolean isDark, boolean supportsDarkText) {
+        if (isDark) {
+            setTheme(R.style.LauncherThemeDark);
+        } else if (supportsDarkText) {
+            setTheme(R.style.LauncherThemeDarkText);
+        }
     }
 
     @Override
@@ -468,6 +496,11 @@
     @Override
     public void onExtractedColorsChanged() {
         loadExtractedColorsAndColorItems();
+        mExtractedColors.notifyChange();
+    }
+
+    public ExtractedColors getExtractedColors() {
+        return mExtractedColors;
     }
 
     @Override
@@ -483,19 +516,9 @@
             mExtractedColors.load(this);
             mHotseat.updateColor(mExtractedColors, !mPaused);
             mWorkspace.getPageIndicator().updateColor(mExtractedColors);
-            boolean lightStatusBar = (FeatureFlags.LIGHT_STATUS_BAR
-                    && mExtractedColors.getColor(ExtractedColors.STATUS_BAR_INDEX,
-                    ExtractedColors.DEFAULT_DARK) == ExtractedColors.DEFAULT_LIGHT);
-            // It's possible that All Apps is visible when this is run,
-            // so always use light status bar in that case. Only change nav bar color to status bar
-            // color when All Apps is visible.
-            activateLightSystemBars(lightStatusBar || isAllAppsVisible(), true, isAllAppsVisible());
         }
     }
 
-    // TODO: use platform flag on API >= 26
-    private static final int SYSTEM_UI_FLAG_LIGHT_NAV_BAR = 0x10;
-
     /**
      * Sets the status and/or nav bar to be light or not. Light status bar means dark icons.
      * @param isLight make sure the system bar is light.
@@ -510,14 +533,14 @@
                 newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
             }
             if (navBar && Utilities.isAtLeastO()) {
-                newSystemUiFlags |= SYSTEM_UI_FLAG_LIGHT_NAV_BAR;
+                newSystemUiFlags |= View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
             }
         } else {
             if (statusBar) {
                 newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
             }
             if (navBar && Utilities.isAtLeastO()) {
-                newSystemUiFlags &= ~(SYSTEM_UI_FLAG_LIGHT_NAV_BAR);
+                newSystemUiFlags &= ~(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
             }
         }
 
@@ -552,47 +575,6 @@
 
     public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {
         mLauncherCallbacks = callbacks;
-        mLauncherCallbacks.setLauncherSearchCallback(new Launcher.LauncherSearchCallbacks() {
-            private boolean mWorkspaceImportanceStored = false;
-            private boolean mHotseatImportanceStored = false;
-            private int mWorkspaceImportanceForAccessibility =
-                    View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
-            private int mHotseatImportanceForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_AUTO;
-
-            @Override
-            public void onSearchOverlayOpened() {
-                if (mWorkspaceImportanceStored || mHotseatImportanceStored) {
-                    return;
-                }
-                // The underlying workspace and hotseat are temporarily suppressed by the search
-                // overlay. So they shouldn't be accessible.
-                if (mWorkspace != null) {
-                    mWorkspaceImportanceForAccessibility =
-                            mWorkspace.getImportantForAccessibility();
-                    mWorkspace.setImportantForAccessibility(
-                            View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
-                    mWorkspaceImportanceStored = true;
-                }
-                if (mHotseat != null) {
-                    mHotseatImportanceForAccessibility = mHotseat.getImportantForAccessibility();
-                    mHotseat.setImportantForAccessibility(
-                            View.IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS);
-                    mHotseatImportanceStored = true;
-                }
-            }
-
-            @Override
-            public void onSearchOverlayClosed() {
-                if (mWorkspaceImportanceStored && mWorkspace != null) {
-                    mWorkspace.setImportantForAccessibility(mWorkspaceImportanceForAccessibility);
-                }
-                if (mHotseatImportanceStored && mHotseat != null) {
-                    mHotseat.setImportantForAccessibility(mHotseatImportanceForAccessibility);
-                }
-                mWorkspaceImportanceStored = false;
-                mHotseatImportanceStored = false;
-            }
-        });
         return true;
     }
 
@@ -954,6 +936,24 @@
         if (!isWorkspaceLoading()) {
             NotificationListener.setNotificationsChangedListener(mPopupDataProvider);
         }
+
+        if (mIsResumeFromActionScreenOff && mDragLayer.getBackground() != null) {
+            if (mScrimAnimator != null) {
+                mScrimAnimator.cancel();
+            }
+            mDragLayer.getBackground().setAlpha(0);
+            mScrimAnimator = ObjectAnimator.ofInt(mDragLayer.getBackground(),
+                    LauncherAnimUtils.DRAWABLE_ALPHA, 0, 255);
+            mScrimAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mScrimAnimator = null;
+                }
+            });
+            mScrimAnimator.setDuration(600);
+            mScrimAnimator.setStartDelay(getWindow().getTransitionBackgroundFadeDuration());
+            mScrimAnimator.start();
+        }
     }
 
     @Override
@@ -1053,13 +1053,12 @@
         updateInteraction(Workspace.State.NORMAL, mWorkspace.getState());
         mWorkspace.onResume();
 
-        if (!isWorkspaceLoading()) {
-            // Process any items that were added while Launcher was away.
-            InstallShortcutReceiver.disableAndFlushInstallQueue(this);
+        // Process any items that were added while Launcher was away.
+        InstallShortcutReceiver.disableAndFlushInstallQueue(
+                InstallShortcutReceiver.FLAG_ACTIVITY_PAUSED, this);
 
-            // Refresh shortcuts if the permission changed.
-            mModel.refreshShortcutsIfRequired();
-        }
+        // Refresh shortcuts if the permission changed.
+        mModel.refreshShortcutsIfRequired();
 
         if (shouldShowDiscoveryBounce()) {
             mAllAppsController.showDiscoveryBounce();
@@ -1074,7 +1073,7 @@
     @Override
     protected void onPause() {
         // Ensure that items added to Launcher are queued until Launcher returns
-        InstallShortcutReceiver.enableInstallQueue();
+        InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_ACTIVITY_PAUSED);
 
         super.onPause();
         mPaused = true;
@@ -1132,18 +1131,6 @@
         public void setOverlayCallbacks(LauncherOverlayCallbacks callbacks);
     }
 
-    public interface LauncherSearchCallbacks {
-        /**
-         * Called when the search overlay is shown.
-         */
-        public void onSearchOverlayOpened();
-
-        /**
-         * Called when the search overlay is dismissed.
-         */
-        public void onSearchOverlayClosed();
-    }
-
     public interface LauncherOverlayCallbacks {
         public void onScrollChanged(float progress);
     }
@@ -1299,9 +1286,7 @@
     private void setupViews() {
         mDragLayer = (DragLayer) findViewById(R.id.drag_layer);
         mFocusHandler = mDragLayer.getFocusIndicatorHelper();
-        mWorkspace = (Workspace) mDragLayer.findViewById(R.id.workspace);
-        mQsbContainer = mDragLayer.findViewById(mDeviceProfile.isVerticalBarLayout()
-                ? R.id.workspace_blocked_row : R.id.qsb_container);
+        mWorkspace = mDragLayer.findViewById(R.id.workspace);
         mWorkspace.initParentViews(mDragLayer);
 
         mLauncherView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
@@ -1336,11 +1321,6 @@
         // Setup Apps and Widgets
         mAppsView = (AllAppsContainerView) findViewById(R.id.apps_view);
         mWidgetsView = (WidgetsContainerView) findViewById(R.id.widgets_view);
-        if (mLauncherCallbacks != null && mLauncherCallbacks.getAllAppsSearchBarController() != null) {
-            mAppsView.setSearchBarController(mLauncherCallbacks.getAllAppsSearchBarController());
-        } else {
-            mAppsView.setSearchBarController(new DefaultAppSearchController());
-        }
 
         // Setup the drag controller (drop targets have to be added in reverse order in priority)
         mDragController.setMoveTarget(mWorkspace);
@@ -1431,8 +1411,8 @@
      * @return A View inflated from layoutResId.
      */
     public View createShortcut(ViewGroup parent, ShortcutInfo info) {
-        BubbleTextView favorite = (BubbleTextView) getLayoutInflater().inflate(R.layout.app_icon,
-                parent, false);
+        BubbleTextView favorite = (BubbleTextView) LayoutInflater.from(parent.getContext())
+                .inflate(R.layout.app_icon, parent, false);
         favorite.applyFromShortcutInfo(info);
         favorite.setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);
         favorite.setOnClickListener(this);
@@ -1441,24 +1421,24 @@
     }
 
     /**
-     * Add a shortcut to the workspace.
+     * Add a shortcut to the workspace or to a Folder.
      *
      * @param data The intent describing the shortcut.
      */
     private void completeAddShortcut(Intent data, long container, long screenId, int cellX,
             int cellY, PendingRequestArgs args) {
-        int[] cellXY = mTmpAddItemCellCoordinates;
-        CellLayout layout = getCellLayout(container, screenId);
-
-        if (args.getRequestCode() != REQUEST_CREATE_SHORTCUT ||
-                args.getPendingIntent().getComponent() == null) {
+        if (args.getRequestCode() != REQUEST_CREATE_SHORTCUT
+                || args.getPendingIntent().getComponent() == null) {
             return;
         }
 
+        int[] cellXY = mTmpAddItemCellCoordinates;
+        CellLayout layout = getCellLayout(container, screenId);
+
         ShortcutInfo info = null;
         if (Utilities.isAtLeastO()) {
-            info = LauncherAppsCompat.createShortcutInfoFromPinItemRequest(
-                    this, PinItemRequestCompat.getPinItemRequest(data), 0);
+            info = LauncherAppsCompatVO.createShortcutInfoFromPinItemRequest(
+                    this, LauncherAppsCompatVO.getPinItemRequest(data), 0);
         }
 
         if (info == null) {
@@ -1477,36 +1457,55 @@
             }
         }
 
-        final View view = createShortcut(info);
-        boolean foundCellSpan = false;
-        // First we check if we already know the exact location where we want to add this item.
-        if (cellX >= 0 && cellY >= 0) {
-            cellXY[0] = cellX;
-            cellXY[1] = cellY;
-            foundCellSpan = true;
+        if (container < 0) {
+            // Adding a shortcut to the Workspace.
+            final View view = createShortcut(info);
+            boolean foundCellSpan = false;
+            // First we check if we already know the exact location where we want to add this item.
+            if (cellX >= 0 && cellY >= 0) {
+                cellXY[0] = cellX;
+                cellXY[1] = cellY;
+                foundCellSpan = true;
 
-            // If appropriate, either create a folder or add to an existing folder
-            if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,
-                    true, null,null)) {
+                // If appropriate, either create a folder or add to an existing folder
+                if (mWorkspace.createUserFolderIfNecessary(view, container, layout, cellXY, 0,
+                        true, null, null)) {
+                    return;
+                }
+                DragObject dragObject = new DragObject();
+                dragObject.dragInfo = info;
+                if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,
+                        true)) {
+                    return;
+                }
+            } else {
+                foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);
+            }
+
+            if (!foundCellSpan) {
+                mWorkspace.onNoCellFound(layout);
                 return;
             }
-            DragObject dragObject = new DragObject();
-            dragObject.dragInfo = info;
-            if (mWorkspace.addToExistingFolderIfNecessary(view, layout, cellXY, 0, dragObject,
-                    true)) {
-                return;
-            }
+
+            getModelWriter().addItemToDatabase(info, container, screenId, cellXY[0], cellXY[1]);
+            mWorkspace.addInScreen(view, info);
         } else {
-            foundCellSpan = layout.findCellForSpan(cellXY, 1, 1);
-        }
+            // Adding a shortcut to a Folder.
+            final long folderIconId = container;
+            FolderIcon folderIcon = (FolderIcon) mWorkspace.getFirstMatch(new ItemOperator() {
+                @Override
+                public boolean evaluate(ItemInfo info, View view) {
+                    return info != null && info.id == folderIconId;
+                }
+            });
 
-        if (!foundCellSpan) {
-            mWorkspace.onNoCellFound(layout);
-            return;
+            if (folderIcon != null) {
+                FolderInfo folderInfo = (FolderInfo) folderIcon.getTag();
+                folderInfo.add(info, args.rank, false);
+            } else {
+                Log.e(TAG, "Could not find folder with id " + folderIconId + " to add shortcut.");
+            }
         }
-
-        getModelWriter().addItemToDatabase(info, container, screenId, cellXY[0], cellXY[1]);
-        mWorkspace.addInScreen(view, info);
     }
 
     /**
@@ -1664,10 +1663,6 @@
         return mWorkspace;
     }
 
-    public View getQsbContainer() {
-        return mQsbContainer;
-    }
-
     public Hotseat getHotseat() {
         return mHotseat;
     }
@@ -1759,7 +1754,7 @@
 
             // Reset the apps view
             if (!alreadyOnHome && mAppsView != null) {
-                mAppsView.scrollToTop();
+                mAppsView.reset();
             }
 
             // Reset the widgets view
@@ -1871,6 +1866,8 @@
         ((AccessibilityManager) getSystemService(ACCESSIBILITY_SERVICE))
                 .removeAccessibilityStateChangeListener(this);
 
+        WallpaperColorInfo.getInstance(this).setOnThemeChangeListener(null);
+
         LauncherAnimUtils.onDestroyActivity();
 
         if (mLauncherCallbacks != null) {
@@ -2462,7 +2459,13 @@
 
     private void startAppShortcutOrInfoActivity(View v) {
         ItemInfo item = (ItemInfo) v.getTag();
-        Intent intent = item.getIntent();
+        Intent intent;
+        if (item instanceof PromiseAppInfo) {
+            PromiseAppInfo promiseAppInfo = (PromiseAppInfo) item;
+            intent = promiseAppInfo.getMarketIntent();
+        } else {
+            intent = item.getIntent();
+        }
         if (intent == null) {
             throw new IllegalArgumentException("Input must have a valid intent");
         }
@@ -2523,8 +2526,8 @@
                 .putExtra(Utilities.EXTRA_WALLPAPER_OFFSET, offset);
 
         String pickerPackage = getString(R.string.wallpaper_picker_package);
-        boolean hasTargetPackage = TextUtils.isEmpty(pickerPackage);
-        if (!hasTargetPackage) {
+        boolean hasTargetPackage = !TextUtils.isEmpty(pickerPackage);
+        if (hasTargetPackage) {
             intent.setPackage(pickerPackage);
         }
 
@@ -3390,7 +3393,7 @@
                     Object tag = v.getTag();
                     String desc = "Collision while binding workspace item: " + item
                             + ". Collides with " + tag;
-                    if (ProviderConfig.IS_DOGFOOD_BUILD) {
+                    if (FeatureFlags.IS_DOGFOOD_BUILD) {
                         throw (new RuntimeException(desc));
                     } else {
                         Log.d(TAG, desc);
@@ -3593,6 +3596,9 @@
 
         LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) view.getTag();
         info.restoreStatus = finalRestoreFlag;
+        if (info.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
+            info.pendingItemInfo = null;
+        }
 
         mWorkspace.reinflateWidgetsIfNecessary();
         getModelWriter().updateItemInDatabase(info);
@@ -3671,7 +3677,8 @@
             mPendingActivityResult = null;
         }
 
-        InstallShortcutReceiver.disableAndFlushInstallQueue(this);
+        InstallShortcutReceiver.disableAndFlushInstallQueue(
+                InstallShortcutReceiver.FLAG_LOADER_RUNNING, this);
 
         NotificationListener.setNotificationsChangedListener(mPopupDataProvider);
 
@@ -3768,6 +3775,22 @@
     }
 
     @Override
+    public void bindPromiseAppProgressUpdated(final PromiseAppInfo app) {
+        Runnable r = new Runnable() {
+            public void run() {
+                bindPromiseAppProgressUpdated(app);
+            }
+        };
+        if (waitUntilResume(r)) {
+            return;
+        }
+
+        if (mAppsView != null) {
+            mAppsView.updatePromiseAppProgress(app);
+        }
+    }
+
+    @Override
     public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {
         Runnable r = new Runnable() {
             public void run() {
@@ -3940,7 +3963,7 @@
      *                    refreshes the widgets and shortcuts associated with the given package/user
      */
     public void refreshAndBindWidgetsForPackageUser(@Nullable PackageUserKey packageUser) {
-        mModel.refreshAndBindWidgetsAndShortcuts(this, mWidgetsView.isEmpty(), packageUser);
+        mModel.refreshAndBindWidgetsAndShortcuts(packageUser);
     }
 
     public void lockScreenOrientation() {
@@ -4119,9 +4142,8 @@
         public void onSharedPreferenceChanged(
                 SharedPreferences sharedPreferences, String key) {
             if (Utilities.ALLOW_ROTATION_PREFERENCE_KEY.equals(key)) {
-                // Finish this instance of the activity. When the activity is recreated,
-                // it will initialize the rotation preference again.
-                finish();
+                // Recreate the activity so that it initializes the rotation preference again.
+                recreate();
             }
         }
     }
diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java
index aa7f5ee..cfb9b57 100644
--- a/src/com/android/launcher3/LauncherAnimUtils.java
+++ b/src/com/android/launcher3/LauncherAnimUtils.java
@@ -21,11 +21,10 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.ValueAnimator;
+import android.graphics.drawable.Drawable;
 import android.util.Property;
 import android.view.View;
-import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
-import android.widget.ViewAnimator;
 
 import java.util.HashSet;
 import java.util.WeakHashMap;
@@ -130,4 +129,16 @@
         return anim;
     }
 
+    public static final Property<Drawable, Integer> DRAWABLE_ALPHA =
+            new Property<Drawable, Integer>(Integer.TYPE, "drawableAlpha") {
+                @Override
+                public Integer get(Drawable drawable) {
+                    return drawable.getAlpha();
+                }
+
+                @Override
+                public void set(Drawable drawable, Integer alpha) {
+                    drawable.setAlpha(alpha);
+                }
+            };
 }
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 180c202..cf20feb 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -26,7 +26,7 @@
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dynamicui.ExtractionUtils;
 import com.android.launcher3.util.ConfigMonitor;
 import com.android.launcher3.util.Preconditions;
@@ -37,7 +37,7 @@
 
 public class LauncherAppState {
 
-    public static final boolean PROFILE_STARTUP = ProviderConfig.IS_DOGFOOD_BUILD;
+    public static final boolean PROFILE_STARTUP = FeatureFlags.IS_DOGFOOD_BUILD;
 
     // We do not need any synchronization for this variable as its only written on UI thread.
     private static LauncherAppState INSTANCE;
@@ -93,9 +93,7 @@
         mInvariantDeviceProfile = new InvariantDeviceProfile(mContext);
         mIconCache = new IconCache(mContext, mInvariantDeviceProfile);
         mWidgetCache = new WidgetPreviewLoader(mContext, mIconCache);
-
-        mModel = new LauncherModel(this, mIconCache,
-                Utilities.getOverrideObject(AppFilter.class, mContext, R.string.app_filter_class));
+        mModel = new LauncherModel(this, mIconCache, AppFilter.newInstance(mContext));
 
         LauncherAppsCompat.getInstance(mContext).addOnAppsChangedCallback(mModel);
 
diff --git a/src/com/android/launcher3/LauncherAppWidgetHostView.java b/src/com/android/launcher3/LauncherAppWidgetHostView.java
index 13cc7ba..c7b7782 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHostView.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHostView.java
@@ -23,7 +23,6 @@
 import android.graphics.Rect;
 import android.os.Handler;
 import android.os.SystemClock;
-import android.util.Log;
 import android.util.SparseBooleanArray;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -40,9 +39,7 @@
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.dragndrop.DragLayer.TouchCompleteListener;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
-import java.util.concurrent.Executor;
 
 /**
  * {@inheritDoc}
@@ -50,8 +47,6 @@
 public class LauncherAppWidgetHostView extends AppWidgetHostView
         implements TouchCompleteListener, View.OnLongClickListener {
 
-    private static final String TAG = "LauncherWidgetHostView";
-
     // Related to the auto-advancing of widgets
     private static final long ADVANCE_INTERVAL = 20000;
     private static final long ADVANCE_STAGGER = 250;
@@ -98,13 +93,7 @@
         setBackgroundResource(R.drawable.widget_internal_focus_bg);
 
         if (Utilities.isAtLeastO()) {
-            try {
-                Method asyncMethod = AppWidgetHostView.class
-                        .getMethod("setExecutor", Executor.class);
-                asyncMethod.invoke(this, Utilities.THREAD_POOL_EXECUTOR);
-            } catch (Exception e) {
-                Log.e(TAG, "Unable to set async executor", e);
-            }
+            setExecutor(Utilities.THREAD_POOL_EXECUTOR);
         }
     }
 
diff --git a/src/com/android/launcher3/LauncherAppWidgetInfo.java b/src/com/android/launcher3/LauncherAppWidgetInfo.java
index 1e0f285..6f23e56 100644
--- a/src/com/android/launcher3/LauncherAppWidgetInfo.java
+++ b/src/com/android/launcher3/LauncherAppWidgetInfo.java
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.os.Process;
 
+import com.android.launcher3.model.PackageItemInfo;
 import com.android.launcher3.util.ContentWriter;
 
 /**
@@ -95,6 +96,11 @@
      */
     public Intent bindOptions;
 
+    /**
+     * Nonnull for pending widgets. We use this to get the icon and title for the widget.
+     */
+    public PackageItemInfo pendingItemInfo;
+
     private boolean mHasNotifiedInitialWidgetSizeChanged;
 
     public LauncherAppWidgetInfo(int appWidgetId, ComponentName providerName) {
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
index 2bac11f..d66b14c 100644
--- a/src/com/android/launcher3/LauncherCallbacks.java
+++ b/src/com/android/launcher3/LauncherCallbacks.java
@@ -17,13 +17,10 @@
 package com.android.launcher3;
 
 import android.content.Intent;
-import android.graphics.Rect;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.View;
 
-import com.android.launcher3.allapps.AllAppsSearchBarController;
-import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.launcher3.util.ComponentKey;
 
 import java.io.FileDescriptor;
@@ -44,69 +41,60 @@
      * Activity life-cycle methods. These methods are triggered after
      * the code in the corresponding Launcher method is executed.
      */
-    public void preOnCreate();
-    public void onCreate(Bundle savedInstanceState);
-    public void preOnResume();
-    public void onResume();
-    public void onStart();
-    public void onStop();
-    public void onPause();
-    public void onDestroy();
-    public void onSaveInstanceState(Bundle outState);
-    public void onPostCreate(Bundle savedInstanceState);
-    public void onNewIntent(Intent intent);
-    public void onActivityResult(int requestCode, int resultCode, Intent data);
-    public void onRequestPermissionsResult(int requestCode, String[] permissions,
+    void preOnCreate();
+    void onCreate(Bundle savedInstanceState);
+    void preOnResume();
+    void onResume();
+    void onStart();
+    void onStop();
+    void onPause();
+    void onDestroy();
+    void onSaveInstanceState(Bundle outState);
+    void onPostCreate(Bundle savedInstanceState);
+    void onNewIntent(Intent intent);
+    void onActivityResult(int requestCode, int resultCode, Intent data);
+    void onRequestPermissionsResult(int requestCode, String[] permissions,
             int[] grantResults);
-    public void onWindowFocusChanged(boolean hasFocus);
-    public void onAttachedToWindow();
-    public void onDetachedFromWindow();
-    public boolean onPrepareOptionsMenu(Menu menu);
-    public void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args);
-    public void onHomeIntent();
-    public boolean handleBackPressed();
-    public void onTrimMemory(int level);
+    void onWindowFocusChanged(boolean hasFocus);
+    void onAttachedToWindow();
+    void onDetachedFromWindow();
+    boolean onPrepareOptionsMenu(Menu menu);
+    void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args);
+    void onHomeIntent();
+    boolean handleBackPressed();
+    void onTrimMemory(int level);
 
     /*
      * Extension points for providing custom behavior on certain user interactions.
      */
-    public void onLauncherProviderChange();
-    public void finishBindingItems(final boolean upgradePath);
-    public void bindAllApplications(ArrayList<AppInfo> apps);
-    public void onInteractionBegin();
-    public void onInteractionEnd();
+    void onLauncherProviderChange();
+    void finishBindingItems(final boolean upgradePath);
+    void bindAllApplications(ArrayList<AppInfo> apps);
+    void onInteractionBegin();
+    void onInteractionEnd();
 
     @Deprecated
-    public void onWorkspaceLockedChanged();
+    void onWorkspaceLockedChanged();
 
     /**
      * Starts a search with {@param initialQuery}. Return false if search was not started.
      */
-    public boolean startSearch(
+    boolean startSearch(
             String initialQuery, boolean selectInitialQuery, Bundle appSearchData);
-    public boolean hasCustomContentToLeft();
-    public void populateCustomContentContainer();
-    public View getQsbBar();
-    public Bundle getAdditionalSearchWidgetOptions();
+    boolean hasCustomContentToLeft();
+    void populateCustomContentContainer();
+    View getQsbBar();
+    Bundle getAdditionalSearchWidgetOptions();
 
     /*
      * Extensions points for adding / replacing some other aspects of the Launcher experience.
      */
-    public boolean shouldMoveToDefaultScreenOnHomeIntent();
-    public boolean hasSettings();
-    public AllAppsSearchBarController getAllAppsSearchBarController();
-    public List<ComponentKey> getPredictedApps();
-    public static final int SEARCH_BAR_HEIGHT_NORMAL = 0, SEARCH_BAR_HEIGHT_TALL = 1;
+    boolean shouldMoveToDefaultScreenOnHomeIntent();
+    boolean hasSettings();
+    List<ComponentKey> getPredictedApps();
+    int SEARCH_BAR_HEIGHT_NORMAL = 0, SEARCH_BAR_HEIGHT_TALL = 1;
     /** Must return one of {@link #SEARCH_BAR_HEIGHT_NORMAL} or {@link #SEARCH_BAR_HEIGHT_TALL} */
-    public int getSearchBarHeight();
+    int getSearchBarHeight();
 
-    /**
-     * Sets the callbacks to allow reacting the actions of search overlays of the launcher.
-     *
-     * @param callbacks A set of callbacks to the Launcher, is actually a LauncherSearchCallback,
-     *                  but for implementation purposes is passed around as an object.
-     */
-    public void setLauncherSearchCallback(Object callbacks);
-
-    public boolean shouldShowDiscoveryBounce();
+    boolean shouldShowDiscoveryBounce();
 }
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index f881b38..48c5c56 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3;
 
-import android.appwidget.AppWidgetProviderInfo;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.ContentProviderOperation;
@@ -24,57 +23,40 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.LauncherActivityInfo;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Process;
-import android.os.SystemClock;
-import android.os.Trace;
 import android.os.UserHandle;
 import android.support.annotation.Nullable;
 import android.text.TextUtils;
 import android.util.Log;
-import android.util.LongSparseArray;
-import android.util.MutableInt;
+import android.util.Pair;
 
-import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
 import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.dynamicui.ExtractionUtils;
-import com.android.launcher3.folder.Folder;
-import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.graphics.LauncherIcons;
-import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.AddWorkspaceItemsTask;
 import com.android.launcher3.model.BgDataModel;
 import com.android.launcher3.model.CacheDataUpdatedTask;
 import com.android.launcher3.model.ExtendedModelTask;
-import com.android.launcher3.model.GridSizeMigrationTask;
-import com.android.launcher3.model.LoaderCursor;
+import com.android.launcher3.model.LoaderResults;
+import com.android.launcher3.model.LoaderTask;
 import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.model.PackageInstallStateChangedTask;
 import com.android.launcher3.model.PackageItemInfo;
 import com.android.launcher3.model.PackageUpdatedTask;
-import com.android.launcher3.model.SdCardAvailableReceiver;
 import com.android.launcher3.model.ShortcutsChangedTask;
 import com.android.launcher3.model.UserLockStateChangedTask;
 import com.android.launcher3.model.WidgetItem;
-import com.android.launcher3.model.WidgetsModel;
-import com.android.launcher3.provider.ImportDataTask;
 import com.android.launcher3.provider.LauncherDbUtils;
 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.ManagedProfileHeuristic;
 import com.android.launcher3.util.MultiHashMap;
-import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Provider;
@@ -85,14 +67,9 @@
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.Executor;
 
@@ -103,20 +80,17 @@
  */
 public class LauncherModel extends BroadcastReceiver
         implements LauncherAppsCompat.OnAppsChangedCallbackCompat {
-    static final boolean DEBUG_LOADERS = false;
+    static final boolean DEBUG_TASKS = false;
     private static final boolean DEBUG_RECEIVER = false;
 
     static final String TAG = "Launcher.Model";
 
-    private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons
-    private static final long INVALID_SCREEN_ID = -1L;
-
+    private final MainThreadExecutor mUiExecutor = new MainThreadExecutor();
     @Thunk final LauncherAppState mApp;
     @Thunk final Object mLock = new Object();
-    @Thunk DeferredHandler mHandler = new DeferredHandler();
-    @Thunk LoaderTask mLoaderTask;
+    @Thunk
+    LoaderTask mLoaderTask;
     @Thunk boolean mIsLoaderTaskRunning;
-    @Thunk boolean mHasLoaderCompletedOnce;
 
     @Thunk static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
     static {
@@ -135,33 +109,10 @@
         }
     }
 
-    /**
-     * Set of runnables to be called on the background thread after the workspace binding
-     * is complete.
-     */
-    static final ArrayList<Runnable> mBindCompleteRunnables = new ArrayList<Runnable>();
-
     @Thunk WeakReference<Callbacks> mCallbacks;
 
     // < only access in worker thread >
     private final AllAppsList mBgAllAppsList;
-    // Entire list of widgets.
-    private final WidgetsModel mBgWidgetsModel;
-
-    private boolean mHasShortcutHostPermission;
-    // Runnable to check if the shortcuts permission has changed.
-    private final Runnable mShortcutPermissionCheckRunnable = new Runnable() {
-        @Override
-        public void run() {
-            if (mModelLoaded) {
-                boolean hasShortcutHostPermission =
-                        DeepShortcutManager.getInstance(mApp.getContext()).hasHostPermission();
-                if (hasShortcutHostPermission != mHasShortcutHostPermission) {
-                    forceReload();
-                }
-            }
-        }
-    };
 
     /**
      * All the static data should be accessed on the background thread, A lock should be acquired
@@ -169,12 +120,19 @@
      */
     static final BgDataModel sBgDataModel = new BgDataModel();
 
-    // </ only access in worker thread >
-
-    private final IconCache mIconCache;
-
-    private final LauncherAppsCompat mLauncherApps;
-    private final UserManagerCompat mUserManager;
+    // Runnable to check if the shortcuts permission has changed.
+    private final Runnable mShortcutPermissionCheckRunnable = new Runnable() {
+        @Override
+        public void run() {
+            if (mModelLoaded) {
+                boolean hasShortcutHostPermission =
+                        DeepShortcutManager.getInstance(mApp.getContext()).hasHostPermission();
+                if (hasShortcutHostPermission != sBgDataModel.hasShortcutHostPermission) {
+                    forceReload();
+                }
+            }
+        }
+    };
 
     public interface Callbacks {
         public boolean setLoadOnResume();
@@ -193,6 +151,7 @@
                                   ArrayList<ItemInfo> addAnimated,
                                   ArrayList<AppInfo> addedApps);
         public void bindAppsUpdated(ArrayList<AppInfo> apps);
+        public void bindPromiseAppProgressUpdated(PromiseAppInfo app);
         public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated,
                 ArrayList<ShortcutInfo> removed, UserHandle user);
         public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
@@ -209,25 +168,8 @@
     }
 
     LauncherModel(LauncherAppState app, IconCache iconCache, AppFilter appFilter) {
-        Context context = app.getContext();
         mApp = app;
         mBgAllAppsList = new AllAppsList(iconCache, appFilter);
-        mBgWidgetsModel = new WidgetsModel(iconCache, appFilter);
-        mIconCache = iconCache;
-
-        mLauncherApps = LauncherAppsCompat.getInstance(context);
-        mUserManager = UserManagerCompat.getInstance(context);
-    }
-
-    /** Runs the specified runnable immediately if called from the main thread, otherwise it is
-     * posted on the main thread handler. */
-    private void runOnMainThread(Runnable r) {
-        if (sWorkerThread.getThreadId() == Process.myTid()) {
-            // If we are on the worker thread, post onto the main handler
-            mHandler.post(r);
-        } else {
-            r.run();
-        }
     }
 
     /** Runs the specified runnable immediately if called from the worker thread, otherwise it is
@@ -258,15 +200,8 @@
     /**
      * Adds the provided items to the workspace.
      */
-    public void addAndBindAddedWorkspaceItems(List<ItemInfo> workspaceApps) {
-        addAndBindAddedWorkspaceItems(Provider.of(workspaceApps));
-    }
-
-    /**
-     * Adds the provided items to the workspace.
-     */
     public void addAndBindAddedWorkspaceItems(
-            Provider<List<ItemInfo>> appsProvider) {
+            Provider<List<Pair<ItemInfo, Object>>> appsProvider) {
         enqueueModelUpdateTask(new AddWorkspaceItemsTask(appsProvider));
     }
 
@@ -379,8 +314,6 @@
     public void initialize(Callbacks callbacks) {
         synchronized (mLock) {
             Preconditions.assertUIThread();
-            // Remove any queued UI runnables
-            mHandler.cancelAll();
             mCallbacks = new WeakReference<>(callbacks);
         }
     }
@@ -538,27 +471,36 @@
      */
     public boolean startLoader(int synchronousBindPage) {
         // Enable queue before starting loader. It will get disabled in Launcher#finishBindingItems
-        InstallShortcutReceiver.enableInstallQueue();
+        InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_LOADER_RUNNING);
         synchronized (mLock) {
             // Don't bother to start the thread if we know it's not going to do anything
             if (mCallbacks != null && mCallbacks.get() != null) {
                 final Callbacks oldCallbacks = mCallbacks.get();
                 // Clear any pending bind-runnables from the synchronized load process.
-                runOnMainThread(new Runnable() {
-                    public void run() {
-                        oldCallbacks.clearPendingBinds();
-                    }
-                });
+                mUiExecutor.execute(new Runnable() {
+                            public void run() {
+                                oldCallbacks.clearPendingBinds();
+                            }
+                        });
 
                 // If there is already one running, tell it to stop.
                 stopLoaderLocked();
-                mLoaderTask = new LoaderTask(mApp.getContext(), synchronousBindPage);
+                LoaderResults loaderResults = new LoaderResults(mApp, sBgDataModel,
+                        mBgAllAppsList, synchronousBindPage, mCallbacks);
                 if (synchronousBindPage != PagedView.INVALID_RESTORE_PAGE
                         && mModelLoaded && !mIsLoaderTaskRunning) {
-                    mLoaderTask.runBindSynchronousPage(synchronousBindPage);
+
+                    // Divide the set of loaded items into those that we are binding synchronously,
+                    // and everything else that is to be bound normally (asynchronously).
+                    loaderResults.bindWorkspace();
+                    // For now, continue posting the binding of AllApps as there are other
+                    // issues that arise from that.
+                    loaderResults.bindAllApps();
+                    loaderResults.bindDeepShortcuts();
+                    loaderResults.bindWidgets();
                     return true;
                 } else {
-                    sWorkerThread.setPriority(Thread.NORM_PRIORITY);
+                    mLoaderTask = new LoaderTask(mApp, mBgAllAppsList, sBgDataModel, loaderResults);
                     sWorker.post(mLoaderTask);
                 }
             }
@@ -586,1211 +528,61 @@
                 screensUri, null, null, null, LauncherSettings.WorkspaceScreens.SCREEN_RANK));
     }
 
-    /**
-     * Runnable for the thread that loads the contents of the launcher:
-     *   - workspace icons
-     *   - widgets
-     *   - all apps icons
-     *   - deep shortcuts within apps
-     */
-    private class LoaderTask implements Runnable {
-        private Context mContext;
-        private int mPageToBindFirst;
-
-        @Thunk boolean mIsLoadingAndBindingWorkspace;
-        private boolean mStopped;
-        @Thunk boolean mLoadAndBindStepFinished;
-
-        LoaderTask(Context context, int pageToBindFirst) {
-            mContext = context;
-            mPageToBindFirst = pageToBindFirst;
-        }
-
-        private void waitForIdle() {
-            // Wait until the either we're stopped or the other threads are done.
-            // This way we don't start loading all apps until the workspace has settled
-            // down.
-            synchronized (LoaderTask.this) {
-                final long workspaceWaitTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
-
-                mHandler.postIdle(new Runnable() {
-                        public void run() {
-                            synchronized (LoaderTask.this) {
-                                mLoadAndBindStepFinished = true;
-                                if (DEBUG_LOADERS) {
-                                    Log.d(TAG, "done with previous binding step");
-                                }
-                                LoaderTask.this.notify();
-                            }
+    public void onInstallSessionCreated(final PackageInstallInfo sessionInfo) {
+        enqueueModelUpdateTask(new ExtendedModelTask() {
+            @Override
+            public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
+                apps.addPromiseApp(app.getContext(), sessionInfo);
+                if (!apps.added.isEmpty()) {
+                    final ArrayList<AppInfo> arrayList = new ArrayList<>(apps.added);
+                    apps.added.clear();
+                    scheduleCallbackTask(new CallbackTask() {
+                        @Override
+                        public void execute(Callbacks callbacks) {
+                            callbacks.bindAppsAdded(null, null, null, arrayList);
                         }
                     });
-
-                while (!mStopped && !mLoadAndBindStepFinished) {
-                    try {
-                        // Just in case mFlushingWorkerThread changes but we aren't woken up,
-                        // wait no longer than 1sec at a time
-                        this.wait(1000);
-                    } catch (InterruptedException ex) {
-                        // Ignore
-                    }
-                }
-                if (DEBUG_LOADERS) {
-                    Log.d(TAG, "waited "
-                            + (SystemClock.uptimeMillis()-workspaceWaitTime)
-                            + "ms for previous step to finish binding");
                 }
             }
-        }
+        });
+    }
 
-        void runBindSynchronousPage(int synchronousBindPage) {
-            if (synchronousBindPage == PagedView.INVALID_RESTORE_PAGE) {
-                // Ensure that we have a valid page index to load synchronously
-                throw new RuntimeException("Should not call runBindSynchronousPage() without " +
-                        "valid page index");
-            }
-            if (!mModelLoaded) {
-                // Ensure that we don't try and bind a specified page when the pages have not been
-                // loaded already (we should load everything asynchronously in that case)
-                throw new RuntimeException("Expecting AllApps and Workspace to be loaded");
-            }
+    public class LoaderTransaction implements AutoCloseable {
+
+        private final LoaderTask mTask;
+
+        private LoaderTransaction(LoaderTask task) throws CancellationException {
             synchronized (mLock) {
-                if (mIsLoaderTaskRunning) {
-                    // Ensure that we are never running the background loading at this point since
-                    // we also touch the background collections
-                    throw new RuntimeException("Error! Background loading is already running");
+                if (mLoaderTask != task) {
+                    throw new CancellationException("Loader already stopped");
                 }
-            }
-
-            // XXX: Throw an exception if we are already loading (since we touch the worker thread
-            //      data structures, we can't allow any other thread to touch that data, but because
-            //      this call is synchronous, we can get away with not locking).
-
-            // The LauncherModel is static in the LauncherAppState and mHandler may have queued
-            // operations from the previous activity.  We need to ensure that all queued operations
-            // are executed before any synchronous binding work is done.
-            mHandler.flush();
-
-            // Divide the set of loaded items into those that we are binding synchronously, and
-            // everything else that is to be bound normally (asynchronously).
-            bindWorkspace(synchronousBindPage);
-            // XXX: For now, continue posting the binding of AllApps as there are other issues that
-            //      arise from that.
-            onlyBindAllApps();
-
-            bindDeepShortcuts();
-        }
-
-        private void verifyNotStopped() throws CancellationException {
-            synchronized (LoaderTask.this) {
-                if (mStopped) {
-                    throw new CancellationException("Loader stopped");
-                }
-            }
-        }
-
-        public void run() {
-            synchronized (mLock) {
-                if (mStopped) {
-                    return;
-                }
+                mTask = task;
                 mIsLoaderTaskRunning = true;
-            }
-
-            try {
-                if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");
-                // Set to false in bindWorkspace()
-                mIsLoadingAndBindingWorkspace = true;
-                loadWorkspace();
-
-                verifyNotStopped();
-                if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace");
-                bindWorkspace(mPageToBindFirst);
-
-                // Take a break
-                if (DEBUG_LOADERS) Log.d(TAG, "step 1 completed, wait for idle");
-                waitForIdle();
-                verifyNotStopped();
-
-                // second step
-                if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps");
-                loadAllApps();
-
-                verifyNotStopped();
-                if (DEBUG_LOADERS) Log.d(TAG, "step 2.2: Update icon cache");
-                updateIconCache();
-
-                // Take a break
-                if (DEBUG_LOADERS) Log.d(TAG, "step 2 completed, wait for idle");
-                waitForIdle();
-                verifyNotStopped();
-
-                // third step
-                if (DEBUG_LOADERS) Log.d(TAG, "step 3.1: loading deep shortcuts");
-                loadDeepShortcuts();
-
-                verifyNotStopped();
-                if (DEBUG_LOADERS) Log.d(TAG, "step 3.2: bind deep shortcuts");
-                bindDeepShortcuts();
-
-                // Take a break
-                if (DEBUG_LOADERS) Log.d(TAG, "step 3 completed, wait for idle");
-                waitForIdle();
-                verifyNotStopped();
-
-                // fourth step
-                if (DEBUG_LOADERS) Log.d(TAG, "step 4.1: loading widgets");
-                refreshAndBindWidgetsAndShortcuts(getCallback(), false /* bindFirst */,
-                        null /* packageUser */);
-
-                synchronized (mLock) {
-                    // Everything loaded bind the data.
-                    mModelLoaded = true;
-                    mHasLoaderCompletedOnce = true;
-                }
-            } catch (CancellationException e) {
-              // Loader stopped, ignore
-            } finally {
-                // Clear out this reference, otherwise we end up holding it until all of the
-                // callback runnables are done.
-                mContext = null;
-
-                synchronized (mLock) {
-                    // If we are still the last one to be scheduled, remove ourselves.
-                    if (mLoaderTask == this) {
-                        mLoaderTask = null;
-                    }
-                    mIsLoaderTaskRunning = false;
-                }
+                mModelLoaded = false;
             }
         }
 
-        public void stopLocked() {
-            synchronized (LoaderTask.this) {
-                mStopped = true;
-                this.notify();
-            }
-        }
-
-        /**
-         * Gets the callbacks object.  If we've been stopped, or if the launcher object
-         * has somehow been garbage collected, return null instead.  Pass in the Callbacks
-         * object that was around when the deferred message was scheduled, and if there's
-         * a new Callbacks object around then also return null.  This will save us from
-         * calling onto it with data that will be ignored.
-         */
-        Callbacks tryGetCallbacks(Callbacks oldCallbacks) {
+        public void commit() {
             synchronized (mLock) {
-                if (mStopped) {
-                    return null;
-                }
-
-                if (mCallbacks == null) {
-                    return null;
-                }
-
-                final Callbacks callbacks = mCallbacks.get();
-                if (callbacks != oldCallbacks) {
-                    return null;
-                }
-                if (callbacks == null) {
-                    Log.w(TAG, "no mCallbacks");
-                    return null;
-                }
-
-                return callbacks;
+                // Everything loaded bind the data.
+                mModelLoaded = true;
             }
         }
 
-        private void loadWorkspace() {
-            if (LauncherAppState.PROFILE_STARTUP) {
-                Trace.beginSection("Loading Workspace");
-            }
-
-            final Context context = mContext;
-            final ContentResolver contentResolver = context.getContentResolver();
-            final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
-            final boolean isSafeMode = pmHelper.isSafeMode();
-            final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
-            final DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(context);
-            final boolean isSdCardReady = Utilities.isBootCompleted();
-            final MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>();
-
-            boolean clearDb = false;
-            try {
-                ImportDataTask.performImportIfPossible(context);
-            } catch (Exception e) {
-                // Migration failed. Clear workspace.
-                clearDb = true;
-            }
-
-            if (!clearDb && GridSizeMigrationTask.ENABLED &&
-                    !GridSizeMigrationTask.migrateGridIfNeeded(mContext)) {
-                // Migration failed. Clear workspace.
-                clearDb = true;
-            }
-
-            if (clearDb) {
-                Log.d(TAG, "loadWorkspace: resetting launcher database");
-                LauncherSettings.Settings.call(contentResolver,
-                        LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
-            }
-
-            Log.d(TAG, "loadWorkspace: loading default favorites");
-            LauncherSettings.Settings.call(contentResolver,
-                    LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES);
-
-            synchronized (sBgDataModel) {
-                sBgDataModel.clear();
-
-                final HashMap<String, Integer> installingPkgs = PackageInstallerCompat
-                        .getInstance(mContext).updateAndGetActiveSessionCache();
-                sBgDataModel.workspaceScreens.addAll(loadWorkspaceScreensDb(mContext));
-
-                Map<ShortcutKey, ShortcutInfoCompat> shortcutKeyToPinnedShortcuts = new HashMap<>();
-                final LoaderCursor c = new LoaderCursor(contentResolver.query(
-                        LauncherSettings.Favorites.CONTENT_URI, null, null, null, null), mApp);
-
-                HashMap<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null;
-
-                try {
-                    final int appWidgetIdIndex = c.getColumnIndexOrThrow(
-                            LauncherSettings.Favorites.APPWIDGET_ID);
-                    final int appWidgetProviderIndex = c.getColumnIndexOrThrow(
-                            LauncherSettings.Favorites.APPWIDGET_PROVIDER);
-                    final int spanXIndex = c.getColumnIndexOrThrow
-                            (LauncherSettings.Favorites.SPANX);
-                    final int spanYIndex = c.getColumnIndexOrThrow(
-                            LauncherSettings.Favorites.SPANY);
-                    final int rankIndex = c.getColumnIndexOrThrow(
-                            LauncherSettings.Favorites.RANK);
-                    final int optionsIndex = c.getColumnIndexOrThrow(
-                            LauncherSettings.Favorites.OPTIONS);
-
-                    final LongSparseArray<UserHandle> allUsers = c.allUsers;
-                    final LongSparseArray<Boolean> quietMode = new LongSparseArray<>();
-                    final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>();
-                    for (UserHandle user : mUserManager.getUserProfiles()) {
-                        long serialNo = mUserManager.getSerialNumberForUser(user);
-                        allUsers.put(serialNo, user);
-                        quietMode.put(serialNo, mUserManager.isQuietModeEnabled(user));
-
-                        boolean userUnlocked = mUserManager.isUserUnlocked(user);
-
-                        // We can only query for shortcuts when the user is unlocked.
-                        if (userUnlocked) {
-                            List<ShortcutInfoCompat> pinnedShortcuts =
-                                    shortcutManager.queryForPinnedShortcuts(null, user);
-                            if (shortcutManager.wasLastCallSuccess()) {
-                                for (ShortcutInfoCompat shortcut : pinnedShortcuts) {
-                                    shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut),
-                                            shortcut);
-                                }
-                            } else {
-                                // Shortcut manager can fail due to some race condition when the
-                                // lock state changes too frequently. For the purpose of the loading
-                                // shortcuts, consider the user is still locked.
-                                userUnlocked = false;
-                            }
-                        }
-                        unlockedUsers.put(serialNo, userUnlocked);
-                    }
-
-                    ShortcutInfo info;
-                    LauncherAppWidgetInfo appWidgetInfo;
-                    Intent intent;
-                    String targetPkg;
-
-                    while (!mStopped && c.moveToNext()) {
-                        try {
-                            if (c.user == null) {
-                                // User has been deleted, remove the item.
-                                c.markDeleted("User has been deleted");
-                                continue;
-                            }
-
-                            boolean allowMissingTarget = false;
-                            switch (c.itemType) {
-                            case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
-                            case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
-                            case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
-                                intent = c.parseIntent();
-                                if (intent == null) {
-                                    c.markDeleted("Invalid or null intent");
-                                    continue;
-                                }
-
-                                int disabledState = quietMode.get(c.serialNumber) ?
-                                        ShortcutInfo.FLAG_DISABLED_QUIET_USER : 0;
-                                ComponentName cn = intent.getComponent();
-                                targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
-
-                                if (!Process.myUserHandle().equals(c.user)) {
-                                    if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
-                                        c.markDeleted("Legacy shortcuts are only allowed for default user");
-                                        continue;
-                                    } else if (c.restoreFlag != 0) {
-                                        // Don't restore items for other profiles.
-                                        c.markDeleted("Restore from managed profile not supported");
-                                        continue;
-                                    }
-                                }
-                                if (TextUtils.isEmpty(targetPkg) &&
-                                        c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
-                                    c.markDeleted("Only legacy shortcuts can have null package");
-                                    continue;
-                                }
-
-                                // If there is no target package, its an implicit intent
-                                // (legacy shortcut) which is always valid
-                                boolean validTarget = TextUtils.isEmpty(targetPkg) ||
-                                        launcherApps.isPackageEnabledForProfile(targetPkg, c.user);
-
-                                if (cn != null && validTarget) {
-                                    // If the apk is present and the shortcut points to a specific
-                                    // component.
-
-                                    // If the component is already present
-                                    if (launcherApps.isActivityEnabledForProfile(cn, c.user)) {
-                                        // no special handling necessary for this item
-                                        c.markRestored();
-                                    } else {
-                                        if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
-                                            // We allow auto install apps to have their intent
-                                            // updated after an install.
-                                            intent = pmHelper.getAppLaunchIntent(targetPkg, c.user);
-                                            if (intent != null) {
-                                                c.restoreFlag = 0;
-                                                c.updater().put(
-                                                        LauncherSettings.Favorites.INTENT,
-                                                        intent.toUri(0)).commit();
-                                                cn = intent.getComponent();
-                                            } else {
-                                                c.markDeleted("Unable to find a launch target");
-                                                continue;
-                                            }
-                                        } else {
-                                            // The app is installed but the component is no
-                                            // longer available.
-                                            c.markDeleted("Invalid component removed: " + cn);
-                                            continue;
-                                        }
-                                    }
-                                }
-                                // else if cn == null => can't infer much, leave it
-                                // else if !validPkg => could be restored icon or missing sd-card
-
-                                if (!TextUtils.isEmpty(targetPkg) && !validTarget) {
-                                    // Points to a valid app (superset of cn != null) but the apk
-                                    // is not available.
-
-                                    if (c.restoreFlag != 0) {
-                                        // Package is not yet available but might be
-                                        // installed later.
-                                        FileLog.d(TAG, "package not yet restored: " + targetPkg);
-
-                                        if (c.hasRestoreFlag(ShortcutInfo.FLAG_RESTORE_STARTED)) {
-                                            // Restore has started once.
-                                        } else if (installingPkgs.containsKey(targetPkg)) {
-                                            // App restore has started. Update the flag
-                                            c.restoreFlag |= ShortcutInfo.FLAG_RESTORE_STARTED;
-                                            c.updater().commit();
-                                        } else {
-                                            c.markDeleted("Unrestored app removed: " + targetPkg);
-                                            continue;
-                                        }
-                                    } else if (pmHelper.isAppOnSdcard(targetPkg, c.user)) {
-                                        // Package is present but not available.
-                                        disabledState |= ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
-                                        // Add the icon on the workspace anyway.
-                                        allowMissingTarget = true;
-                                    } else if (!isSdCardReady) {
-                                        // SdCard is not ready yet. Package might get available,
-                                        // once it is ready.
-                                        Log.d(TAG, "Missing pkg, will check later: " + targetPkg);
-                                        pendingPackages.addToList(c.user, targetPkg);
-                                        // Add the icon on the workspace anyway.
-                                        allowMissingTarget = true;
-                                    } else {
-                                        // Do not wait for external media load anymore.
-                                        c.markDeleted("Invalid package removed: " + targetPkg);
-                                        continue;
-                                    }
-                                }
-
-                                if (validTarget) {
-                                    // The shortcut points to a valid target (either no target
-                                    // or something which is ready to be used)
-                                    c.markRestored();
-                                }
-
-                                boolean useLowResIcon = !c.isOnWorkspaceOrHotseat() &&
-                                        c.getInt(rankIndex) >= FolderIcon.NUM_ITEMS_IN_PREVIEW;
-
-                                if (c.restoreFlag != 0) {
-                                    // Already verified above that user is same as default user
-                                    info = c.getRestoredItemInfo(intent);
-                                } else if (c.itemType ==
-                                        LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
-                                    info = c.getAppShortcutInfo(
-                                            intent, allowMissingTarget, useLowResIcon);
-                                } else if (c.itemType ==
-                                        LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
-
-                                    ShortcutKey key = ShortcutKey.fromIntent(intent, c.user);
-                                    if (unlockedUsers.get(c.serialNumber)) {
-                                        ShortcutInfoCompat pinnedShortcut =
-                                                shortcutKeyToPinnedShortcuts.get(key);
-                                        if (pinnedShortcut == null) {
-                                            // The shortcut is no longer valid.
-                                            c.markDeleted("Pinned shortcut not found");
-                                            continue;
-                                        }
-                                        info = new ShortcutInfo(pinnedShortcut, context);
-                                        info.iconBitmap = LauncherIcons
-                                                .createShortcutIcon(pinnedShortcut, context);
-                                        if (pmHelper.isAppSuspended(
-                                                pinnedShortcut.getPackage(), info.user)) {
-                                            info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
-                                        }
-                                        intent = info.intent;
-                                    } else {
-                                        // Create a shortcut info in disabled mode for now.
-                                        info = c.loadSimpleShortcut();
-                                        info.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER;
-                                    }
-                                } else { // item type == ITEM_TYPE_SHORTCUT
-                                    info = c.loadSimpleShortcut();
-
-                                    // Shortcuts are only available on the primary profile
-                                    if (!TextUtils.isEmpty(targetPkg)
-                                            && pmHelper.isAppSuspended(targetPkg, c.user)) {
-                                        disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
-                                    }
-
-                                    // App shortcuts that used to be automatically added to Launcher
-                                    // didn't always have the correct intent flags set, so do that
-                                    // here
-                                    if (intent.getAction() != null &&
-                                        intent.getCategories() != null &&
-                                        intent.getAction().equals(Intent.ACTION_MAIN) &&
-                                        intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
-                                        intent.addFlags(
-                                            Intent.FLAG_ACTIVITY_NEW_TASK |
-                                            Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-                                    }
-                                }
-
-                                if (info != null) {
-                                    c.applyCommonProperties(info);
-
-                                    info.intent = intent;
-                                    info.rank = c.getInt(rankIndex);
-                                    info.spanX = 1;
-                                    info.spanY = 1;
-                                    info.isDisabled |= disabledState;
-                                    if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
-                                        info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE;
-                                    }
-
-                                    if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) {
-                                        Integer progress = installingPkgs.get(targetPkg);
-                                        if (progress != null) {
-                                            info.setInstallProgress(progress);
-                                        } else {
-                                            info.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
-                                        }
-                                    }
-
-                                    c.checkAndAddItem(info, sBgDataModel);
-                                } else {
-                                    throw new RuntimeException("Unexpected null ShortcutInfo");
-                                }
-                                break;
-
-                            case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
-                                FolderInfo folderInfo = sBgDataModel.findOrMakeFolder(c.id);
-                                c.applyCommonProperties(folderInfo);
-
-                                // Do not trim the folder label, as is was set by the user.
-                                folderInfo.title = c.getString(c.titleIndex);
-                                folderInfo.spanX = 1;
-                                folderInfo.spanY = 1;
-                                folderInfo.options = c.getInt(optionsIndex);
-
-                                // no special handling required for restored folders
-                                c.markRestored();
-
-                                c.checkAndAddItem(folderInfo, sBgDataModel);
-                                break;
-
-                            case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
-                            case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
-                                // Read all Launcher-specific widget details
-                                boolean customWidget = c.itemType ==
-                                    LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
-
-                                int appWidgetId = c.getInt(appWidgetIdIndex);
-                                String savedProvider = c.getString(appWidgetProviderIndex);
-
-                                final ComponentName component =
-                                        ComponentName.unflattenFromString(savedProvider);
-
-                                final boolean isIdValid = !c.hasRestoreFlag(
-                                        LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
-                                final boolean wasProviderReady = !c.hasRestoreFlag(
-                                        LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
-
-                                if (widgetProvidersMap == null) {
-                                    widgetProvidersMap = AppWidgetManagerCompat
-                                            .getInstance(mContext).getAllProvidersMap();
-                                }
-                                final AppWidgetProviderInfo provider = widgetProvidersMap.get(
-                                        new ComponentKey(
-                                                ComponentName.unflattenFromString(savedProvider),
-                                                c.user));
-
-                                final boolean isProviderReady = isValidProvider(provider);
-                                if (!isSafeMode && !customWidget &&
-                                        wasProviderReady && !isProviderReady) {
-                                    c.markDeleted(
-                                            "Deleting widget that isn't installed anymore: "
-                                            + provider);
-                                } else {
-                                    if (isProviderReady) {
-                                        appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
-                                                provider.provider);
-
-                                        // The provider is available. So the widget is either
-                                        // available or not available. We do not need to track
-                                        // any future restore updates.
-                                        int status = c.restoreFlag &
-                                                ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
-                                        if (!wasProviderReady) {
-                                            // If provider was not previously ready, update the
-                                            // status and UI flag.
-
-                                            // Id would be valid only if the widget restore broadcast was received.
-                                            if (isIdValid) {
-                                                status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
-                                            } else {
-                                                status &= ~LauncherAppWidgetInfo
-                                                        .FLAG_PROVIDER_NOT_READY;
-                                            }
-                                        }
-                                        appWidgetInfo.restoreStatus = status;
-                                    } else {
-                                        Log.v(TAG, "Widget restore pending id=" + c.id
-                                                + " appWidgetId=" + appWidgetId
-                                                + " status =" + c.restoreFlag);
-                                        appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
-                                                component);
-                                        appWidgetInfo.restoreStatus = c.restoreFlag;
-                                        Integer installProgress = installingPkgs.get(component.getPackageName());
-
-                                        if (c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED)) {
-                                            // Restore has started once.
-                                        } else if (installProgress != null) {
-                                            // App restore has started. Update the flag
-                                            appWidgetInfo.restoreStatus |=
-                                                    LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
-                                        } else if (!isSafeMode) {
-                                            c.markDeleted("Unrestored widget removed: " + component);
-                                            continue;
-                                        }
-
-                                        appWidgetInfo.installProgress =
-                                                installProgress == null ? 0 : installProgress;
-                                    }
-                                    if (appWidgetInfo.hasRestoreFlag(
-                                            LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) {
-                                        appWidgetInfo.bindOptions = c.parseIntent();
-                                    }
-
-                                    c.applyCommonProperties(appWidgetInfo);
-                                    appWidgetInfo.spanX = c.getInt(spanXIndex);
-                                    appWidgetInfo.spanY = c.getInt(spanYIndex);
-                                    appWidgetInfo.user = c.user;
-
-                                    if (!c.isOnWorkspaceOrHotseat()) {
-                                        c.markDeleted("Widget found where container != " +
-                                                "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!");
-                                        continue;
-                                    }
-
-                                    if (!customWidget) {
-                                        String providerName =
-                                                appWidgetInfo.providerName.flattenToString();
-                                        if (!providerName.equals(savedProvider) ||
-                                                (appWidgetInfo.restoreStatus != c.restoreFlag)) {
-                                            c.updater()
-                                                    .put(LauncherSettings.Favorites.APPWIDGET_PROVIDER,
-                                                            providerName)
-                                                    .put(LauncherSettings.Favorites.RESTORED,
-                                                            appWidgetInfo.restoreStatus)
-                                                    .commit();
-                                        }
-                                    }
-                                    c.checkAndAddItem(appWidgetInfo, sBgDataModel);
-                                }
-                                break;
-                            }
-                        } catch (Exception e) {
-                            Log.e(TAG, "Desktop items loading interrupted", e);
-                        }
-                    }
-                } finally {
-                    Utilities.closeSilently(c);
+        @Override
+        public void close() {
+            synchronized (mLock) {
+                // If we are still the last one to be scheduled, remove ourselves.
+                if (mLoaderTask == mTask) {
+                    mLoaderTask = null;
                 }
-
-                // Break early if we've stopped loading
-                if (mStopped) {
-                    sBgDataModel.clear();
-                    return;
-                }
-
-                // Remove dead items
-                if (c.commitDeleted()) {
-                    // Remove any empty folder
-                    ArrayList<Long> deletedFolderIds = (ArrayList<Long>) LauncherSettings.Settings
-                            .call(contentResolver,
-                                    LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS)
-                            .getSerializable(LauncherSettings.Settings.EXTRA_VALUE);
-                    for (long folderId : deletedFolderIds) {
-                        sBgDataModel.workspaceItems.remove(sBgDataModel.folders.get(folderId));
-                        sBgDataModel.folders.remove(folderId);
-                        sBgDataModel.itemsIdMap.remove(folderId);
-                    }
-
-                    // Remove any ghost widgets
-                    LauncherSettings.Settings.call(contentResolver,
-                            LauncherSettings.Settings.METHOD_REMOVE_GHOST_WIDGETS);
-                }
-
-                // Unpin shortcuts that don't exist on the workspace.
-                HashSet<ShortcutKey> pendingShortcuts =
-                        InstallShortcutReceiver.getPendingShortcuts(context);
-                for (ShortcutKey key : shortcutKeyToPinnedShortcuts.keySet()) {
-                    MutableInt numTimesPinned = sBgDataModel.pinnedShortcutCounts.get(key);
-                    if ((numTimesPinned == null || numTimesPinned.value == 0)
-                            && !pendingShortcuts.contains(key)) {
-                        // Shortcut is pinned but doesn't exist on the workspace; unpin it.
-                        shortcutManager.unpinShortcut(key);
-                    }
-                }
-
-                // Sort all the folder items and make sure the first 3 items are high resolution.
-                for (FolderInfo folder : sBgDataModel.folders) {
-                    Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR);
-                    int pos = 0;
-                    for (ShortcutInfo info : folder.contents) {
-                        if (info.usingLowResIcon &&
-                                info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
-                            mIconCache.getTitleAndIcon(info, false);
-                        }
-                        pos ++;
-                        if (pos >= FolderIcon.NUM_ITEMS_IN_PREVIEW) {
-                            break;
-                        }
-                    }
-                }
-
-                c.commitRestoredItems();
-                if (!isSdCardReady && !pendingPackages.isEmpty()) {
-                    context.registerReceiver(
-                            new SdCardAvailableReceiver(
-                                    LauncherModel.this, mContext, pendingPackages),
-                            new IntentFilter(Intent.ACTION_BOOT_COMPLETED),
-                            null,
-                            sWorker);
-                }
-
-                // Remove any empty screens
-                ArrayList<Long> unusedScreens = new ArrayList<>(sBgDataModel.workspaceScreens);
-                for (ItemInfo item: sBgDataModel.itemsIdMap) {
-                    long screenId = item.screenId;
-                    if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                            unusedScreens.contains(screenId)) {
-                        unusedScreens.remove(screenId);
-                    }
-                }
-
-                // If there are any empty screens remove them, and update.
-                if (unusedScreens.size() != 0) {
-                    sBgDataModel.workspaceScreens.removeAll(unusedScreens);
-                    updateWorkspaceScreenOrder(context, sBgDataModel.workspaceScreens);
-                }
-            }
-            if (LauncherAppState.PROFILE_STARTUP) {
-                Trace.endSection();
-            }
-        }
-
-        /** Filters the set of items who are directly or indirectly (via another container) on the
-         * specified screen. */
-        private void filterCurrentWorkspaceItems(long currentScreenId,
-                ArrayList<ItemInfo> allWorkspaceItems,
-                ArrayList<ItemInfo> currentScreenItems,
-                ArrayList<ItemInfo> otherScreenItems) {
-            // Purge any null ItemInfos
-            Iterator<ItemInfo> iter = allWorkspaceItems.iterator();
-            while (iter.hasNext()) {
-                ItemInfo i = iter.next();
-                if (i == null) {
-                    iter.remove();
-                }
-            }
-
-            // Order the set of items by their containers first, this allows use to walk through the
-            // list sequentially, build up a list of containers that are in the specified screen,
-            // as well as all items in those containers.
-            Set<Long> itemsOnScreen = new HashSet<Long>();
-            Collections.sort(allWorkspaceItems, new Comparator<ItemInfo>() {
-                @Override
-                public int compare(ItemInfo lhs, ItemInfo rhs) {
-                    return Utilities.longCompare(lhs.container, rhs.container);
-                }
-            });
-            for (ItemInfo info : allWorkspaceItems) {
-                if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                    if (info.screenId == currentScreenId) {
-                        currentScreenItems.add(info);
-                        itemsOnScreen.add(info.id);
-                    } else {
-                        otherScreenItems.add(info);
-                    }
-                } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
-                    currentScreenItems.add(info);
-                    itemsOnScreen.add(info.id);
-                } else {
-                    if (itemsOnScreen.contains(info.container)) {
-                        currentScreenItems.add(info);
-                        itemsOnScreen.add(info.id);
-                    } else {
-                        otherScreenItems.add(info);
-                    }
-                }
-            }
-        }
-
-        /** Filters the set of widgets which are on the specified screen. */
-        private void filterCurrentAppWidgets(long currentScreenId,
-                ArrayList<LauncherAppWidgetInfo> appWidgets,
-                ArrayList<LauncherAppWidgetInfo> currentScreenWidgets,
-                ArrayList<LauncherAppWidgetInfo> otherScreenWidgets) {
-
-            for (LauncherAppWidgetInfo widget : appWidgets) {
-                if (widget == null) continue;
-                if (widget.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                        widget.screenId == currentScreenId) {
-                    currentScreenWidgets.add(widget);
-                } else {
-                    otherScreenWidgets.add(widget);
-                }
-            }
-        }
-
-        /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to
-         * right) */
-        private void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) {
-            final InvariantDeviceProfile profile = mApp.getInvariantDeviceProfile();
-            final int screenCols = profile.numColumns;
-            final int screenCellCount = profile.numColumns * profile.numRows;
-            Collections.sort(workspaceItems, new Comparator<ItemInfo>() {
-                @Override
-                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) {
-                            case LauncherSettings.Favorites.CONTAINER_DESKTOP: {
-                                long lr = (lhs.screenId * screenCellCount +
-                                        lhs.cellY * screenCols + lhs.cellX);
-                                long rr = (rhs.screenId * screenCellCount +
-                                        rhs.cellY * screenCols + rhs.cellX);
-                                return Utilities.longCompare(lr, rr);
-                            }
-                            case LauncherSettings.Favorites.CONTAINER_HOTSEAT: {
-                                // We currently use the screen id as the rank
-                                return Utilities.longCompare(lhs.screenId, rhs.screenId);
-                            }
-                            default:
-                                if (ProviderConfig.IS_DOGFOOD_BUILD) {
-                                    throw new RuntimeException("Unexpected container type when " +
-                                            "sorting workspace items.");
-                                }
-                                return 0;
-                        }
-                    } else {
-                        // Between containers, order by hotseat, desktop
-                        return Utilities.longCompare(lhs.container, rhs.container);
-                    }
-                }
-            });
-        }
-
-        private void bindWorkspaceScreens(final Callbacks oldCallbacks,
-                final ArrayList<Long> orderedScreens) {
-            final Runnable r = new Runnable() {
-                @Override
-                public void run() {
-                    Callbacks callbacks = tryGetCallbacks(oldCallbacks);
-                    if (callbacks != null) {
-                        callbacks.bindScreens(orderedScreens);
-                    }
-                }
-            };
-            runOnMainThread(r);
-        }
-
-        private void bindWorkspaceItems(final Callbacks oldCallbacks,
-                final ArrayList<ItemInfo> workspaceItems,
-                final ArrayList<LauncherAppWidgetInfo> appWidgets,
-                final Executor executor) {
-
-            // 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 = tryGetCallbacks(oldCallbacks);
-                        if (callbacks != null) {
-                            callbacks.bindItems(workspaceItems, start, start+chunkSize,
-                                    false);
-                        }
-                    }
-                };
-                executor.execute(r);
-            }
-
-            // Bind the widgets, one at a time
-            N = appWidgets.size();
-            for (int i = 0; i < N; i++) {
-                final LauncherAppWidgetInfo widget = appWidgets.get(i);
-                final Runnable r = new Runnable() {
-                    public void run() {
-                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
-                        if (callbacks != null) {
-                            callbacks.bindAppWidget(widget);
-                        }
-                    }
-                };
-                executor.execute(r);
-            }
-        }
-
-        /**
-         * Binds all loaded data to actual views on the main thread.
-         */
-        private void bindWorkspace(int synchronizeBindPage) {
-            final long t = SystemClock.uptimeMillis();
-            Runnable r;
-
-            // Don't use these two variables in any of the callback runnables.
-            // Otherwise we hold a reference to them.
-            final Callbacks oldCallbacks = mCallbacks.get();
-            if (oldCallbacks == null) {
-                // This launcher has exited and nobody bothered to tell us.  Just bail.
-                Log.w(TAG, "LoaderTask running with no launcher");
-                return;
-            }
-
-            // Save a copy of all the bg-thread collections
-            ArrayList<ItemInfo> workspaceItems = new ArrayList<>();
-            ArrayList<LauncherAppWidgetInfo> appWidgets = new ArrayList<>();
-            ArrayList<Long> orderedScreenIds = new ArrayList<>();
-
-            synchronized (sBgDataModel) {
-                workspaceItems.addAll(sBgDataModel.workspaceItems);
-                appWidgets.addAll(sBgDataModel.appWidgets);
-                orderedScreenIds.addAll(sBgDataModel.workspaceScreens);
-            }
-
-            final int currentScreen;
-            {
-                int currScreen = synchronizeBindPage != PagedView.INVALID_RESTORE_PAGE
-                        ? synchronizeBindPage : oldCallbacks.getCurrentWorkspaceScreen();
-                if (currScreen >= orderedScreenIds.size()) {
-                    // There may be no workspace screens (just hotseat items and an empty page).
-                    currScreen = PagedView.INVALID_RESTORE_PAGE;
-                }
-                currentScreen = currScreen;
-            }
-            final boolean validFirstPage = currentScreen >= 0;
-            final long currentScreenId =
-                    validFirstPage ? orderedScreenIds.get(currentScreen) : INVALID_SCREEN_ID;
-
-            // Separate the items that are on the current screen, and all the other remaining items
-            ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
-            ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
-            ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
-            ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
-
-            filterCurrentWorkspaceItems(currentScreenId, workspaceItems, currentWorkspaceItems,
-                    otherWorkspaceItems);
-            filterCurrentAppWidgets(currentScreenId, appWidgets, currentAppWidgets,
-                    otherAppWidgets);
-            sortWorkspaceItemsSpatially(currentWorkspaceItems);
-            sortWorkspaceItemsSpatially(otherWorkspaceItems);
-
-            // Tell the workspace that we're about to start binding items
-            r = new Runnable() {
-                public void run() {
-                    Callbacks callbacks = tryGetCallbacks(oldCallbacks);
-                    if (callbacks != null) {
-                        callbacks.clearPendingBinds();
-                        callbacks.startBinding();
-                    }
-                }
-            };
-            runOnMainThread(r);
-
-            bindWorkspaceScreens(oldCallbacks, orderedScreenIds);
-
-            Executor mainExecutor = new DeferredMainThreadExecutor();
-            // Load items on the current page.
-            bindWorkspaceItems(oldCallbacks, currentWorkspaceItems, 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).
-            // This ensures that the first screen is immediately visible (eg. during rotation)
-            // In case of !validFirstPage, bind all pages one after other.
-            final Executor deferredExecutor =
-                    validFirstPage ? new ViewOnDrawExecutor(mHandler) : mainExecutor;
-
-            mainExecutor.execute(new Runnable() {
-                @Override
-                public void run() {
-                    Callbacks callbacks = tryGetCallbacks(oldCallbacks);
-                    if (callbacks != null) {
-                        callbacks.finishFirstPageBind(
-                                validFirstPage ? (ViewOnDrawExecutor) deferredExecutor : null);
-                    }
-                }
-            });
-
-            bindWorkspaceItems(oldCallbacks, otherWorkspaceItems, otherAppWidgets, deferredExecutor);
-
-            // Tell the workspace that we're done binding items
-            r = new Runnable() {
-                public void run() {
-                    Callbacks callbacks = tryGetCallbacks(oldCallbacks);
-                    if (callbacks != null) {
-                        callbacks.finishBindingItems();
-                    }
-
-                    mIsLoadingAndBindingWorkspace = false;
-
-                    // Run all the bind complete runnables after workspace is bound.
-                    if (!mBindCompleteRunnables.isEmpty()) {
-                        synchronized (mBindCompleteRunnables) {
-                            for (final Runnable r : mBindCompleteRunnables) {
-                                runOnWorkerThread(r);
-                            }
-                            mBindCompleteRunnables.clear();
-                        }
-                    }
-
-                    // If we're profiling, ensure this is the last thing in the queue.
-                    if (DEBUG_LOADERS) {
-                        Log.d(TAG, "bound workspace in "
-                            + (SystemClock.uptimeMillis()-t) + "ms");
-                    }
-
-                }
-            };
-            deferredExecutor.execute(r);
-
-            if (validFirstPage) {
-                r = new Runnable() {
-                    public void run() {
-                        Callbacks callbacks = tryGetCallbacks(oldCallbacks);
-                        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);
-                        }
-                    }
-                };
-                runOnMainThread(r);
-            }
-        }
-
-        private void updateIconCache() {
-            // Ignore packages which have a promise icon.
-            HashSet<String> packagesToIgnore = new HashSet<>();
-            synchronized (sBgDataModel) {
-                for (ItemInfo info : sBgDataModel.itemsIdMap) {
-                    if (info instanceof ShortcutInfo) {
-                        ShortcutInfo si = (ShortcutInfo) info;
-                        if (si.isPromise() && si.getTargetComponent() != null) {
-                            packagesToIgnore.add(si.getTargetComponent().getPackageName());
-                        }
-                    } else if (info instanceof LauncherAppWidgetInfo) {
-                        LauncherAppWidgetInfo lawi = (LauncherAppWidgetInfo) info;
-                        if (lawi.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) {
-                            packagesToIgnore.add(lawi.providerName.getPackageName());
-                        }
-                    }
-                }
-            }
-            mIconCache.updateDbIcons(packagesToIgnore);
-        }
-
-        private void onlyBindAllApps() {
-            final Callbacks oldCallbacks = mCallbacks.get();
-            if (oldCallbacks == null) {
-                // This launcher has exited and nobody bothered to tell us.  Just bail.
-                Log.w(TAG, "LoaderTask running with no launcher (onlyBindAllApps)");
-                return;
-            }
-
-            // shallow copy
-            @SuppressWarnings("unchecked")
-            final ArrayList<AppInfo> list
-                    = (ArrayList<AppInfo>) mBgAllAppsList.data.clone();
-            Runnable r = new Runnable() {
-                public void run() {
-                    final long t = SystemClock.uptimeMillis();
-                    final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
-                    if (callbacks != null) {
-                        callbacks.bindAllApplications(list);
-                    }
-                    if (DEBUG_LOADERS) {
-                        Log.d(TAG, "bound all " + list.size() + " apps from cache in "
-                                + (SystemClock.uptimeMillis() - t) + "ms");
-                    }
-                }
-            };
-            runOnMainThread(r);
-        }
-
-        private void loadAllApps() {
-            final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
-
-            final Callbacks oldCallbacks = mCallbacks.get();
-            if (oldCallbacks == null) {
-                // This launcher has exited and nobody bothered to tell us.  Just bail.
-                Log.w(TAG, "LoaderTask running with no launcher (loadAllApps)");
-                return;
-            }
-
-            final List<UserHandle> profiles = mUserManager.getUserProfiles();
-
-            // Clear the list of apps
-            mBgAllAppsList.clear();
-            for (UserHandle user : profiles) {
-                // Query for the set of apps
-                final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
-                final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
-                if (DEBUG_LOADERS) {
-                    Log.d(TAG, "getActivityList took "
-                            + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user);
-                    Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user);
-                }
-                // Fail if we don't have any apps
-                // TODO: Fix this. Only fail for the current user.
-                if (apps == null || apps.isEmpty()) {
-                    return;
-                }
-                boolean quietMode = mUserManager.isQuietModeEnabled(user);
-                // Create the ApplicationInfos
-                for (int i = 0; i < apps.size(); i++) {
-                    LauncherActivityInfo app = apps.get(i);
-                    // This builds the icon bitmaps.
-                    mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
-                }
-
-                final ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(mContext, user);
-                if (heuristic != null) {
-                    final Runnable r = new Runnable() {
-
-                        @Override
-                        public void run() {
-                            heuristic.processUserApps(apps);
-                        }
-                    };
-                    runOnMainThread(new Runnable() {
-
-                        @Override
-                        public void run() {
-                            // Check isLoadingWorkspace on the UI thread, as it is updated on
-                            // the UI thread.
-                            if (mIsLoadingAndBindingWorkspace) {
-                                synchronized (mBindCompleteRunnables) {
-                                    mBindCompleteRunnables.add(r);
-                                }
-                            } else {
-                                runOnWorkerThread(r);
-                            }
-                        }
-                    });
-                }
-            }
-            // Huh? Shouldn't this be inside the Runnable below?
-            final ArrayList<AppInfo> added = mBgAllAppsList.added;
-            mBgAllAppsList.added = new ArrayList<AppInfo>();
-
-            // Post callback on main thread
-            mHandler.post(new Runnable() {
-                public void run() {
-
-                    final long bindTime = SystemClock.uptimeMillis();
-                    final Callbacks callbacks = tryGetCallbacks(oldCallbacks);
-                    if (callbacks != null) {
-                        callbacks.bindAllApplications(added);
-                        if (DEBUG_LOADERS) {
-                            Log.d(TAG, "bound " + added.size() + " apps in "
-                                    + (SystemClock.uptimeMillis() - bindTime) + "ms");
-                        }
-                    } else {
-                        Log.i(TAG, "not binding apps: no Launcher activity");
-                    }
-                }
-            });
-            // Cleanup any data stored for a deleted user.
-            ManagedProfileHeuristic.processAllUsers(profiles, mContext);
-            if (DEBUG_LOADERS) {
-                Log.d(TAG, "Icons processed in "
-                        + (SystemClock.uptimeMillis() - loadTime) + "ms");
-            }
-        }
-
-        private void loadDeepShortcuts() {
-            sBgDataModel.deepShortcutMap.clear();
-            DeepShortcutManager shortcutManager = DeepShortcutManager.getInstance(mContext);
-            mHasShortcutHostPermission = shortcutManager.hasHostPermission();
-            if (mHasShortcutHostPermission) {
-                for (UserHandle user : mUserManager.getUserProfiles()) {
-                    if (mUserManager.isUserUnlocked(user)) {
-                        List<ShortcutInfoCompat> shortcuts =
-                                shortcutManager.queryForAllShortcuts(user);
-                        sBgDataModel.updateDeepShortcutMap(null, user, shortcuts);
-                    }
-                }
+                mIsLoaderTaskRunning = false;
             }
         }
     }
 
-    public void bindDeepShortcuts() {
-        final MultiHashMap<ComponentKey, String> shortcutMapCopy =
-                sBgDataModel.deepShortcutMap.clone();
-        Runnable r = new Runnable() {
-            @Override
-            public void run() {
-                Callbacks callbacks = getCallback();
-                if (callbacks != null) {
-                    callbacks.bindDeepShortcutMap(shortcutMapCopy);
-                }
-            }
-        };
-        runOnMainThread(r);
+    public LoaderTransaction beginLoader(LoaderTask task) throws CancellationException {
+        return new LoaderTransaction(task);
     }
 
     /**
@@ -1815,13 +607,7 @@
                 CacheDataUpdatedTask.OP_CACHE_UPDATE, user, updatedPackages));
     }
 
-    void enqueueModelUpdateTask(BaseModelUpdateTask task) {
-        if (!mModelLoaded && mLoaderTask == null) {
-            if (DEBUG_LOADERS) {
-                Log.d(TAG, "enqueueModelUpdateTask Ignoring task since loader is pending=" + task);
-            }
-            return;
-        }
+    public void enqueueModelUpdateTask(BaseModelUpdateTask task) {
         task.init(this);
         runOnWorkerThread(task);
     }
@@ -1841,17 +627,20 @@
     public static abstract class BaseModelUpdateTask implements Runnable {
 
         private LauncherModel mModel;
-        private DeferredHandler mUiHandler;
+        private Executor mUiExecutor;
 
         /* package private */
         void init(LauncherModel model) {
             mModel = model;
-            mUiHandler = mModel.mHandler;
+            mUiExecutor = mModel.mUiExecutor;
         }
 
         @Override
-        public void run() {
-            if (!mModel.mHasLoaderCompletedOnce) {
+        public final void run() {
+            if (!mModel.mModelLoaded) {
+                if (DEBUG_TASKS) {
+                    Log.d(TAG, "Ignoring model task since loader is pending=" + this);
+                }
                 // Loader has not yet run.
                 return;
             }
@@ -1869,7 +658,7 @@
          */
         public final void scheduleCallbackTask(final CallbackTask task) {
             final Callbacks callbacks = mModel.getCallback();
-            mUiHandler.post(new Runnable() {
+            mUiExecutor.execute(new Runnable() {
                 public void run() {
                     Callbacks cb = mModel.getCallback();
                     if (callbacks == cb && cb != null) {
@@ -1911,43 +700,16 @@
         });
     }
 
-    private void bindWidgetsModel(final Callbacks callbacks) {
-        final MultiHashMap<PackageItemInfo, WidgetItem> widgets
-                = mBgWidgetsModel.getWidgetsMap().clone();
-        mHandler.post(new Runnable() {
+    public void refreshAndBindWidgetsAndShortcuts(@Nullable final PackageUserKey packageUser) {
+        enqueueModelUpdateTask(new ExtendedModelTask() {
             @Override
-            public void run() {
-                Callbacks cb = getCallback();
-                if (callbacks == cb && cb != null) {
-                    callbacks.bindAllWidgets(widgets);
-                }
+            public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
+                dataModel.widgetsModel.update(app, packageUser);
+                bindUpdatedWidgets(dataModel);
             }
         });
     }
 
-    public void refreshAndBindWidgetsAndShortcuts(final Callbacks callbacks,
-            final boolean bindFirst, @Nullable final PackageUserKey packageUser) {
-        runOnWorkerThread(new Runnable() {
-            @Override
-            public void run() {
-                if (bindFirst && !mBgWidgetsModel.isEmpty()) {
-                    bindWidgetsModel(callbacks);
-                }
-                ArrayList<WidgetItem> widgets = mBgWidgetsModel.update(
-                        mApp.getContext(), packageUser);
-                bindWidgetsModel(callbacks);
-
-                // update the Widget entries inside DB on the worker thread.
-                mApp.getWidgetCache().removeObsoletePreviews(widgets, packageUser);
-            }
-        });
-    }
-
-    static boolean isValidProvider(AppWidgetProviderInfo provider) {
-        return (provider != null) && (provider.provider != null)
-                && (provider.provider.getPackageName() != null);
-    }
-
     public void dumpState(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) {
         if (args.length > 0 && TextUtils.equals(args[0], "--all")) {
             writer.println(prefix + "All apps list: size=" + mBgAllAppsList.data.size());
@@ -1964,23 +726,6 @@
     }
 
     /**
-     * @return {@link FolderInfo} if its already loaded.
-     */
-    public FolderInfo findFolderById(Long folderId) {
-        synchronized (sBgDataModel) {
-            return sBgDataModel.folders.get(folderId);
-        }
-    }
-
-    @Thunk class DeferredMainThreadExecutor implements Executor {
-
-        @Override
-        public void execute(Runnable command) {
-            runOnMainThread(command);
-        }
-    }
-
-    /**
      * @return the looper for the worker thread which can be used to start background tasks.
      */
     public static Looper getWorkerLooper() {
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 3150d5b..4813571 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import android.annotation.TargetApi;
 import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetManager;
 import android.content.ComponentName;
@@ -38,6 +39,7 @@
 import android.database.sqlite.SQLiteStatement;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -53,43 +55,39 @@
 import com.android.launcher3.LauncherSettings.WorkspaceScreens;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.dynamicui.ExtractionUtils;
 import com.android.launcher3.graphics.IconShapeOverride;
 import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.model.DbDowngradeHelper;
 import com.android.launcher3.provider.LauncherDbUtils;
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
 import com.android.launcher3.provider.RestoreDbTask;
 import com.android.launcher3.util.ManagedProfileHeuristic;
 import com.android.launcher3.util.NoLocaleSqliteContext;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.Thunk;
 
+import java.io.File;
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.lang.reflect.Method;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 
 public class LauncherProvider extends ContentProvider {
     private static final String TAG = "LauncherProvider";
     private static final boolean LOGD = false;
 
+    private static final String DOWNGRADE_SCHEMA_FILE = "downgrade_schema.json";
+
     /**
      * Represents the schema of the database. Changes in scheme need not be backwards compatible.
      */
-    private static final int SCHEMA_VERSION = 27;
-    /**
-     * Represents the actual data. It could include additional validations and normalizations added
-     * overtime. These must be backwards compatible, else we risk breaking old devices during
-     * restore or binary version downgrade.
-     */
-    private static final int DATA_VERSION = 3;
+    public static final int SCHEMA_VERSION = 27;
 
-    private static final String PREF_KEY_DATA_VERISON = "provider_data_version";
-
-    public static final String AUTHORITY = ProviderConfig.AUTHORITY;
+    public static final String AUTHORITY = (BuildConfig.APPLICATION_ID + ".settings").intern();
 
     static final String EMPTY_DATABASE_CREATED = "EMPTY_DATABASE_CREATED";
 
@@ -114,7 +112,7 @@
 
     @Override
     public boolean onCreate() {
-        if (ProviderConfig.IS_DOGFOOD_BUILD) {
+        if (FeatureFlags.IS_DOGFOOD_BUILD) {
             Log.d(TAG, "Launcher process started");
         }
         mListenerHandler = new Handler(mListenerWrapper);
@@ -305,8 +303,7 @@
         SqlArguments args = new SqlArguments(uri);
 
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        db.beginTransaction();
-        try {
+        try (SQLiteTransaction t = new SQLiteTransaction(db)) {
             int numValues = values.length;
             for (int i = 0; i < numValues; i++) {
                 addModifiedTime(values[i]);
@@ -314,9 +311,7 @@
                     return 0;
                 }
             }
-            db.setTransactionSuccessful();
-        } finally {
-            db.endTransaction();
+            t.commit();
         }
 
         notifyListeners();
@@ -328,15 +323,11 @@
     public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
             throws OperationApplicationException {
         createDbIfNotExists();
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        db.beginTransaction();
-        try {
+        try (SQLiteTransaction t = new SQLiteTransaction(mOpenHelper.getWritableDatabase())) {
             ContentProviderResult[] result =  super.applyBatch(operations);
-            db.setTransactionSuccessful();
+            t.commit();
             reloadLauncherIfExternal();
             return result;
-        } finally {
-            db.endTransaction();
         }
     }
 
@@ -442,31 +433,26 @@
     private ArrayList<Long> deleteEmptyFolders() {
         ArrayList<Long> folderIds = new ArrayList<>();
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        db.beginTransaction();
-        try {
+        try (SQLiteTransaction t = new SQLiteTransaction(db)) {
             // Select folders whose id do not match any container value.
             String selection = LauncherSettings.Favorites.ITEM_TYPE + " = "
                     + LauncherSettings.Favorites.ITEM_TYPE_FOLDER + " AND "
                     + LauncherSettings.Favorites._ID +  " NOT IN (SELECT " +
                             LauncherSettings.Favorites.CONTAINER + " FROM "
                                 + Favorites.TABLE_NAME + ")";
-            Cursor c = db.query(Favorites.TABLE_NAME,
+            try (Cursor c = db.query(Favorites.TABLE_NAME,
                     new String[] {LauncherSettings.Favorites._ID},
-                    selection, null, null, null, null);
-            while (c.moveToNext()) {
-                folderIds.add(c.getLong(0));
+                    selection, null, null, null, null)) {
+                LauncherDbUtils.iterateCursor(c, 0, folderIds);
             }
-            c.close();
             if (!folderIds.isEmpty()) {
                 db.delete(Favorites.TABLE_NAME, Utilities.createDbSelectionQuery(
                         LauncherSettings.Favorites._ID, folderIds), null);
             }
-            db.setTransactionSuccessful();
+            t.commit();
         } catch (SQLException ex) {
             Log.e(TAG, ex.getMessage(), ex);
             folderIds.clear();
-        } finally {
-            db.endTransaction();
         }
         return folderIds;
     }
@@ -714,50 +700,30 @@
         @Override
         public void onOpen(SQLiteDatabase db) {
             super.onOpen(db);
-            SharedPreferences prefs = mContext
-                    .getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, 0);
-            int oldVersion = prefs.getInt(PREF_KEY_DATA_VERISON, 0);
-            if (oldVersion != DATA_VERSION) {
-                // Only run the data upgrade path for an existing db.
-                if (!Utilities.getPrefs(mContext).getBoolean(EMPTY_DATABASE_CREATED, false)) {
-                    db.beginTransaction();
-                    try {
-                        onDataUpgrade(db, oldVersion);
-                        db.setTransactionSuccessful();
-                    } catch (Exception e) {
-                        Log.d(TAG, "Error updating data version, ignoring", e);
-                        return;
-                    } finally {
-                        db.endTransaction();
-                    }
-                }
-                prefs.edit().putInt(PREF_KEY_DATA_VERISON, DATA_VERSION).apply();
+
+            File schemaFile = mContext.getFileStreamPath(DOWNGRADE_SCHEMA_FILE);
+            if (!schemaFile.exists()) {
+                handleOneTimeDataUpgrade(db);
             }
+            DbDowngradeHelper.updateSchemaFile(schemaFile, SCHEMA_VERSION, mContext,
+                    R.raw.downgrade_schema);
         }
 
         /**
-         * Called when the data is updated as part of app update. It can be called multiple times
-         * with old version, even though it had been run before. The changes made here must be
-         * backwards compatible, else we risk breaking old devices during restore or binary
-         * version downgrade.
+         * One-time data updated before support of onDowngrade was added. This update is backwards
+         * compatible and can safely be run multiple times.
+         * Note: No new logic should be added here after release, as the new logic might not get
+         * executed on an existing device.
+         * TODO: Move this to db upgrade path, once the downgrade path is released.
          */
-        protected void onDataUpgrade(SQLiteDatabase db, int oldVersion) {
-            switch (oldVersion) {
-                case 0:
-                case 1: {
-                    // Remove "profile extra"
-                    UserManagerCompat um = UserManagerCompat.getInstance(mContext);
-                    for (UserHandle user : um.getUserProfiles()) {
-                        long serial = um.getSerialNumberForUser(user);
-                        String sql = "update favorites set intent = replace(intent, "
-                                + "';l.profile=" + serial + ";', ';') where itemType = 0;";
-                        db.execSQL(sql);
-                    }
-                }
-                case 2:
-                case 3:
-                    // data updated
-                    return;
+        protected void handleOneTimeDataUpgrade(SQLiteDatabase db) {
+            // Remove "profile extra"
+            UserManagerCompat um = UserManagerCompat.getInstance(mContext);
+            for (UserHandle user : um.getUserProfiles()) {
+                long serial = um.getSerialNumberForUser(user);
+                String sql = "update favorites set intent = replace(intent, "
+                        + "';l.profile=" + serial + ";', ';') where itemType = 0;";
+                db.execSQL(sql);
             }
         }
 
@@ -774,35 +740,29 @@
                     addWorkspacesTable(db, false);
                 }
                 case 13: {
-                    db.beginTransaction();
-                    try {
+                    try (SQLiteTransaction t = new SQLiteTransaction(db)) {
                         // Insert new column for holding widget provider name
                         db.execSQL("ALTER TABLE favorites " +
                                 "ADD COLUMN appWidgetProvider TEXT;");
-                        db.setTransactionSuccessful();
+                        t.commit();
                     } catch (SQLException ex) {
                         Log.e(TAG, ex.getMessage(), ex);
                         // Old version remains, which means we wipe old data
                         break;
-                    } finally {
-                        db.endTransaction();
                     }
                 }
                 case 14: {
-                    db.beginTransaction();
-                    try {
+                    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;");
-                        db.setTransactionSuccessful();
+                        t.commit();
                     } catch (SQLException ex) {
                         Log.e(TAG, ex.getMessage(), ex);
                         // Old version remains, which means we wipe old data
                         break;
-                    } finally {
-                        db.endTransaction();
                     }
                 }
                 case 15: {
@@ -870,29 +830,25 @@
 
         @Override
         public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            if (oldVersion == 28 && newVersion == 27) {
-                // TODO: remove this check. This is only applicable for internal development/testing
-                // and for any released version of Launcher.
-                return;
+            try {
+                DbDowngradeHelper.parse(mContext.getFileStreamPath(DOWNGRADE_SCHEMA_FILE))
+                        .onDowngrade(db, oldVersion, newVersion);
+            } catch (Exception e) {
+                Log.d(TAG, "Unable to downgrade from: " + oldVersion + " to " + newVersion +
+                        ". Wiping databse.", e);
+                createEmptyDB(db);
             }
-            // This shouldn't happen -- throw our hands up in the air and start over.
-            Log.w(TAG, "Database version downgrade from: " + oldVersion + " to " + newVersion +
-                    ". Wiping databse.");
-            createEmptyDB(db);
         }
 
         /**
          * Clears all the data for a fresh start.
          */
         public void createEmptyDB(SQLiteDatabase db) {
-            db.beginTransaction();
-            try {
+            try (SQLiteTransaction t = new SQLiteTransaction(db)) {
                 db.execSQL("DROP TABLE IF EXISTS " + Favorites.TABLE_NAME);
                 db.execSQL("DROP TABLE IF EXISTS " + WorkspaceScreens.TABLE_NAME);
                 onCreate(db);
-                db.setTransactionSuccessful();
-            } finally {
-                db.endTransaction();
+                t.commit();
             }
         }
 
@@ -900,40 +856,39 @@
          * Removes widgets which are registered to the Launcher's host, but are not present
          * in our model.
          */
+        @TargetApi(Build.VERSION_CODES.O)
         public void removeGhostWidgets(SQLiteDatabase db) {
             // Get all existing widget ids.
             final AppWidgetHost host = newLauncherWidgetHost();
             final int[] allWidgets;
             try {
-                Method getter = AppWidgetHost.class.getDeclaredMethod("getAppWidgetIds");
-                getter.setAccessible(true);
-                allWidgets = (int[]) getter.invoke(host);
-            } catch (Exception e) {
+                // Although the method was defined in O, it has existed since the beginning of time,
+                // so it might work on older platforms as well.
+                allWidgets = host.getAppWidgetIds();
+            } catch (IncompatibleClassChangeError e) {
                 Log.e(TAG, "getAppWidgetIds not supported", e);
                 return;
             }
-            try {
-                Cursor c = db.query(Favorites.TABLE_NAME,
-                        new String[] {Favorites.APPWIDGET_ID },
-                        "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null, null, null);
-                HashSet<Integer> validWidgets = new HashSet<>();
+            final HashSet<Integer> validWidgets = new HashSet<>();
+            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));
                 }
-                c.close();
-
-                for (int widgetId : allWidgets) {
-                    if (!validWidgets.contains(widgetId)) {
-                        try {
-                            FileLog.d(TAG, "Deleting invalid widget " + widgetId);
-                            host.deleteAppWidgetId(widgetId);
-                        } catch (RuntimeException e) {
-                            // Ignore
-                        }
-                    }
-                }
             } catch (SQLException ex) {
                 Log.w(TAG, "Error getting widgets list", ex);
+                return;
+            }
+            for (int widgetId : allWidgets) {
+                if (!validWidgets.contains(widgetId)) {
+                    try {
+                        FileLog.d(TAG, "Deleting invalid widget " + widgetId);
+                        host.deleteAppWidgetId(widgetId);
+                    } catch (RuntimeException e) {
+                        // Ignore
+                    }
+                }
             }
         }
 
@@ -942,22 +897,16 @@
          * launcher activity target with {@link Favorites#ITEM_TYPE_APPLICATION}.
          */
         @Thunk void convertShortcutsToLauncherActivities(SQLiteDatabase db) {
-            db.beginTransaction();
-            Cursor c = null;
-            SQLiteStatement updateStmt = null;
-
-            try {
-                // Only consider the primary user as other users can't have a shortcut.
-                long userSerial = getDefaultUserSerial();
-                c = db.query(Favorites.TABLE_NAME, new String[] {
-                        Favorites._ID,
-                        Favorites.INTENT,
-                    }, "itemType=" + Favorites.ITEM_TYPE_SHORTCUT + " AND profileId=" + userSerial,
-                    null, null, null, null);
-
-                updateStmt = db.compileStatement("UPDATE favorites SET itemType="
-                        + Favorites.ITEM_TYPE_APPLICATION + " WHERE _id=?");
-
+            try (SQLiteTransaction t = new SQLiteTransaction(db);
+                 // Only consider the primary user as other users can't have a shortcut.
+                 Cursor c = db.query(Favorites.TABLE_NAME,
+                         new String[] { Favorites._ID, Favorites.INTENT},
+                         "itemType=" + Favorites.ITEM_TYPE_SHORTCUT +
+                                 " AND profileId=" + getDefaultUserSerial(),
+                         null, null, null, null);
+                 SQLiteStatement updateStmt = db.compileStatement("UPDATE favorites SET itemType="
+                         + Favorites.ITEM_TYPE_APPLICATION + " WHERE _id=?")
+            ) {
                 final int idIndex = c.getColumnIndexOrThrow(Favorites._ID);
                 final int intentIndex = c.getColumnIndexOrThrow(Favorites.INTENT);
 
@@ -979,17 +928,9 @@
                     updateStmt.bindLong(1, id);
                     updateStmt.executeUpdateDelete();
                 }
-                db.setTransactionSuccessful();
+                t.commit();
             } catch (SQLException ex) {
                 Log.w(TAG, "Error deduping shortcuts", ex);
-            } finally {
-                db.endTransaction();
-                if (c != null) {
-                    c.close();
-                }
-                if (updateStmt != null) {
-                    updateStmt.close();
-                }
             }
         }
 
@@ -997,26 +938,17 @@
          * Recreates workspace table and migrates data to the new table.
          */
         public boolean recreateWorkspaceTable(SQLiteDatabase db) {
-            db.beginTransaction();
-            try {
-                Cursor c = db.query(WorkspaceScreens.TABLE_NAME,
+            try (SQLiteTransaction t = new SQLiteTransaction(db)) {
+                final ArrayList<Long> sortedIDs;
+
+                try (Cursor c = db.query(WorkspaceScreens.TABLE_NAME,
                         new String[] {LauncherSettings.WorkspaceScreens._ID},
                         null, null, null, null,
-                        LauncherSettings.WorkspaceScreens.SCREEN_RANK);
-                ArrayList<Long> sortedIDs = new ArrayList<Long>();
-                long maxId = 0;
-                try {
-                    while (c.moveToNext()) {
-                        Long id = c.getLong(0);
-                        if (!sortedIDs.contains(id)) {
-                            sortedIDs.add(id);
-                            maxId = Math.max(maxId, id);
-                        }
-                    }
-                } finally {
-                    c.close();
+                        LauncherSettings.WorkspaceScreens.SCREEN_RANK)) {
+                    // Use LinkedHashSet so that ordering is preserved
+                    sortedIDs = new ArrayList<>(
+                            LauncherDbUtils.iterateCursor(c, 0, new LinkedHashSet<Long>()));
                 }
-
                 db.execSQL("DROP TABLE IF EXISTS " + WorkspaceScreens.TABLE_NAME);
                 addWorkspacesTable(db, false);
 
@@ -1029,21 +961,18 @@
                     addModifiedTime(values);
                     db.insertOrThrow(WorkspaceScreens.TABLE_NAME, null, values);
                 }
-                db.setTransactionSuccessful();
-                mMaxScreenId = maxId;
+                t.commit();
+                mMaxScreenId = sortedIDs.isEmpty() ? 0 : Collections.max(sortedIDs);
             } catch (SQLException ex) {
                 // Old version remains, which means we wipe old data
                 Log.e(TAG, ex.getMessage(), ex);
                 return false;
-            } finally {
-                db.endTransaction();
             }
             return true;
         }
 
         @Thunk boolean updateFolderItemsRank(SQLiteDatabase db, boolean addRankColumn) {
-            db.beginTransaction();
-            try {
+            try (SQLiteTransaction t = new SQLiteTransaction(db)) {
                 if (addRankColumn) {
                     // Insert new column for holding rank
                     db.execSQL("ALTER TABLE favorites ADD COLUMN rank INTEGER NOT NULL DEFAULT 0;");
@@ -1062,13 +991,11 @@
                 }
 
                 c.close();
-                db.setTransactionSuccessful();
+                t.commit();
             } catch (SQLException ex) {
                 // Old version remains, which means we wipe old data
                 Log.e(TAG, ex.getMessage(), ex);
                 return false;
-            } finally {
-                db.endTransaction();
             }
             return true;
         }
@@ -1078,16 +1005,13 @@
         }
 
         private boolean addIntegerColumn(SQLiteDatabase db, String columnName, long defaultValue) {
-            db.beginTransaction();
-            try {
+            try (SQLiteTransaction t = new SQLiteTransaction(db)) {
                 db.execSQL("ALTER TABLE favorites ADD COLUMN "
                         + columnName + " INTEGER NOT NULL DEFAULT " + defaultValue + ";");
-                db.setTransactionSuccessful();
+                t.commit();
             } catch (SQLException ex) {
                 Log.e(TAG, ex.getMessage(), ex);
                 return false;
-            } finally {
-                db.endTransaction();
             }
             return true;
         }
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index b25b256..87f62eb 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -22,8 +22,6 @@
 import android.os.Bundle;
 import android.provider.BaseColumns;
 
-import com.android.launcher3.config.ProviderConfig;
-
 /**
  * Settings related utilities.
  */
@@ -101,7 +99,7 @@
          * The content:// style URL for this table
          */
         public static final Uri CONTENT_URI = Uri.parse("content://" +
-                ProviderConfig.AUTHORITY + "/" + TABLE_NAME);
+                LauncherProvider.AUTHORITY + "/" + TABLE_NAME);
 
         /**
          * The rank of this screen -- ie. how it is ordered relative to the other screens.
@@ -121,7 +119,7 @@
          * The content:// style URL for this table
          */
         public static final Uri CONTENT_URI = Uri.parse("content://" +
-                ProviderConfig.AUTHORITY + "/" + TABLE_NAME);
+                LauncherProvider.AUTHORITY + "/" + TABLE_NAME);
 
         /**
          * The content:// style URL for a given row, identified by its id.
@@ -131,7 +129,7 @@
          * @return The unique content URL for the specified row.
          */
         public static Uri getContentUri(long id) {
-            return Uri.parse("content://" + ProviderConfig.AUTHORITY +
+            return Uri.parse("content://" + LauncherProvider.AUTHORITY +
                     "/" + TABLE_NAME + "/" + id);
         }
 
@@ -155,6 +153,18 @@
             }
         }
 
+        static final String itemTypeToString(int type) {
+            switch(type) {
+                case ITEM_TYPE_APPLICATION: return "APP";
+                case ITEM_TYPE_SHORTCUT: return "SHORTCUT";
+                case ITEM_TYPE_FOLDER: return "FOLDER";
+                case ITEM_TYPE_APPWIDGET: return "WIDGET";
+                case ITEM_TYPE_CUSTOM_APPWIDGET: return "CUSTOMWIDGET";
+                case ITEM_TYPE_DEEP_SHORTCUT: return "DEEPSHORTCUT";
+                default: return String.valueOf(type);
+            }
+        }
+
         /**
          * The screen holding the favorite (if container is CONTAINER_DESKTOP)
          * <P>Type: INTEGER</P>
@@ -280,7 +290,7 @@
     public static final class Settings {
 
         public static final Uri CONTENT_URI = Uri.parse("content://" +
-                ProviderConfig.AUTHORITY + "/settings");
+                LauncherProvider.AUTHORITY + "/settings");
 
         public static final String METHOD_CLEAR_EMPTY_DB_FLAG = "clear_empty_db_flag";
         public static final String METHOD_WAS_EMPTY_DB_CREATED = "get_empty_db_flag";
diff --git a/src/com/android/launcher3/LauncherStateTransitionAnimation.java b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
index 39c466d..85467e0 100644
--- a/src/com/android/launcher3/LauncherStateTransitionAnimation.java
+++ b/src/com/android/launcher3/LauncherStateTransitionAnimation.java
@@ -31,8 +31,8 @@
 import com.android.launcher3.allapps.AllAppsContainerView;
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.anim.AnimationLayerSet;
+import com.android.launcher3.anim.CircleRevealOutlineProvider;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.util.CircleRevealOutlineProvider;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.widget.WidgetsContainerView;
 
diff --git a/src/com/android/launcher3/MainThreadExecutor.java b/src/com/android/launcher3/MainThreadExecutor.java
index 4ca0a59..5094682 100644
--- a/src/com/android/launcher3/MainThreadExecutor.java
+++ b/src/com/android/launcher3/MainThreadExecutor.java
@@ -18,14 +18,14 @@
 
 import android.os.Looper;
 
-import com.android.launcher3.util.LooperExecuter;
+import com.android.launcher3.util.LooperExecutor;
 
 /**
  * An executor service that executes its tasks on the main thread.
  *
  * Shutting down this executor is not supported.
  */
-public class MainThreadExecutor extends LooperExecuter {
+public class MainThreadExecutor extends LooperExecutor {
 
     public MainThreadExecutor() {
         super(Looper.getMainLooper());
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index fb6a611..255677a 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -50,6 +50,7 @@
 import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.pageindicators.PageIndicator;
 import com.android.launcher3.util.LauncherEdgeEffect;
+import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 
 import java.util.ArrayList;
@@ -226,11 +227,10 @@
         mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * density);
         setOnHierarchyChangeListener(this);
         setWillNotDraw(false);
-    }
 
-    protected void setEdgeGlowColor(int color) {
-        mEdgeGlowLeft.setColor(color);
-        mEdgeGlowRight.setColor(color);
+        int edgeEffectColor = Themes.getAttrColor(getContext(), android.R.attr.colorEdgeEffect);
+        mEdgeGlowLeft.setColor(edgeEffectColor);
+        mEdgeGlowRight.setColor(edgeEffectColor);
     }
 
     protected void setDefaultInterpolator(Interpolator interpolator) {
@@ -1599,7 +1599,7 @@
                 mTotalMotionX += Math.abs(mLastMotionX + mLastMotionXRemainder - x);
 
                 boolean isFling = mTotalMotionX > MIN_LENGTH_FOR_FLING &&
-                        Math.abs(velocityX) > mFlingThresholdVelocity;
+                        shouldFlingForVelocity(velocityX);
 
                 if (!mFreeScroll) {
                     // In the case that the page is moved far to one direction and then is flung
@@ -1705,6 +1705,10 @@
         return true;
     }
 
+    protected boolean shouldFlingForVelocity(int velocityX) {
+        return Math.abs(velocityX) > mFlingThresholdVelocity;
+    }
+
     private void resetTouchState() {
         releaseVelocityTracker();
         endReordering();
diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/PendingAppWidgetHostView.java
index b163464..de424ab 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/PendingAppWidgetHostView.java
@@ -80,10 +80,13 @@
         updateAppWidget(null);
         setOnClickListener(mLauncher);
 
-        // Load icon
-        PackageItemInfo item = new PackageItemInfo(info.providerName.getPackageName());
-        item.user = info.user;
-        cache.updateIconInBackground(this, item);
+        if (info.pendingItemInfo == null) {
+            info.pendingItemInfo = new PackageItemInfo(info.providerName.getPackageName());
+            info.pendingItemInfo.user = info.user;
+            cache.updateIconInBackground(this, info.pendingItemInfo);
+        } else {
+            reapplyItemInfo(info.pendingItemInfo);
+        }
     }
 
     @Override
diff --git a/src/com/android/launcher3/PinchAnimationManager.java b/src/com/android/launcher3/PinchAnimationManager.java
index f8196e5..c3d3bb3 100644
--- a/src/com/android/launcher3/PinchAnimationManager.java
+++ b/src/com/android/launcher3/PinchAnimationManager.java
@@ -56,11 +56,10 @@
     private static final LinearInterpolator INTERPOLATOR = new LinearInterpolator();
 
     private static final int INDEX_HOTSEAT = 0;
-    private static final int INDEX_QSB = 1;
-    private static final int INDEX_OVERVIEW_PANEL_BUTTONS = 2;
-    private static final int INDEX_SCRIM = 3;
+    private static final int INDEX_OVERVIEW_PANEL_BUTTONS = 1;
+    private static final int INDEX_SCRIM = 2;
 
-    private final Animator[] mAnimators = new Animator[4];
+    private final Animator[] mAnimators = new Animator[3];
 
     private Launcher mLauncher;
     private Workspace mWorkspace;
@@ -196,8 +195,6 @@
     private void animateHotseatAndQsb(boolean show) {
         startAnimator(INDEX_HOTSEAT,
                 mWorkspace.createHotseatAlphaAnimator(show ? 1 : 0), THRESHOLD_ANIM_DURATION);
-        startAnimator(INDEX_QSB, mWorkspace.mQsbAlphaController.animateAlphaAtIndex(
-                show ? 1 : 0, Workspace.QSB_ALPHA_INDEX_STATE_CHANGE), THRESHOLD_ANIM_DURATION);
     }
 
     private void animateOverviewPanelButtons(boolean show) {
diff --git a/src/com/android/launcher3/PromiseAppInfo.java b/src/com/android/launcher3/PromiseAppInfo.java
new file mode 100644
index 0000000..07515d0
--- /dev/null
+++ b/src/com/android/launcher3/PromiseAppInfo.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import android.content.Intent;
+import android.support.annotation.NonNull;
+
+import com.android.launcher3.compat.PackageInstallerCompat;
+import com.android.launcher3.util.PackageManagerHelper;
+
+public class PromiseAppInfo extends AppInfo {
+
+    public int level = 0;
+
+    public PromiseAppInfo(@NonNull PackageInstallerCompat.PackageInstallInfo installInfo) {
+        componentName = installInfo.componentName;
+        intent = new Intent(Intent.ACTION_MAIN)
+                .addCategory(Intent.CATEGORY_LAUNCHER)
+                .setComponent(componentName)
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+    }
+
+    @Override
+    public ShortcutInfo makeShortcut() {
+        ShortcutInfo shortcut = new ShortcutInfo(this);
+        shortcut.setInstallProgress(level);
+        // We need to update the component name when the apk is installed
+        shortcut.status |= ShortcutInfo.FLAG_AUTOINSTALL_ICON;
+        // Since the user is manually placing it on homescreen, it should not be auto-removed later
+        shortcut.status |= ShortcutInfo.FLAG_RESTORE_STARTED;
+        return shortcut;
+    }
+
+    public Intent getMarketIntent() {
+        return PackageManagerHelper.getMarketIntent(componentName.getPackageName());
+    }
+}
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index 61bcc17..8caba75 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -67,18 +67,19 @@
         SessionInfo info = intent.getParcelableExtra(PackageInstaller.EXTRA_SESSION);
         UserHandle user = intent.getParcelableExtra(Intent.EXTRA_USER);
 
-        if (TextUtils.isEmpty(info.getAppPackageName()) ||
-                info.getInstallReason() != PackageManager.INSTALL_REASON_USER) {
-            return;
+        if (Process.myUserHandle().equals(user)) {
+            if (TextUtils.isEmpty(info.getAppPackageName()) ||
+                    info.getInstallReason() != PackageManager.INSTALL_REASON_USER) {
+                return;
+            }
         }
 
-        if (!Process.myUserHandle().equals(user)) {
-            // Managed profile is handled using ManagedProfileHeuristic
-            return;
-        }
+        queueAppIconAddition(context, info.getAppPackageName(), user);
+    }
 
+    public static void queueAppIconAddition(Context context, String packageName, UserHandle user) {
         List<LauncherActivityInfo> activities = LauncherAppsCompat.getInstance(context)
-                .getActivityList(info.getAppPackageName(), user);
+                .getActivityList(packageName, user);
         if (activities == null || activities.isEmpty()) {
             // no activity found
             return;
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index 6f0417c..f0d9367 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -45,10 +45,10 @@
      * be present along with {@link #FLAG_RESTORED_ICON}, and is set during default layout
      * parsing.
      */
-    public static final int FLAG_AUTOINTALL_ICON = 2; //0B10;
+    public static final int FLAG_AUTOINSTALL_ICON = 2; //0B10;
 
     /**
-     * The icon is being installed. If {@link #FLAG_RESTORED_ICON} or {@link #FLAG_AUTOINTALL_ICON}
+     * The icon is being installed. If {@link #FLAG_RESTORED_ICON} or {@link #FLAG_AUTOINSTALL_ICON}
      * is set, then the icon is either being installed or is in a broken state.
      */
     public static final int FLAG_INSTALL_SESSION_ACTIVE = 4; // 0B100;
@@ -185,7 +185,7 @@
 
 
     public final boolean isPromise() {
-        return hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINTALL_ICON);
+        return hasStatusFlag(FLAG_RESTORED_ICON | FLAG_AUTOINSTALL_ICON);
     }
 
     public int getInstallProgress() {
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
index 0fac29f..45c14d6 100644
--- a/src/com/android/launcher3/UninstallDropTarget.java
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -28,10 +28,13 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
+        setupUi();
+    }
+
+    protected void setupUi() {
         // Get the hover color
         mHoverColor = getResources().getColor(R.color.uninstall_target_hover_tint);
-
-        setDrawable(R.drawable.ic_uninstall_launcher);
+        setDrawable(R.drawable.ic_uninstall_shadow);
     }
 
     @Override
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index b5c44bb..c2987f8 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -28,6 +28,7 @@
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Matrix;
 import android.graphics.Paint;
@@ -51,7 +52,7 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 
 import java.io.ByteArrayOutputStream;
 import java.io.Closeable;
@@ -110,6 +111,7 @@
     public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET";
 
     public static final int COLOR_EXTRACTION_JOB_ID = 1;
+    public static final int WALLPAPER_COMPAT_JOB_ID = 2;
 
     // These values are same as that in {@link AsyncTask}.
     private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
@@ -260,7 +262,7 @@
         return scale;
     }
 
-    static boolean isSystemApp(Context context, Intent intent) {
+    public static boolean isSystemApp(Context context, Intent intent) {
         PackageManager pm = context.getPackageManager();
         ComponentName cn = intent.getComponent();
         String packageName = null;
@@ -550,6 +552,11 @@
                 LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE);
     }
 
+    public static SharedPreferences getDevicePrefs(Context context) {
+        return context.getSharedPreferences(
+                LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE);
+    }
+
     public static boolean isPowerSaverOn(Context context) {
         PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         return powerManager.isPowerSaveMode();
@@ -571,7 +578,7 @@
             try {
                 c.close();
             } catch (IOException e) {
-                if (ProviderConfig.IS_DOGFOOD_BUILD) {
+                if (FeatureFlags.IS_DOGFOOD_BUILD) {
                     Log.d(TAG, "Error closing", e);
                 }
             }
@@ -647,4 +654,28 @@
         hashSet.add(elem);
         return hashSet;
     }
+
+    /**
+     * @return creates a new alpha mask bitmap out of an existing bitmap
+     */
+    public static Bitmap convertToAlphaMask(Bitmap b, int applyAlpha) {
+        Bitmap a = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ALPHA_8);
+        Canvas c = new Canvas(a);
+        Paint paint = new Paint();
+        paint.setAlpha(applyAlpha);
+        c.drawBitmap(b, 0f, 0f, paint);
+        return a;
+    }
+
+    /**
+     * @return a new white 1x1 bitmap with ALPHA_8
+     */
+    public static Bitmap createOnePixBitmap() {
+        Bitmap a = Bitmap.createBitmap(1, 1, Bitmap.Config.ALPHA_8);
+        Canvas c = new Canvas(a);
+        Paint paint = new Paint();
+        paint.setColor(Color.WHITE);
+        c.drawPaint(paint);
+        return a;
+    }
 }
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index c525cd4..f66995f 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -27,7 +27,6 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.support.annotation.Nullable;
-import android.support.v4.graphics.ColorUtils;
 import android.util.Log;
 import android.util.LongSparseArray;
 
@@ -388,10 +387,10 @@
             drawable.setBounds(x, 0, x + previewWidth, previewHeight);
             drawable.draw(c);
         } else {
-            final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-            RectF boxRect = drawBoxWithShadow(c, p, previewWidth, previewHeight);
+            RectF boxRect = drawBoxWithShadow(c, previewWidth, previewHeight);
 
             // Draw horizontal and vertical lines to represent individual columns.
+            final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
             p.setStyle(Paint.Style.STROKE);
             p.setStrokeWidth(mContext.getResources()
                     .getDimension(R.dimen.widget_preview_cell_divider_width));
@@ -431,7 +430,7 @@
         return preview;
     }
 
-    private RectF drawBoxWithShadow(Canvas c, Paint p, int width, int height) {
+    private RectF drawBoxWithShadow(Canvas c, int width, int height) {
         Resources res = mContext.getResources();
         float shadowBlur = res.getDimension(R.dimen.widget_preview_shadow_blur);
         float keyShadowDistance = res.getDimension(R.dimen.widget_preview_key_shadow_distance);
@@ -439,19 +438,7 @@
 
         RectF bounds = new RectF(shadowBlur, shadowBlur,
                 width - shadowBlur, height - shadowBlur - keyShadowDistance);
-        p.setColor(Color.WHITE);
-
-        // Key shadow
-        p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
-                ShadowGenerator.KEY_SHADOW_ALPHA << 24);
-        c.drawRoundRect(bounds, corner, corner, p);
-
-        // Ambient shadow
-        p.setShadowLayer(shadowBlur, 0, 0,
-                ColorUtils.setAlphaComponent(Color.BLACK, ShadowGenerator.AMBIENT_SHADOW_ALPHA));
-        c.drawRoundRect(bounds, corner, corner, p);
-
-        p.clearShadowLayer();
+        ShadowGenerator.drawShadow(c, bounds, Color.WHITE, shadowBlur, keyShadowDistance, corner);
         return bounds;
     }
 
@@ -478,8 +465,7 @@
             c.setBitmap(preview);
             c.drawColor(0, PorterDuff.Mode.CLEAR);
         }
-        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-        RectF boxRect = drawBoxWithShadow(c, p, size, size);
+        RectF boxRect = drawBoxWithShadow(c, size, size);
 
         Bitmap icon = LauncherIcons.createScaledBitmapWithoutShadow(
                 mutateOnMainThread(info.getFullResIcon(mIconCache)), mContext, Build.VERSION_CODES.O);
@@ -487,7 +473,8 @@
 
         boxRect.set(0, 0, iconSize, iconSize);
         boxRect.offset(padding, padding);
-        c.drawBitmap(icon, src, boxRect, p);
+        c.drawBitmap(icon, src, boxRect,
+                new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
         c.setBitmap(null);
         return preview;
     }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 36f2880..ce92c8e 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -43,6 +43,7 @@
 import android.util.Log;
 import android.util.Property;
 import android.util.SparseArray;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewDebug;
@@ -64,7 +65,6 @@
 import com.android.launcher3.badge.FolderBadgeInfo;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.dragndrop.DragOptions;
@@ -80,7 +80,6 @@
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
 import com.android.launcher3.util.ItemInfoMatcher;
 import com.android.launcher3.util.LongArrayMap;
-import com.android.launcher3.util.MultiStateAlphaController;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.util.VerticalFlingDetector;
@@ -234,14 +233,6 @@
      */
     private float[] mHotseatAlpha = new float[] {1, 1, 1};
 
-    public static final int QSB_ALPHA_INDEX_STATE_CHANGE = 0;
-    public static final int QSB_ALPHA_INDEX_Y_TRANSLATION = 1;
-    public static final int QSB_ALPHA_INDEX_PAGE_SCROLL = 2;
-    public static final int QSB_ALPHA_INDEX_OVERLAY_SCROLL = 3;
-
-
-    MultiStateAlphaController mQsbAlphaController;
-
     @ViewDebug.ExportedProperty(category = "launcher")
     private State mState = State.NORMAL;
     private boolean mIsSwitchingState = false;
@@ -323,7 +314,6 @@
     private WorkspaceStateTransitionAnimation mStateTransitionAnimation;
 
     private AccessibilityDelegate mPagesAccessibilityDelegate;
-    private OnStateChangeListener mOnStateChangeListener;
 
     /**
      * Used to inflate the Workspace from XML.
@@ -378,10 +368,6 @@
         }
     }
 
-    public void setOnStateChangeListener(OnStateChangeListener listener) {
-        mOnStateChangeListener = listener;
-    }
-
     /**
      * Estimates the size of an item using spans: hSpan, vSpan.
      *
@@ -451,7 +437,7 @@
         mLauncher.lockScreenOrientation();
         mLauncher.onInteractionBegin();
         // Prevent any Un/InstallShortcutReceivers from updating the db while we are dragging
-        InstallShortcutReceiver.enableInstallQueue();
+        InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_DRAG_AND_DROP);
 
         // Do not add a new page if it is a accessible drag which was not started by the workspace.
         // We do not support accessibility drag from other sources and instead provide a direct
@@ -504,7 +490,8 @@
         mLauncher.unlockScreenOrientation(false);
 
         // Re-enable any Un/InstallShortcutReceiver and now process any queued items
-        InstallShortcutReceiver.disableAndFlushInstallQueue(getContext());
+        InstallShortcutReceiver.disableAndFlushInstallQueue(
+                InstallShortcutReceiver.FLAG_DRAG_AND_DROP, getContext());
 
         mOutlineProvider = null;
         mDragInfo = null;
@@ -529,15 +516,12 @@
 
         // Set the wallpaper dimensions when Launcher starts up
         setWallpaperDimension();
-
-        setEdgeGlowColor(getResources().getColor(R.color.workspace_edge_effect_color));
     }
 
     @Override
     public void initParentViews(View parent) {
         super.initParentViews(parent);
         mPageIndicator.setAccessibilityDelegate(new OverviewAccessibilityDelegate());
-        mQsbAlphaController = new MultiStateAlphaController(mLauncher.getQsbContainer(), 4);
     }
 
     private int getDefaultPage() {
@@ -577,11 +561,6 @@
         return mTouchState != TOUCH_STATE_REST;
     }
 
-    private int getEmbeddedQsbId() {
-        return mLauncher.getDeviceProfile().isVerticalBarLayout()
-                ? R.id.qsb_container : R.id.workspace_blocked_row;
-    }
-
     /**
      * Initializes and binds the first page
      * @param qsb an existing qsb to recycle or null.
@@ -623,41 +602,17 @@
         if (qsb == null) {
             // In transposed layout, we add the QSB in the Grid. As workspace does not touch the
             // edges, we do not need a full width QSB.
-            qsb = mLauncher.getLayoutInflater().inflate(
-                    mLauncher.getDeviceProfile().isVerticalBarLayout()
-                            ? R.layout.qsb_container : R.layout.qsb_blocker_view,
-                    firstPage, false);
+            qsb = LayoutInflater.from(getContext())
+                    .inflate(R.layout.qsb_container,firstPage, false);
         }
 
         CellLayout.LayoutParams lp = new CellLayout.LayoutParams(0, 0, firstPage.getCountX(), 1);
         lp.canReorder = false;
-        if (!firstPage.addViewToCellLayout(qsb, 0, getEmbeddedQsbId(), lp, true)) {
+        if (!firstPage.addViewToCellLayout(qsb, 0, R.id.qsb_container, lp, true)) {
             Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout");
         }
     }
 
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
-
-        // Update the QSB to match the cell height. This is treating the QSB essentially as a child
-        // of workspace despite that it's not a true child.
-        // Note that it relies on the strict ordering of measuring the workspace before the QSB
-        // at the dragLayer level.
-        // Only measure the QSB when the view is enabled
-        if (FeatureFlags.QSB_ON_FIRST_SCREEN && getChildCount() > 0) {
-            CellLayout firstPage = (CellLayout) getChildAt(0);
-            int cellHeight = firstPage.getCellHeight();
-
-            View qsbContainer = mLauncher.getQsbContainer();
-            ViewGroup.LayoutParams lp = qsbContainer.getLayoutParams();
-            if (cellHeight > 0 && lp.height != cellHeight) {
-                lp.height = cellHeight;
-                qsbContainer.setLayoutParams(lp);
-            }
-        }
-    }
-
     public void removeAllWorkspaceScreens() {
         // Disable all layout transitions before removing all pages to ensure that we don't get the
         // transition animations competing with us changing the scroll when we add pages or the
@@ -671,7 +626,7 @@
         }
 
         // Recycle the QSB widget
-        View qsb = findViewById(getEmbeddedQsbId());
+        View qsb = findViewById(R.id.qsb_container);
         if (qsb != null) {
             ((ViewGroup) qsb.getParent()).removeView(qsb);
         }
@@ -709,7 +664,7 @@
 
         // Inflate the cell layout, but do not add it automatically so that we can get the newly
         // created CellLayout.
-        CellLayout newScreen = (CellLayout) mLauncher.getLayoutInflater().inflate(
+        CellLayout newScreen = (CellLayout) LayoutInflater.from(getContext()).inflate(
                         R.layout.workspace_screen, this, false /* attachToRoot */);
         newScreen.setOnLongClickListener(mLongClickListener);
         newScreen.setOnClickListener(mLauncher);
@@ -727,7 +682,7 @@
 
     public void createCustomContentContainer() {
         CellLayout customScreen = (CellLayout)
-                mLauncher.getLayoutInflater().inflate(R.layout.workspace_screen, this, false);
+                LayoutInflater.from(getContext()).inflate(R.layout.workspace_screen, this, false);
         customScreen.disableDragTarget();
         customScreen.disableJailContent();
 
@@ -1407,17 +1362,9 @@
         super.scrollTo(x, y);
     }
 
-    private void onWorkspaceOverallScrollChanged() {
-        if (!mIgnoreQsbScroll) {
-            mLauncher.getQsbContainer().setTranslationX(
-                    mOverlayTranslation + mFirstPageScrollX - getScrollX());
-        }
-    }
-
     @Override
     protected void onScrollChanged(int l, int t, int oldl, int oldt) {
         super.onScrollChanged(l, t, oldl, oldt);
-        onWorkspaceOverallScrollChanged();
 
         // Update the page indicator progress.
         boolean isTransitioning = mIsSwitchingState
@@ -1465,6 +1412,13 @@
         }
     }
 
+    @Override
+    protected boolean shouldFlingForVelocity(int velocityX) {
+        // When the overlay is moving, the fling or settle transition is controlled by the overlay.
+        return Float.compare(mOverlayTranslation, 0) == 0 &&
+                super.shouldFlingForVelocity(velocityX);
+    }
+
     private final Interpolator mAlphaInterpolator = new DecelerateInterpolator(3f);
 
     /**
@@ -1491,9 +1445,6 @@
         // device I've tried, translating the launcher causes things to get quite laggy.
         setWorkspaceTranslationAndAlpha(Direction.X, transX, alpha);
         setHotseatTranslationAndAlpha(Direction.X, transX, alpha);
-        onWorkspaceOverallScrollChanged();
-
-        mQsbAlphaController.setAlphaAtIndex(alpha, QSB_ALPHA_INDEX_OVERLAY_SCROLL);
     }
 
     /**
@@ -1503,9 +1454,6 @@
      */
     public void setWorkspaceYTranslationAndAlpha(float translation, float alpha) {
         setWorkspaceTranslationAndAlpha(Direction.Y, translation, alpha);
-
-        mLauncher.getQsbContainer().setTranslationY(translation);
-        mQsbAlphaController.setAlphaAtIndex(alpha, QSB_ALPHA_INDEX_Y_TRANSLATION);
     }
 
     /**
@@ -1701,10 +1649,6 @@
                     float scrollProgress = getScrollProgress(screenCenter, child, i);
                     float alpha = 1 - Math.abs(scrollProgress);
                     child.getShortcutsAndWidgets().setAlpha(alpha);
-
-                    if (isQsbContainerPage(i)) {
-                        mQsbAlphaController.setAlphaAtIndex(alpha, QSB_ALPHA_INDEX_PAGE_SCROLL);
-                    }
                 }
             }
         }
@@ -1799,7 +1743,6 @@
         }
         super.onLayout(changed, left, top, right, bottom);
         mFirstPageScrollX = getScrollForPage(0);
-        onWorkspaceOverallScrollChanged();
 
         final LayoutTransition transition = getLayoutTransition();
         // If the transition is running defer updating max scroll, as some empty pages could
@@ -1821,7 +1764,6 @@
                         mIgnoreQsbScroll = false;
                         transition.removeTransitionListener(this);
                         mFirstPageScrollX = getScrollForPage(0);
-                        onWorkspaceOverallScrollChanged();
                     }
                 }
             });
@@ -2064,10 +2006,6 @@
             mLauncher.notifyWidgetProvidersChanged();
         }
 
-        if (mOnStateChangeListener != null) {
-            mOnStateChangeListener.prepareStateChange(toState, animated ? workspaceAnim : null);
-        }
-
         onPrepareStateTransition(mState.hasMultipleVisiblePages);
 
         StateTransitionListener listener = new StateTransitionListener();
@@ -2620,7 +2558,7 @@
                         CellLayout parentCell = getParentCellLayoutForView(cell);
                         if (parentCell != null) {
                             parentCell.removeView(cell);
-                        } else if (ProviderConfig.IS_DOGFOOD_BUILD) {
+                        } else if (FeatureFlags.IS_DOGFOOD_BUILD) {
                             throw new NullPointerException("mDragInfo.cell has null parent");
                         }
                         addInScreen(cell, container, screenId, mTargetCell[0], mTargetCell[1],
@@ -2953,7 +2891,7 @@
 
         ItemInfo item = d.dragInfo;
         if (item == null) {
-            if (ProviderConfig.IS_DOGFOOD_BUILD) {
+            if (FeatureFlags.IS_DOGFOOD_BUILD) {
                 throw new NullPointerException("DragObject has null info");
             }
             return;
@@ -3160,11 +3098,8 @@
             this.cellX = cellX;
             this.cellY = cellY;
 
-            DeviceProfile grid = mLauncher.getDeviceProfile();
             BubbleTextView cell = (BubbleTextView) layout.getChildAt(cellX, cellY);
-
-            bg.setup(getResources().getDisplayMetrics(), grid, null,
-                    cell.getMeasuredWidth(), cell.getPaddingTop());
+            bg.setup(mLauncher, null, cell.getMeasuredWidth(), cell.getPaddingTop());
 
             // The full preview background should appear behind the icon
             bg.isClipping = false;
@@ -3610,7 +3545,7 @@
                     mDragInfo.container, mDragInfo.screenId);
             if (cellLayout != null) {
                 cellLayout.onDropChild(mDragInfo.cell);
-            } else if (ProviderConfig.IS_DOGFOOD_BUILD) {
+            } else if (FeatureFlags.IS_DOGFOOD_BUILD) {
                 throw new RuntimeException("Invalid state: cellLayout == null in "
                         + "Workspace#onDropCompleted. Please file a bug. ");
             };
@@ -3636,7 +3571,7 @@
         CellLayout parentCell = getParentCellLayoutForView(v);
         if (parentCell != null) {
             parentCell.removeView(v);
-        } else if (ProviderConfig.IS_DOGFOOD_BUILD) {
+        } else if (FeatureFlags.IS_DOGFOOD_BUILD) {
             // When an app is uninstalled using the drop target, we wait until resume to remove
             // the icon. We also remove all the corresponding items from the workspace at
             // {@link Launcher#bindComponentsRemoved}. That call can come before or after
@@ -4227,20 +4162,6 @@
         }
     }
 
-    public interface OnStateChangeListener {
-
-        /**
-         * Called when the workspace state is changing.
-         * @param toState final state
-         * @param targetAnim animation which will be played during the transition or null.
-         */
-        void prepareStateChange(State toState, AnimatorSet targetAnim);
-    }
-
-    public static final boolean isQsbContainerPage(int pageNo) {
-        return pageNo == 0;
-    }
-
     private class StateTransitionListener extends AnimatorListenerAdapter
             implements AnimatorUpdateListener {
         @Override
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 482a2c9..32deaf2 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -355,27 +355,10 @@
                 cl.setBackgroundAlpha(finalBackgroundAlpha);
                 cl.setShortcutAndWidgetAlpha(finalAlpha);
             }
-
-            if (Workspace.isQsbContainerPage(i) &&
-                    states.stateIsNormal && mWorkspaceFadeInAdjacentScreens) {
-                if (animated) {
-                    Animator anim = mWorkspace.mQsbAlphaController
-                            .animateAlphaAtIndex(finalAlpha, Workspace.QSB_ALPHA_INDEX_PAGE_SCROLL);
-                    anim.setDuration(duration);
-                    anim.setInterpolator(mZoomInInterpolator);
-                    mStateAnimator.play(anim);
-                } else {
-                    mWorkspace.mQsbAlphaController.setAlphaAtIndex(
-                            finalAlpha, Workspace.QSB_ALPHA_INDEX_PAGE_SCROLL);
-                }
-            }
         }
 
         final ViewGroup overviewPanel = mLauncher.getOverviewPanel();
 
-        Animator qsbAlphaAnimation = mWorkspace.mQsbAlphaController
-                .animateAlphaAtIndex(finalQsbAlpha, Workspace.QSB_ALPHA_INDEX_STATE_CHANGE);
-
         if (animated) {
             Animator scale = LauncherAnimUtils.ofPropertyValuesHolder(mWorkspace,
                     new PropertyListBuilder().scale(mNewScale)
@@ -393,7 +376,6 @@
             // For animation optimization, we may need to provide the Launcher transition
             // with a set of views on which to force build and manage layers in certain scenarios.
             layerViews.addView(overviewPanel);
-            layerViews.addView(mLauncher.getQsbContainer());
             layerViews.addView(mLauncher.getHotseat());
             layerViews.addView(mWorkspace.getPageIndicator());
 
@@ -407,11 +389,9 @@
 
             overviewPanelAlpha.setDuration(duration);
             hotseatAlpha.setDuration(duration);
-            qsbAlphaAnimation.setDuration(duration);
 
             mStateAnimator.play(overviewPanelAlpha);
             mStateAnimator.play(hotseatAlpha);
-            mStateAnimator.play(qsbAlphaAnimation);
             mStateAnimator.addListener(new AnimatorListenerAdapter() {
                 boolean canceled = false;
                 @Override
@@ -439,7 +419,6 @@
             AlphaUpdateListener.updateVisibility(overviewPanel, accessibilityEnabled);
             mWorkspace.getPageIndicator().setShouldAutoHide(!states.stateIsSpringLoaded);
 
-            qsbAlphaAnimation.end();
             mWorkspace.createHotseatAlphaAnimator(finalHotseatAlpha).end();
             mWorkspace.updateCustomContentVisibility();
             mWorkspace.setScaleX(mNewScale);
diff --git a/src/com/android/launcher3/accessibility/FolderAccessibilityHelper.java b/src/com/android/launcher3/accessibility/FolderAccessibilityHelper.java
index d271f1d..9c23c19 100644
--- a/src/com/android/launcher3/accessibility/FolderAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/FolderAccessibilityHelper.java
@@ -17,8 +17,8 @@
 package com.android.launcher3.accessibility;
 
 import com.android.launcher3.CellLayout;
-import com.android.launcher3.folder.FolderPagedView;
 import com.android.launcher3.R;
+import com.android.launcher3.folder.FolderPagedView;
 
 /**
  * Implementation of {@link DragAndDropAccessibilityDelegate} to support DnD in a folder.
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 70e5781..3433533 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -18,7 +18,6 @@
 import com.android.launcher3.AppWidgetResizeFrame;
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.CellLayout;
-import com.android.launcher3.popup.PopupContainerWithArrow;
 import com.android.launcher3.DeleteDropTarget;
 import com.android.launcher3.DropTarget.DragObject;
 import com.android.launcher3.FolderInfo;
@@ -27,7 +26,6 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppWidgetHostView;
 import com.android.launcher3.LauncherAppWidgetInfo;
-import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.R;
@@ -37,6 +35,7 @@
 import com.android.launcher3.dragndrop.DragController.DragListener;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.folder.Folder;
+import com.android.launcher3.popup.PopupContainerWithArrow;
 import com.android.launcher3.shortcuts.DeepShortcutManager;
 import com.android.launcher3.util.Thunk;
 
diff --git a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
index 9a23aa8..e6f120f 100644
--- a/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
+++ b/src/com/android/launcher3/accessibility/WorkspaceAccessibilityHelper.java
@@ -27,9 +27,9 @@
 import com.android.launcher3.FolderInfo;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DragType;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.accessibility.LauncherAccessibilityDelegate.DragType;
 import com.android.launcher3.dragndrop.DragLayer;
 
 /**
diff --git a/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java b/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java
index c71bc31..54c5bd0 100644
--- a/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java
+++ b/src/com/android/launcher3/allapps/AllAppsBackgroundDrawable.java
@@ -25,6 +25,7 @@
 import android.graphics.drawable.Drawable;
 import android.view.Gravity;
 
+import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.R;
 
 /**
@@ -119,7 +120,8 @@
         int finalAlphaI = (int) (finalAlpha * 255f);
         if (getAlpha() != finalAlphaI) {
             mBackgroundAnim = cancelAnimator(mBackgroundAnim);
-            mBackgroundAnim = ObjectAnimator.ofInt(this, "alpha", finalAlphaI);
+            mBackgroundAnim = ObjectAnimator.ofInt(this, LauncherAnimUtils.DRAWABLE_ALPHA,
+                    finalAlphaI);
             mBackgroundAnim.setDuration(duration);
             mBackgroundAnim.start();
         }
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 2c7d156..c3df073 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -20,15 +20,10 @@
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.InsetDrawable;
-import android.support.annotation.NonNull;
-import android.support.annotation.Nullable;
+import android.support.v7.widget.LinearLayoutManager;
 import android.support.v7.widget.RecyclerView;
 import android.text.Selection;
-import android.text.Spannable;
-import android.text.SpannableString;
 import android.text.SpannableStringBuilder;
-import android.text.TextUtils;
-import android.text.method.TextKeyListener;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
@@ -42,25 +37,22 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.DragSource;
 import com.android.launcher3.DropTarget;
-import com.android.launcher3.ExtendedEditText;
 import com.android.launcher3.Insettable;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
+import com.android.launcher3.PromiseAppInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.SpringAnimationHandler;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.discovery.AppDiscoveryItem;
-import com.android.launcher3.discovery.AppDiscoveryUpdateState;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.folder.Folder;
-import com.android.launcher3.graphics.TintedDrawableSpan;
 import com.android.launcher3.keyboard.FocusedItemDecorator;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.PackageUserKey;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
 
@@ -68,26 +60,24 @@
  * The all apps view container.
  */
 public class AllAppsContainerView extends BaseContainerView implements DragSource,
-        View.OnLongClickListener, AllAppsSearchBarController.Callbacks, Insettable {
+        View.OnLongClickListener, Insettable {
 
     private final Launcher mLauncher;
     private final AlphabeticalAppsList mApps;
     private final AllAppsGridAdapter mAdapter;
-    private final RecyclerView.LayoutManager mLayoutManager;
+    private final LinearLayoutManager mLayoutManager;
 
     private AllAppsRecyclerView mAppsRecyclerView;
-    private AllAppsSearchBarController mSearchBarController;
-
+    private SearchUiManager mSearchUiManager;
     private View mSearchContainer;
-    private int mSearchContainerMinHeight;
-    private ExtendedEditText mSearchInput;
-    private HeaderElevationController mElevationController;
 
     private SpannableStringBuilder mSearchQueryBuilder = null;
 
     private int mNumAppsPerRow;
     private int mNumPredictedAppsPerRow;
 
+    private SpringAnimationHandler mSpringAnimationHandler;
+
     public AllAppsContainerView(Context context) {
         this(context, null);
     }
@@ -102,11 +92,10 @@
         mLauncher = Launcher.getLauncher(context);
         mApps = new AlphabeticalAppsList(context);
         mAdapter = new AllAppsGridAdapter(mLauncher, mApps, mLauncher, this);
+        mSpringAnimationHandler = mAdapter.getSpringAnimationHandler();
         mApps.setAdapter(mAdapter);
         mLayoutManager = mAdapter.getLayoutManager();
         mSearchQueryBuilder = new SpannableStringBuilder();
-        mSearchContainerMinHeight
-                = getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_height);
 
         Selection.setSelection(mSearchQueryBuilder, 0);
     }
@@ -148,7 +137,7 @@
      */
     public void addApps(List<AppInfo> apps) {
         mApps.addApps(apps);
-        mSearchBarController.refreshSearchResult();
+        mSearchUiManager.refreshSearchResult();
     }
 
     /**
@@ -156,7 +145,18 @@
      */
     public void updateApps(List<AppInfo> apps) {
         mApps.updateApps(apps);
-        mSearchBarController.refreshSearchResult();
+        mSearchUiManager.refreshSearchResult();
+    }
+
+    public void updatePromiseAppProgress(PromiseAppInfo app) {
+        int childCount = mAppsRecyclerView.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            View child = mAppsRecyclerView.getChildAt(i);
+            if (child instanceof BubbleTextView && child.getTag() == app) {
+                BubbleTextView bubbleTextView = (BubbleTextView) child;
+                bubbleTextView.applyProgressLevel(app.level);
+            }
+        }
     }
 
     /**
@@ -164,34 +164,7 @@
      */
     public void removeApps(List<AppInfo> apps) {
         mApps.removeApps(apps);
-        mSearchBarController.refreshSearchResult();
-    }
-
-    public void setSearchBarVisible(boolean visible) {
-        if (visible) {
-            mSearchBarController.setVisibility(View.VISIBLE);
-        } else {
-            mSearchBarController.setVisibility(View.INVISIBLE);
-        }
-    }
-
-    /**
-     * Sets the search bar that shows above the a-z list.
-     */
-    public void setSearchBarController(AllAppsSearchBarController searchController) {
-        if (mSearchBarController != null) {
-            throw new RuntimeException("Expected search bar controller to only be set once");
-        }
-        mSearchBarController = searchController;
-        mSearchBarController.initialize(mApps, mSearchInput, mLauncher, this);
-        mAdapter.setSearchController(mSearchBarController);
-    }
-
-    /**
-     * Scrolls this list view to the top.
-     */
-    public void scrollToTop() {
-        mAppsRecyclerView.scrollToTop();
+        mSearchUiManager.refreshSearchResult();
     }
 
     /**
@@ -226,9 +199,7 @@
      * Focuses the search field and begins an app search.
      */
     public void startAppsSearch() {
-        if (mSearchBarController != null) {
-            mSearchBarController.focusSearchField();
-        }
+        mSearchUiManager.startAppsSearch();
     }
 
     /**
@@ -236,9 +207,8 @@
      */
     public void reset() {
         // Reset the search bar and base recycler view after transitioning home
-        scrollToTop();
-        mSearchBarController.reset();
-        mAppsRecyclerView.reset();
+        mAppsRecyclerView.scrollToTop();
+        mSearchUiManager.reset();
     }
 
     @Override
@@ -256,28 +226,21 @@
             }
         });
 
-        mSearchContainer = findViewById(R.id.search_container);
-        mSearchInput = (ExtendedEditText) findViewById(R.id.search_box_input);
-
-        // Update the hint to contain the icon.
-        // Prefix the original hint with two spaces. The first space gets replaced by the icon
-        // using span. The second space is used for a singe space character between the hint
-        // and the icon.
-        SpannableString spanned = new SpannableString("  " + mSearchInput.getHint());
-        spanned.setSpan(new TintedDrawableSpan(getContext(), R.drawable.ic_allapps_search),
-                0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
-        mSearchInput.setHint(spanned);
-
-        mElevationController = new HeaderElevationController(mSearchContainer);
-
         // Load the all apps recycler view
         mAppsRecyclerView = (AllAppsRecyclerView) findViewById(R.id.apps_list_view);
         mAppsRecyclerView.setApps(mApps);
         mAppsRecyclerView.setLayoutManager(mLayoutManager);
         mAppsRecyclerView.setAdapter(mAdapter);
         mAppsRecyclerView.setHasFixedSize(true);
-        mAppsRecyclerView.addOnScrollListener(mElevationController);
-        mAppsRecyclerView.setElevationController(mElevationController);
+        if (FeatureFlags.LAUNCHER3_PHYSICS) {
+            mAppsRecyclerView.setSpringAnimationHandler(mSpringAnimationHandler);
+            mAppsRecyclerView.addOnScrollListener(new SpringMotionOnScrollListener());
+        }
+
+        mSearchContainer = findViewById(R.id.search_container);
+        mSearchUiManager = (SearchUiManager) mSearchContainer;
+        mSearchUiManager.initialize(mApps, mAppsRecyclerView);
+
 
         FocusedItemDecorator focusedItemDecorator = new FocusedItemDecorator(mAppsRecyclerView);
         mAppsRecyclerView.addItemDecoration(focusedItemDecorator);
@@ -291,18 +254,21 @@
         }
     }
 
+    public SearchUiManager getSearchUiManager() {
+        return mSearchUiManager;
+    }
+
     @Override
     public View getTouchDelegateTargetView() {
         return mAppsRecyclerView;
     }
 
     @Override
-    public void onBoundsChanged(Rect newBounds) { }
-
-    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         DeviceProfile grid = mLauncher.getDeviceProfile();
+        // Update the number of items in the grid before we measure the view
         grid.updateAppsViewNumCols();
+
         if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
             if (mNumAppsPerRow != grid.inv.numColumns ||
                     mNumPredictedAppsPerRow != grid.inv.numColumns) {
@@ -313,22 +279,11 @@
                 mAdapter.setNumAppsPerRow(mNumAppsPerRow);
                 mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow);
             }
-            if (!grid.isVerticalBarLayout()) {
-                MarginLayoutParams searchContainerLp =
-                        (MarginLayoutParams) mSearchContainer.getLayoutParams();
-
-                searchContainerLp.height = mLauncher.getDragLayer().getInsets().top
-                        + mSearchContainerMinHeight;
-                mSearchContainer.setLayoutParams(searchContainerLp);
-            }
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
             return;
         }
 
         // --- remove START when {@code FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP} is enabled. ---
-
-        // Update the number of items in the grid before we measure the view
-        grid.updateAppsViewNumCols();
         if (mNumAppsPerRow != grid.allAppsNumCols ||
                 mNumPredictedAppsPerRow != grid.allAppsNumPredictiveCols) {
             mNumAppsPerRow = grid.allAppsNumCols;
@@ -345,22 +300,7 @@
 
     @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
-        // Determine if the key event was actual text, if so, focus the search bar and then dispatch
-        // the key normally so that it can process this key event
-        if (!mSearchBarController.isSearchFieldFocused() &&
-                event.getAction() == KeyEvent.ACTION_DOWN) {
-            final int unicodeChar = event.getUnicodeChar();
-            final boolean isKeyNotWhitespace = unicodeChar > 0 &&
-                    !Character.isWhitespace(unicodeChar) && !Character.isSpaceChar(unicodeChar);
-            if (isKeyNotWhitespace) {
-                boolean gotKey = TextKeyListener.getInstance().onKeyDown(this, mSearchQueryBuilder,
-                        event.getKeyCode(), event);
-                if (gotKey && mSearchQueryBuilder.length() > 0) {
-                    mSearchBarController.focusSearchField();
-                }
-            }
-        }
-
+        mSearchUiManager.preDispatchKeyEvent(event);
         return super.dispatchKeyEvent(event);
     }
 
@@ -428,47 +368,21 @@
     }
 
     @Override
-    public void onSearchResult(String query, ArrayList<ComponentKey> apps) {
-        if (apps != null) {
-            mApps.setOrderedFilter(apps);
-            mAppsRecyclerView.onSearchResultsChanged();
-            mAdapter.setLastSearchQuery(query);
-        }
-    }
-
-    @Override
-    public void onAppDiscoverySearchUpdate(@Nullable AppDiscoveryItem app,
-            @NonNull AppDiscoveryUpdateState state) {
-        if (!mLauncher.isDestroyed()) {
-            mApps.onAppDiscoverySearchUpdate(app, state);
-            mAppsRecyclerView.onSearchResultsChanged();
-        }
-    }
-
-    @Override
-    public void clearSearchResult() {
-        if (mApps.setOrderedFilter(null)) {
-            mAppsRecyclerView.onSearchResultsChanged();
-        }
-
-        // Clear the search query
-        mSearchQueryBuilder.clear();
-        mSearchQueryBuilder.clearSpans();
-        Selection.setSelection(mSearchQueryBuilder, 0);
-    }
-
-    @Override
     public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
         targetParent.containerType = mAppsRecyclerView.getContainerType(v);
     }
 
     public boolean shouldRestoreImeState() {
-        return !TextUtils.isEmpty(mSearchInput.getText());
+        return mSearchUiManager.shouldRestoreImeState();
     }
 
     @Override
     public void setInsets(Rect insets) {
         DeviceProfile grid = mLauncher.getDeviceProfile();
+        mAppsRecyclerView.setPadding(
+                mAppsRecyclerView.getPaddingLeft(), mAppsRecyclerView.getPaddingTop(),
+                mAppsRecyclerView.getPaddingRight(), insets.bottom);
+
         if (grid.isVerticalBarLayout()) {
             ViewGroup.MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
             mlp.leftMargin = insets.left;
@@ -480,7 +394,8 @@
             ViewGroup.LayoutParams navBarBgLp = navBarBg.getLayoutParams();
             navBarBgLp.height = insets.bottom;
             navBarBg.setLayoutParams(navBarBgLp);
-            navBarBg.setVisibility(View.VISIBLE);
+            navBarBg.setVisibility(FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS
+                    ? View.INVISIBLE : View.VISIBLE);
         }
     }
 
@@ -498,4 +413,39 @@
             }
         }
     }
+
+    public SpringAnimationHandler getSpringAnimationHandler() {
+        return mSpringAnimationHandler;
+    }
+
+    public class SpringMotionOnScrollListener extends RecyclerView.OnScrollListener {
+
+        private int mScrollState = RecyclerView.SCROLL_STATE_IDLE;
+
+        @Override
+        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
+            if (mScrollState == RecyclerView.SCROLL_STATE_DRAGGING
+                    || (dx == 0 && dy == 0)) {
+                if (mSpringAnimationHandler.isRunning()){
+                    mSpringAnimationHandler.skipToEnd();
+                }
+                return;
+            }
+
+            int first = mLayoutManager.findFirstVisibleItemPosition();
+            int last = mLayoutManager.findLastVisibleItemPosition();
+
+            // We only show the spring animation when at the top or bottom, so we wait until the
+            // first or last row is visible to ensure that all animations run in sync.
+            if ((first == 0 && dy < 0) || (last == mAdapter.getItemCount() - 1 && dy > 0)) {
+                mSpringAnimationHandler.animateToFinalPosition(0);
+            }
+        }
+
+        @Override
+        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
+            super.onScrollStateChanged(recyclerView, newState);
+            mScrollState = newState;
+        }
+    }
 }
diff --git a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
index a1ff822..e08cb15 100644
--- a/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
+++ b/src/com/android/launcher3/allapps/AllAppsFastScrollHelper.java
@@ -16,11 +16,7 @@
 package com.android.launcher3.allapps;
 
 import android.support.v7.widget.RecyclerView;
-import android.view.View;
 
-import com.android.launcher3.BaseRecyclerViewFastScrollBar;
-import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.FastBitmapDrawable;
 import com.android.launcher3.util.Thunk;
 
 import java.util.HashSet;
@@ -210,7 +206,9 @@
         for (RecyclerView.ViewHolder viewHolder : mTrackedFastScrollViews) {
             int pos = viewHolder.getAdapterPosition();
             boolean isActive = false;
-            if (mCurrentFastScrollSection != null && pos > -1) {
+            if (mCurrentFastScrollSection != null
+                    && pos > RecyclerView.NO_POSITION
+                    && pos < mApps.getAdapterItems().size()) {
                 AlphabeticalAppsList.AdapterItem item = mApps.getAdapterItems().get(pos);
                 isActive = item != null &&
                         mCurrentFastScrollSection.equals(item.sectionName) &&
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 59cac8d..9c7372f 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -19,6 +19,8 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Point;
+import android.support.animation.DynamicAnimation;
+import android.support.animation.SpringAnimation;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
 import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
 import android.support.v4.view.accessibility.AccessibilityRecordCompat;
@@ -33,13 +35,17 @@
 import android.view.accessibility.AccessibilityEvent;
 import android.widget.TextView;
 
-import com.android.launcher3.discovery.AppDiscoveryAppInfo;
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
+import com.android.launcher3.anim.SpringAnimationHandler;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.discovery.AppDiscoveryAppInfo;
 import com.android.launcher3.discovery.AppDiscoveryItemView;
+import com.android.launcher3.util.PackageManagerHelper;
 
 import java.util.List;
 
@@ -79,6 +85,8 @@
             | VIEW_TYPE_PREDICTION_ICON;
     public static final int VIEW_TYPE_MASK_CONTENT = VIEW_TYPE_MASK_ICON
             | VIEW_TYPE_DISCOVERY_ITEM;
+    public static final int VIEW_TYPE_MASK_HAS_SPRINGS = VIEW_TYPE_MASK_ICON
+            | VIEW_TYPE_PREDICTION_DIVIDER;
 
 
     public interface BindViewCallback {
@@ -89,6 +97,7 @@
      * ViewHolder for each icon.
      */
     public static class ViewHolder extends RecyclerView.ViewHolder {
+
         public ViewHolder(View v) {
             super(v);
         }
@@ -160,11 +169,6 @@
             }
             return extraRows;
         }
-
-        @Override
-        public int getPaddingBottom() {
-            return mLauncher.getDragLayer().getInsets().bottom;
-        }
     }
 
     /**
@@ -199,7 +203,6 @@
     private int mAppsPerRow;
 
     private BindViewCallback mBindViewCallback;
-    private AllAppsSearchBarController mSearchController;
     private OnFocusChangeListener mIconFocusListener;
 
     // The text to show when there are no search results and no market search handler.
@@ -207,6 +210,8 @@
     // The intent to send off to the market app, updated each time the search query changes.
     private Intent mMarketSearchIntent;
 
+    private SpringAnimationHandler<ViewHolder> mSpringAnimationHandler;
+
     public AllAppsGridAdapter(Launcher launcher, AlphabeticalAppsList apps, View.OnClickListener
             iconClickListener, View.OnLongClickListener iconLongClickListener) {
         Resources res = launcher.getResources();
@@ -219,6 +224,14 @@
         mLayoutInflater = LayoutInflater.from(launcher);
         mIconClickListener = iconClickListener;
         mIconLongClickListener = iconLongClickListener;
+        if (FeatureFlags.LAUNCHER3_PHYSICS) {
+            mSpringAnimationHandler = new SpringAnimationHandler<>(
+                    SpringAnimationHandler.Y_DIRECTION, new AllAppsSpringAnimationFactory());
+        }
+    }
+
+    public SpringAnimationHandler getSpringAnimationHandler() {
+        return mSpringAnimationHandler;
     }
 
     public static boolean isDividerViewType(int viewType) {
@@ -241,8 +254,8 @@
         mGridLayoutMgr.setSpanCount(appsPerRow);
     }
 
-    public void setSearchController(AllAppsSearchBarController searchController) {
-        mSearchController = searchController;
+    public int getNumAppsPerRow() {
+        return mAppsPerRow;
     }
 
     public void setIconFocusListener(OnFocusChangeListener focusListener) {
@@ -256,7 +269,7 @@
     public void setLastSearchQuery(String query) {
         Resources res = mLauncher.getResources();
         mEmptySearchMessage = res.getString(R.string.all_apps_no_search_results, query);
-        mMarketSearchIntent = mSearchController.createMarketSearchIntent(query);
+        mMarketSearchIntent = PackageManagerHelper.getMarketSearchIntent(mLauncher, query);
     }
 
     /**
@@ -282,8 +295,7 @@
                         R.layout.all_apps_icon, parent, false);
                 icon.setOnClickListener(mIconClickListener);
                 icon.setOnLongClickListener(mIconLongClickListener);
-                icon.setLongPressTimeout(ViewConfiguration.get(parent.getContext())
-                        .getLongPressTimeout());
+                icon.setLongPressTimeout(ViewConfiguration.getLongPressTimeout());
                 icon.setOnFocusChangeListener(mIconFocusListener);
 
                 // Ensure the all apps icon height matches the workspace icons
@@ -336,7 +348,6 @@
                 AppInfo info = mApps.getAdapterItems().get(position).appInfo;
                 BubbleTextView icon = (BubbleTextView) holder.itemView;
                 icon.applyFromApplicationInfo(info);
-                icon.setAccessibilityDelegate(mLauncher.getAccessibilityDelegate());
                 break;
             case VIEW_TYPE_DISCOVERY_ITEM:
                 AppDiscoveryAppInfo appDiscoveryAppInfo = (AppDiscoveryAppInfo)
@@ -374,6 +385,22 @@
     }
 
     @Override
+    public void onViewAttachedToWindow(ViewHolder holder) {
+        int type = holder.getItemViewType();
+        if (FeatureFlags.LAUNCHER3_PHYSICS && isViewType(type, VIEW_TYPE_MASK_HAS_SPRINGS)) {
+            mSpringAnimationHandler.add(holder.itemView, holder);
+        }
+    }
+
+    @Override
+    public void onViewDetachedFromWindow(ViewHolder holder) {
+        int type = holder.getItemViewType();
+        if (FeatureFlags.LAUNCHER3_PHYSICS && isViewType(type, VIEW_TYPE_MASK_HAS_SPRINGS)) {
+            mSpringAnimationHandler.remove(holder.itemView);
+        }
+    }
+
+    @Override
     public boolean onFailedToRecycleView(ViewHolder holder) {
         // Always recycle and we will reset the view when it is bound
         return true;
@@ -389,4 +416,121 @@
         AlphabeticalAppsList.AdapterItem item = mApps.getAdapterItems().get(position);
         return item.viewType;
     }
+
+    /**
+     * Helper class to set the SpringAnimation values for an item in the adapter.
+     */
+    private class AllAppsSpringAnimationFactory
+            implements SpringAnimationHandler.AnimationFactory<ViewHolder> {
+        private static final float DEFAULT_MAX_VALUE_PX = 100;
+        private static final float DEFAULT_MIN_VALUE_PX = -DEFAULT_MAX_VALUE_PX;
+
+        // Damping ratio range is [0, 1]
+        private static final float SPRING_DAMPING_RATIO = 0.55f;
+
+        // Stiffness is a non-negative number.
+        private static final float MIN_SPRING_STIFFNESS = 580f;
+        private static final float MAX_SPRING_STIFFNESS = 900f;
+
+        // The amount by which each adjacent rows' stiffness will differ.
+        private static final float ROW_STIFFNESS_COEFFICIENT = 50f;
+
+        @Override
+        public SpringAnimation initialize(ViewHolder vh) {
+            return SpringAnimationHandler.forView(vh.itemView, DynamicAnimation.TRANSLATION_Y, 0);
+        }
+
+        /**
+         * @param spring A new or recycled SpringAnimation.
+         * @param vh The ViewHolder that {@param spring} is related to.
+         */
+        @Override
+        public void update(SpringAnimation spring, ViewHolder vh) {
+            int numPredictedApps = Math.min(mAppsPerRow, mApps.getPredictedApps().size());
+            int appPosition = getAppPosition(vh.getAdapterPosition(), numPredictedApps,
+                    mAppsPerRow);
+
+            int col = appPosition % mAppsPerRow;
+            int row = appPosition / mAppsPerRow;
+
+            int numTotalRows = mApps.getNumAppRows() - 1; // zero-based count
+            if (row > (numTotalRows / 2)) {
+                // Mirror the rows so that the top row acts the same as the bottom row.
+                row = Math.abs(numTotalRows - row);
+            }
+
+            // We manipulate the stiffness, min, and max values based on the items distance to the
+            // first row and the items distance to the center column to create the ^-shaped motion
+            // effect.
+            float rowFactor = (1 + row) * 0.5f;
+            float colFactor = getColumnFactor(col, mAppsPerRow);
+
+            float minValue = DEFAULT_MIN_VALUE_PX * (rowFactor + colFactor);
+            float maxValue = DEFAULT_MAX_VALUE_PX * (rowFactor + colFactor);
+
+            float stiffness = Utilities.boundToRange(
+                    MAX_SPRING_STIFFNESS - (row * ROW_STIFFNESS_COEFFICIENT),
+                    MIN_SPRING_STIFFNESS,
+                    MAX_SPRING_STIFFNESS);
+
+            spring.setMinValue(minValue)
+                    .setMaxValue(maxValue)
+                    .getSpring()
+                    .setStiffness(stiffness)
+                    .setDampingRatio(SPRING_DAMPING_RATIO);
+        }
+
+        /**
+         * @return The app position is the position of the app in the Adapter if we ignored all
+         * other view types.
+         *
+         * The first app is at position 0, and the first app each following row is at a
+         * position that is a multiple of {@param appsPerRow}.
+         *
+         * ie. If there are 5 apps per row, and there are two rows of apps:
+         *     0 1 2 3 4
+         *     5 6 7 8 9
+         */
+        private int getAppPosition(int position, int numPredictedApps, int appsPerRow) {
+            int appPosition = position;
+            int numDividerViews = 1 + (numPredictedApps == 0 ? 0 : 1);
+
+            int allAppsStartAt = numDividerViews + numPredictedApps;
+            if (numDividerViews == 1 || position < allAppsStartAt) {
+                appPosition -= 1;
+            } else {
+                // We cannot assume that the predicted row will always be full.
+                int numPredictedAppsOffset = appsPerRow - numPredictedApps;
+                appPosition = position + numPredictedAppsOffset - numDividerViews;
+            }
+
+            return appPosition;
+        }
+
+        /**
+         * Increase the column factor as the distance increases between the column and the center
+         * column(s).
+         */
+        private float getColumnFactor(int col, int numCols) {
+            float centerColumn = numCols / 2;
+            int distanceToCenter = (int) Math.abs(col - centerColumn);
+
+            boolean evenNumberOfColumns = numCols % 2 == 0;
+            if (evenNumberOfColumns && col < centerColumn) {
+                distanceToCenter -= 1;
+            }
+
+            float factor = 0;
+            while (distanceToCenter > 0) {
+                if (distanceToCenter == 1) {
+                    factor += 0.2f;
+                } else {
+                    factor += 0.1f;
+                }
+                --distanceToCenter;
+            }
+
+            return factor;
+        }
+    }
 }
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 64e2fcb..b2a74ff 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -28,8 +28,8 @@
 import com.android.launcher3.BaseRecyclerView;
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
+import com.android.launcher3.anim.SpringAnimationHandler;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.graphics.DrawableFactory;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -53,7 +53,7 @@
     private AllAppsBackgroundDrawable mEmptySearchBackground;
     private int mEmptySearchBackgroundTopOffset;
 
-    private HeaderElevationController mElevationController;
+    private SpringAnimationHandler mSpringAnimationHandler;
 
     public AllAppsRecyclerView(Context context) {
         this(context, null);
@@ -77,6 +77,18 @@
                 R.dimen.all_apps_empty_search_bg_top_offset);
     }
 
+    public void setSpringAnimationHandler(SpringAnimationHandler springAnimationHandler) {
+        mSpringAnimationHandler = springAnimationHandler;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent e) {
+        if (FeatureFlags.LAUNCHER3_PHYSICS && mSpringAnimationHandler != null) {
+            mSpringAnimationHandler.addMovement(e);
+        }
+        return super.onTouchEvent(e);
+    }
+
     /**
      * Sets the list of apps in this view, used to determine the fastscroll position.
      */
@@ -85,8 +97,8 @@
         mFastScrollHelper = new AllAppsFastScrollHelper(this, apps);
     }
 
-    public void setElevationController(HeaderElevationController elevationController) {
-        mElevationController = elevationController;
+    public AlphabeticalAppsList getApps() {
+        return mApps;
     }
 
     /**
@@ -152,13 +164,8 @@
      */
     public void scrollToTop() {
         // Ensure we reattach the scrollbar if it was previously detached while fast-scrolling
-        if (mScrollbar.isThumbDetached()) {
-            mScrollbar.reattachThumbToScroll();
-        }
+        mScrollbar.reattachThumbToScroll();
         scrollToPosition(0);
-        if (mElevationController != null) {
-            mElevationController.reset();
-        }
     }
 
     @Override
@@ -403,21 +410,14 @@
         return getPaddingTop() + y - offset;
     }
 
-    @Override
-    protected int getScrollbarTrackHeight() {
-        return super.getScrollbarTrackHeight()
-                - Launcher.getLauncher(getContext()).getDragLayer().getInsets().bottom;
-    }
-
     /**
      * Returns the available scroll height:
      *   AvailableScrollHeight = Total height of the all items - last page height
      */
     @Override
     protected int getAvailableScrollHeight() {
-        int paddedHeight = getCurrentScrollY(mApps.getAdapterItems().size(), 0);
-        int totalHeight = paddedHeight + getPaddingBottom();
-        return totalHeight - getScrollbarTrackHeight();
+        return getCurrentScrollY(mApps.getAdapterItems().size(), 0)
+                - getHeight() + getPaddingBottom();
     }
 
     /**
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java
index 6587ad7..517dc94 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerViewContainerView.java
@@ -20,7 +20,6 @@
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.ViewGroup;
-import android.widget.FrameLayout;
 import android.widget.RelativeLayout;
 
 import com.android.launcher3.BubbleTextView;
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 30ed180..d79b0d19 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -22,6 +22,10 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
+import com.android.launcher3.anim.SpringAnimationHandler;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.graphics.GradientView;
+import com.android.launcher3.graphics.ScrimView;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.util.Themes;
@@ -38,12 +42,13 @@
  * closer to top or closer to the page indicator.
  */
 public class AllAppsTransitionController implements TouchController, VerticalPullDetector.Listener,
-        View.OnLayoutChangeListener {
+         SearchUiManager.OnScrollRangeChangeListener {
 
     private static final String TAG = "AllAppsTrans";
     private static final boolean DBG = false;
 
-    private final Interpolator mAccelInterpolator = new AccelerateInterpolator(2f);
+    private final Interpolator mWorkspaceAccelnterpolator = new AccelerateInterpolator(2f);
+    private final Interpolator mHotseatAccelInterpolator = new AccelerateInterpolator(.5f);
     private final Interpolator mDecelInterpolator = new DecelerateInterpolator(3f);
     private final Interpolator mFastOutSlowInInterpolator = new FastOutSlowInInterpolator();
     private final VerticalPullDetector.ScrollInterpolator mScrollInterpolator
@@ -65,6 +70,8 @@
     private final Launcher mLauncher;
     private final VerticalPullDetector mDetector;
     private final ArgbEvaluator mEvaluator;
+    private final boolean mIsDarkTheme;
+    private final boolean mIsWorkspaceDarkText;
 
     // Animation in this class is controlled by a single variable {@link mProgress}.
     // Visually, it represents top y coordinate of the all apps container if multiplied with
@@ -87,10 +94,15 @@
 
     private AnimatorSet mCurrentAnimation;
     private boolean mNoIntercept;
+    private boolean mTouchEventStartedOnHotseat;
 
     // Used in discovery bounce animation to provide the transition without workspace changing.
     private boolean mIsTranslateWithoutWorkspace = false;
     private AnimatorSet mDiscoBounceAnimation;
+    private GradientView mGradientView;
+    private ScrimView mScrimView;
+
+    private SpringAnimationHandler mSpringAnimationHandler;
 
     public AllAppsTransitionController(Launcher l) {
         mLauncher = l;
@@ -101,12 +113,15 @@
 
         mEvaluator = new ArgbEvaluator();
         mAllAppsBackgroundColor = Themes.getAttrColor(l, android.R.attr.colorPrimary);
+        mIsDarkTheme = Themes.getAttrBoolean(mLauncher, R.attr.isMainColorDark);
+        mIsWorkspaceDarkText = Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText);
     }
 
     @Override
     public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
             mNoIntercept = false;
+            mTouchEventStartedOnHotseat = mLauncher.getDragLayer().isEventOverHotseat(ev);
             if (!mLauncher.isAllAppsVisible() && mLauncher.getWorkspace().workspaceInModalState()) {
                 mNoIntercept = true;
             } else if (mLauncher.isAllAppsVisible() &&
@@ -153,6 +168,9 @@
 
     @Override
     public boolean onControllerTouchEvent(MotionEvent ev) {
+        if (hasSpringAnimationHandler()) {
+            mSpringAnimationHandler.addMovement(ev);
+        }
         return mDetector.onTouchEvent(ev);
     }
 
@@ -171,6 +189,9 @@
         mCurrentAnimation = LauncherAnimUtils.createAnimatorSet();
         mShiftStart = mAppsView.getTranslationY();
         preparePull(start);
+        if (hasSpringAnimationHandler()) {
+            mSpringAnimationHandler.skipToEnd();
+        }
     }
 
     @Override
@@ -193,6 +214,9 @@
             return; // early termination.
         }
 
+        final int containerType = mTouchEventStartedOnHotseat
+                ? ContainerType.HOTSEAT : ContainerType.WORKSPACE;
+
         if (fling) {
             if (velocity < 0) {
                 calculateDuration(velocity, mAppsView.getTranslationY());
@@ -201,11 +225,14 @@
                     mLauncher.getUserEventDispatcher().logActionOnContainer(
                             Action.Touch.FLING,
                             Action.Direction.UP,
-                            ContainerType.HOTSEAT);
+                            containerType);
                 }
                 mLauncher.showAppsView(true /* animated */,
                         false /* updatePredictedApps */,
                         false /* focusSearchBar */);
+                if (hasSpringAnimationHandler()) {
+                    mSpringAnimationHandler.animateToFinalPosition(0);
+                }
             } else {
                 calculateDuration(velocity, Math.abs(mShiftRange - mAppsView.getTranslationY()));
                 mLauncher.showWorkspace(true);
@@ -221,7 +248,7 @@
                     mLauncher.getUserEventDispatcher().logActionOnContainer(
                             Action.Touch.SWIPE,
                             Action.Direction.UP,
-                            ContainerType.HOTSEAT);
+                            containerType);
                 }
                 mLauncher.showAppsView(true, /* animated */
                         false /* updatePredictedApps */,
@@ -247,14 +274,17 @@
             if (!mLauncher.isAllAppsVisible()) {
                 mLauncher.tryAndUpdatePredictedApps();
                 mAppsView.setVisibility(View.VISIBLE);
-                mAppsView.setRevealDrawableColor(mHotseatBackgroundColor);
+                if (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+                    mAppsView.setRevealDrawableColor(mHotseatBackgroundColor);
+                }
             }
         }
     }
 
     private void updateLightStatusBar(float shift) {
-        // Do not modify status bar on landscape as all apps is not full bleed.
-        if (mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+        // Do not modify status bar in dark theme or on landscape as all apps is not full bleed.
+        if (mIsDarkTheme || mIsWorkspaceDarkText || (!FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS
+                && mLauncher.getDeviceProfile().isVerticalBarLayout())) {
             return;
         }
         // Use a light status bar (dark icons) if all apps is behind at least half of the status
@@ -263,6 +293,22 @@
         mLauncher.activateLightSystemBars(forceLight, true /* statusBar */, true /* navBar */);
     }
 
+    private void updateAllAppsBg(float progress) {
+        // gradient
+        if (mGradientView == null) {
+            mGradientView = (GradientView) mLauncher.findViewById(R.id.gradient_bg);
+            mGradientView.setVisibility(View.VISIBLE);
+        }
+        mGradientView.setProgress(progress);
+
+        // scrim
+        if (mScrimView == null) {
+            mScrimView = (ScrimView) mLauncher.findViewById(R.id.scrim_bg);
+            mScrimView.setVisibility(View.VISIBLE);
+        }
+        mScrimView.setProgress(progress);
+    }
+
     /**
      * @param progress       value between 0 and 1, 0 shows all apps and 1 shows workspace
      */
@@ -273,31 +319,37 @@
 
         float workspaceHotseatAlpha = Utilities.boundToRange(progress, 0f, 1f);
         float alpha = 1 - workspaceHotseatAlpha;
-        float interpolation = mAccelInterpolator.getInterpolation(workspaceHotseatAlpha);
+        float workspaceAlpha = mWorkspaceAccelnterpolator.getInterpolation(workspaceHotseatAlpha);
+        float hotseatAlpha = mHotseatAccelInterpolator.getInterpolation(workspaceHotseatAlpha);
 
         int color = (Integer) mEvaluator.evaluate(mDecelInterpolator.getInterpolation(alpha),
                 mHotseatBackgroundColor, mAllAppsBackgroundColor);
         int bgAlpha = Color.alpha((int) mEvaluator.evaluate(alpha,
                 mHotseatBackgroundColor, mAllAppsBackgroundColor));
 
-        mAppsView.setRevealDrawableColor(ColorUtils.setAlphaComponent(color, bgAlpha));
+        if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+            updateAllAppsBg(alpha);
+        } else {
+            mAppsView.setRevealDrawableColor(ColorUtils.setAlphaComponent(color, bgAlpha));
+        }
+
         mAppsView.getContentView().setAlpha(alpha);
         mAppsView.setTranslationY(shiftCurrent);
 
         if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
             mWorkspace.setHotseatTranslationAndAlpha(Workspace.Direction.Y, -mShiftRange + shiftCurrent,
-                    interpolation);
+                    hotseatAlpha);
         } else {
             mWorkspace.setHotseatTranslationAndAlpha(Workspace.Direction.Y,
                     PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent),
-                    interpolation);
+                    hotseatAlpha);
         }
 
         if (mIsTranslateWithoutWorkspace) {
             return;
         }
         mWorkspace.setWorkspaceYTranslationAndAlpha(
-                PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent), interpolation);
+                PARALLAX_COEFFICIENT * (-mShiftRange + shiftCurrent), workspaceAlpha);
 
         if (!mDetector.isDraggingState()) {
             mContainerVelocity = mDetector.computeVelocity(shiftCurrent - shiftPrevious,
@@ -451,6 +503,9 @@
 
     public void finishPullUp() {
         mHotseat.setVisibility(View.INVISIBLE);
+        if (hasSpringAnimationHandler()) {
+            mSpringAnimationHandler.reset();
+        }
         setProgress(0f);
     }
 
@@ -459,6 +514,9 @@
         mHotseat.setBackgroundTransparent(false /* transparent */);
         mHotseat.setVisibility(View.VISIBLE);
         mAppsView.reset();
+        if (hasSpringAnimationHandler()) {
+            mSpringAnimationHandler.reset();
+        }
         setProgress(1f);
     }
 
@@ -486,21 +544,20 @@
         mAppsView = appsView;
         mHotseat = hotseat;
         mWorkspace = workspace;
-        mHotseat.addOnLayoutChangeListener(this);
         mHotseat.bringToFront();
         mCaretController = new AllAppsCaretController(
                 mWorkspace.getPageIndicator().getCaretDrawable(), mLauncher);
+        mAppsView.getSearchUiManager().addOnScrollRangeChangeListener(this);
+        mSpringAnimationHandler = mAppsView.getSpringAnimationHandler();
+    }
+
+    private boolean hasSpringAnimationHandler() {
+        return FeatureFlags.LAUNCHER3_PHYSICS && mSpringAnimationHandler != null;
     }
 
     @Override
-    public void onLayoutChange(View v, int left, int top, int right, int bottom,
-            int oldLeft, int oldTop, int oldRight, int oldBottom) {
-        if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
-            mShiftRange = top;
-        } else {
-            mShiftRange = bottom;
-        }
+    public void onScrollRangeChanged(int scrollRange) {
+        mShiftRange = scrollRange;
         setProgress(mProgress);
     }
-
 }
diff --git a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
index f5cf7ef..b84c627 100644
--- a/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
+++ b/src/com/android/launcher3/allapps/AlphabeticalAppsList.java
@@ -24,7 +24,7 @@
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.compat.AlphabeticIndexCompat;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.discovery.AppDiscoveryAppInfo;
 import com.android.launcher3.discovery.AppDiscoveryItem;
 import com.android.launcher3.discovery.AppDiscoveryUpdateState;
@@ -195,6 +195,8 @@
     private int mNumPredictedAppsPerRow;
     private int mNumAppRowsInAdapter;
 
+    private boolean mHasSearchDivider = true;
+
     public AlphabeticalAppsList(Context context) {
         mLauncher = Launcher.getLauncher(context);
         mIndexer = new AlphabeticIndexCompat(context);
@@ -226,6 +228,13 @@
     }
 
     /**
+     * Returns the predicted apps.
+     */
+    public List<AppInfo> getPredictedApps() {
+        return mPredictedApps;
+    }
+
+    /**
      * Returns fast scroller sections of all the current filtered applications.
      */
     public List<FastScrollSectionInfo> getFastScrollerSections() {
@@ -343,6 +352,10 @@
         onAppsUpdated();
     }
 
+    public void disableSearchDivider() {
+        mHasSearchDivider = false;
+    }
+
     /**
      * Updates internals when the set of apps are updated.
      */
@@ -429,8 +442,10 @@
             }
         }
 
-        // Add the search divider
-        mAdapterItems.add(AdapterItem.asSearchDivider(position++));
+        if (mHasSearchDivider) {
+            // Add the search divider
+            mAdapterItems.add(AdapterItem.asSearchDivider(position++));
+        }
 
         // Process the predicted app components
         mPredictedApps.clear();
@@ -440,7 +455,7 @@
                 if (info != null) {
                     mPredictedApps.add(info);
                 } else {
-                    if (ProviderConfig.IS_DOGFOOD_BUILD) {
+                    if (FeatureFlags.IS_DOGFOOD_BUILD) {
                         Log.e(TAG, "Predicted app not found: " + ck);
                     }
                 }
diff --git a/src/com/android/launcher3/allapps/DefaultAppSearchController.java b/src/com/android/launcher3/allapps/DefaultAppSearchController.java
deleted file mode 100644
index 57747e3..0000000
--- a/src/com/android/launcher3/allapps/DefaultAppSearchController.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.launcher3.allapps;
-
-/**
- * The default search controller.
- */
-public class DefaultAppSearchController extends AllAppsSearchBarController {
-
-    public DefaultAppSearchAlgorithm onInitializeSearch() {
-        return new DefaultAppSearchAlgorithm(mApps.getApps());
-    }
-}
diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java
new file mode 100644
index 0000000..0d013c7
--- /dev/null
+++ b/src/com/android/launcher3/allapps/SearchUiManager.java
@@ -0,0 +1,68 @@
+/*
+ * 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.allapps;
+
+import android.view.KeyEvent;
+
+/**
+ * Interface for controlling the Apps search UI.
+ */
+public interface SearchUiManager {
+
+    /**
+     * Initializes the search manager.
+     */
+    void initialize(AlphabeticalAppsList appsList, AllAppsRecyclerView recyclerView);
+
+    /**
+     * Notifies the search manager that the apps-list has changed and the search UI should be
+     * updated accordingly.
+     */
+    void refreshSearchResult();
+
+    /**
+     * Notifies the search manager to close any active search session.
+     */
+    void reset();
+
+    /**
+     * Called before dispatching a key event, in case the search manager wants to initialize
+     * some UI beforehand.
+     */
+    void preDispatchKeyEvent(KeyEvent keyEvent);
+
+    /**
+     * Returns true if the IME should be brought back.
+     * TODO: Remove when removing support for opening all-apps in search mode.
+     */
+    boolean shouldRestoreImeState();
+
+    /**
+     * Starts the search UI
+     * TODO: Remove when removing support for opening all-apps in search mode.
+     */
+    void startAppsSearch();
+
+    void addOnScrollRangeChangeListener(OnScrollRangeChangeListener listener);
+
+    /**
+     * Callback for listening to changes in the vertical scroll range when opening all-apps.
+     */
+    interface OnScrollRangeChangeListener {
+
+        void onScrollRangeChanged(int scrollRange);
+    }
+}
diff --git a/src/com/android/launcher3/allapps/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
similarity index 85%
rename from src/com/android/launcher3/allapps/AllAppsSearchBarController.java
rename to src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
index c7ba3ab..547d9e1 100644
--- a/src/com/android/launcher3/allapps/AllAppsSearchBarController.java
+++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java
@@ -13,12 +13,9 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.allapps;
+package com.android.launcher3.allapps.search;
 
 import android.content.Context;
-import android.content.Intent;
-import android.graphics.Rect;
-import android.net.Uri;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.text.Editable;
@@ -34,16 +31,18 @@
 import com.android.launcher3.ExtendedEditText;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.allapps.AlphabeticalAppsList;
 import com.android.launcher3.discovery.AppDiscoveryItem;
 import com.android.launcher3.discovery.AppDiscoveryUpdateState;
 import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.PackageManagerHelper;
 
 import java.util.ArrayList;
 
 /**
  * An interface to a search box that AllApps can command.
  */
-public abstract class AllAppsSearchBarController
+public class AllAppsSearchBarController
         implements TextWatcher, OnEditorActionListener, ExtendedEditText.OnBackKeyListener {
 
     protected Launcher mLauncher;
@@ -88,9 +87,11 @@
     }
 
     /**
-     * To be implemented by subclasses. This method will get called when the controller is set.
+     * This method will get called when the controller is set.
      */
-    protected abstract DefaultAppSearchAlgorithm onInitializeSearch();
+    public DefaultAppSearchAlgorithm onInitializeSearch() {
+        return new DefaultAppSearchAlgorithm(mApps.getApps());
+    }
 
     @Override
     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@@ -114,7 +115,7 @@
         }
     }
 
-    protected void refreshSearchResult() {
+    public void refreshSearchResult() {
         if (TextUtils.isEmpty(mQuery)) {
             return;
         }
@@ -135,7 +136,8 @@
         if (query.isEmpty()) {
             return false;
         }
-        return mLauncher.startActivitySafely(v, createMarketSearchIntent(query), null);
+        return mLauncher.startActivitySafely(v,
+                PackageManagerHelper.getMarketSearchIntent(mLauncher, query), null);
     }
 
     @Override
@@ -186,29 +188,11 @@
     }
 
     /**
-     * Creates a new market search intent.
-     */
-    public Intent createMarketSearchIntent(String query) {
-        Uri marketSearchUri = Uri.parse("market://search")
-                .buildUpon()
-                .appendQueryParameter("c", "apps")
-                .appendQueryParameter("q", query)
-                .build();
-        return new Intent(Intent.ACTION_VIEW).setData(marketSearchUri);
-    }
-
-    /**
      * Callback for getting search results.
      */
     public interface Callbacks {
 
         /**
-         * Called when the bounds of the search bar has changed.
-         */
-        @Deprecated
-        void onBoundsChanged(Rect newBounds);
-
-        /**
          * Called when the search is complete.
          *
          * @param apps sorted list of matching components or null if in case of failure.
@@ -220,7 +204,6 @@
          */
         void clearSearchResult();
 
-
         /**
          * Called when the app discovery is providing an update of search, which can either be
          * START for starting a new discovery,
diff --git a/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
new file mode 100644
index 0000000..126a02c
--- /dev/null
+++ b/src/com/android/launcher3/allapps/search/AppsSearchContainerLayout.java
@@ -0,0 +1,220 @@
+/*
+ * 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.allapps.search;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.text.Selection;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.SpannableStringBuilder;
+import android.text.TextUtils;
+import android.text.method.TextKeyListener;
+import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.ExtendedEditText;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.allapps.AllAppsGridAdapter;
+import com.android.launcher3.allapps.AllAppsRecyclerView;
+import com.android.launcher3.allapps.AlphabeticalAppsList;
+import com.android.launcher3.allapps.SearchUiManager;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.discovery.AppDiscoveryItem;
+import com.android.launcher3.discovery.AppDiscoveryUpdateState;
+import com.android.launcher3.graphics.TintedDrawableSpan;
+import com.android.launcher3.util.ComponentKey;
+
+import java.util.ArrayList;
+
+/**
+ * Layout to contain the All-apps search UI.
+ */
+public class AppsSearchContainerLayout extends FrameLayout
+        implements SearchUiManager, AllAppsSearchBarController.Callbacks {
+
+    private final Launcher mLauncher;
+    private final int mMinHeight;
+    private final int mSearchBoxHeight;
+    private final AllAppsSearchBarController mSearchBarController;
+    private final SpannableStringBuilder mSearchQueryBuilder;
+    private final HeaderElevationController mElevationController;
+
+    private ExtendedEditText mSearchInput;
+    private AlphabeticalAppsList mApps;
+    private AllAppsRecyclerView mAppsRecyclerView;
+    private AllAppsGridAdapter mAdapter;
+
+    public AppsSearchContainerLayout(Context context) {
+        this(context, null);
+    }
+
+    public AppsSearchContainerLayout(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public AppsSearchContainerLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+
+        mLauncher = Launcher.getLauncher(context);
+        mMinHeight = getResources().getDimensionPixelSize(R.dimen.all_apps_search_bar_height);
+        mSearchBoxHeight = getResources()
+                .getDimensionPixelSize(R.dimen.all_apps_search_bar_field_height);
+        mSearchBarController = new AllAppsSearchBarController();
+        mElevationController = new HeaderElevationController(this);
+
+        mSearchQueryBuilder = new SpannableStringBuilder();
+        Selection.setSelection(mSearchQueryBuilder, 0);
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        super.onFinishInflate();
+        mSearchInput = findViewById(R.id.search_box_input);
+
+        // Update the hint to contain the icon.
+        // Prefix the original hint with two spaces. The first space gets replaced by the icon
+        // using span. The second space is used for a singe space character between the hint
+        // and the icon.
+        SpannableString spanned = new SpannableString("  " + mSearchInput.getHint());
+        spanned.setSpan(new TintedDrawableSpan(getContext(), R.drawable.ic_allapps_search),
+                0, 1, Spannable.SPAN_EXCLUSIVE_INCLUSIVE);
+        mSearchInput.setHint(spanned);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP &&
+                !mLauncher.getDeviceProfile().isVerticalBarLayout()) {
+            getLayoutParams().height = mLauncher.getDragLayer().getInsets().top + mMinHeight;
+        }
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+
+    @Override
+    public void initialize(
+            AlphabeticalAppsList appsList, AllAppsRecyclerView recyclerView) {
+        mApps = appsList;
+        mAppsRecyclerView = recyclerView;
+        mAppsRecyclerView.addOnScrollListener(mElevationController);
+        mAdapter = (AllAppsGridAdapter) mAppsRecyclerView.getAdapter();
+
+        mSearchBarController.initialize(appsList, mSearchInput, mLauncher, this);
+    }
+
+    @Override
+    public void refreshSearchResult() {
+        mSearchBarController.refreshSearchResult();
+    }
+
+    @Override
+    public void reset() {
+        mElevationController.reset();
+        mSearchBarController.reset();
+    }
+
+    @Override
+    public void preDispatchKeyEvent(KeyEvent event) {
+        // Determine if the key event was actual text, if so, focus the search bar and then dispatch
+        // the key normally so that it can process this key event
+        if (!mSearchBarController.isSearchFieldFocused() &&
+                event.getAction() == KeyEvent.ACTION_DOWN) {
+            final int unicodeChar = event.getUnicodeChar();
+            final boolean isKeyNotWhitespace = unicodeChar > 0 &&
+                    !Character.isWhitespace(unicodeChar) && !Character.isSpaceChar(unicodeChar);
+            if (isKeyNotWhitespace) {
+                boolean gotKey = TextKeyListener.getInstance().onKeyDown(this, mSearchQueryBuilder,
+                        event.getKeyCode(), event);
+                if (gotKey && mSearchQueryBuilder.length() > 0) {
+                    mSearchBarController.focusSearchField();
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean shouldRestoreImeState() {
+        return !TextUtils.isEmpty(mSearchInput.getText());
+    }
+
+    @Override
+    public void startAppsSearch() {
+        if (mApps != null) {
+            mSearchBarController.focusSearchField();
+        }
+    }
+
+    @Override
+    public void onSearchResult(String query, ArrayList<ComponentKey> apps) {
+        if (apps != null) {
+            mApps.setOrderedFilter(apps);
+            notifyResultChanged();
+            mAdapter.setLastSearchQuery(query);
+        }
+    }
+
+    @Override
+    public void clearSearchResult() {
+        if (mApps.setOrderedFilter(null)) {
+            notifyResultChanged();
+        }
+
+        // Clear the search query
+        mSearchQueryBuilder.clear();
+        mSearchQueryBuilder.clearSpans();
+        Selection.setSelection(mSearchQueryBuilder, 0);
+    }
+
+    @Override
+    public void onAppDiscoverySearchUpdate(
+            @Nullable AppDiscoveryItem app, @NonNull AppDiscoveryUpdateState state) {
+        if (!mLauncher.isDestroyed()) {
+            mApps.onAppDiscoverySearchUpdate(app, state);
+            notifyResultChanged();
+        }
+    }
+
+    private void notifyResultChanged() {
+        mElevationController.reset();
+        mAppsRecyclerView.onSearchResultsChanged();
+    }
+
+    @Override
+    public void addOnScrollRangeChangeListener(final OnScrollRangeChangeListener listener) {
+        mLauncher.getHotseat().addOnLayoutChangeListener(new OnLayoutChangeListener() {
+            @Override
+            public void onLayoutChange(View v, int left, int top, int right, int bottom,
+                    int oldLeft, int oldTop, int oldRight, int oldBottom) {
+                DeviceProfile dp = mLauncher.getDeviceProfile();
+                if (!dp.isVerticalBarLayout()) {
+                    Rect insets = mLauncher.getDragLayer().getInsets();
+                    int hotseatBottom = bottom - dp.hotseatBarBottomPaddingPx - insets.bottom;
+                    int searchTopMargin = insets.top + (mMinHeight - mSearchBoxHeight);
+                    listener.onScrollRangeChanged(hotseatBottom - searchTopMargin);
+                } else {
+                    listener.onScrollRangeChanged(bottom);
+                }
+            }
+        });
+    }
+}
diff --git a/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
similarity index 96%
rename from src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java
rename to src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
index 06cf9aa..06097d0 100644
--- a/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithm.java
+++ b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.allapps;
+package com.android.launcher3.allapps.search;
 
 import android.os.Handler;
 
@@ -54,7 +54,7 @@
         });
     }
 
-    protected ArrayList<ComponentKey> getTitleMatchResult(String query) {
+    public ArrayList<ComponentKey> getTitleMatchResult(String query) {
         // Do an intersection of the words in the query and each title, and filter out all the
         // apps that don't match all of the words in the query.
         final String queryTextLower = query.toLowerCase();
@@ -67,7 +67,7 @@
         return result;
     }
 
-    protected boolean matches(AppInfo info, String query) {
+    public boolean matches(AppInfo info, String query) {
         int queryLength = query.length();
 
         String title = info.title.toString();
diff --git a/src/com/android/launcher3/allapps/HeaderElevationController.java b/src/com/android/launcher3/allapps/search/HeaderElevationController.java
similarity index 97%
rename from src/com/android/launcher3/allapps/HeaderElevationController.java
rename to src/com/android/launcher3/allapps/search/HeaderElevationController.java
index b167fed..ab4e88f 100644
--- a/src/com/android/launcher3/allapps/HeaderElevationController.java
+++ b/src/com/android/launcher3/allapps/search/HeaderElevationController.java
@@ -1,4 +1,4 @@
-package com.android.launcher3.allapps;
+package com.android.launcher3.allapps.search;
 
 import android.content.res.Resources;
 import android.graphics.Outline;
diff --git a/src/com/android/launcher3/anim/AnimationLayerSet.java b/src/com/android/launcher3/anim/AnimationLayerSet.java
index 14bcd17..f0b3458 100644
--- a/src/com/android/launcher3/anim/AnimationLayerSet.java
+++ b/src/com/android/launcher3/anim/AnimationLayerSet.java
@@ -18,9 +18,8 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
+import android.util.ArrayMap;
 import android.view.View;
-
-import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 
@@ -29,14 +28,14 @@
  */
 public class AnimationLayerSet extends AnimatorListenerAdapter {
 
-    private final HashMap<View, Integer> mViewsToLayerTypeMap;
+    private final ArrayMap<View, Integer> mViewsToLayerTypeMap;
 
     public AnimationLayerSet() {
-        mViewsToLayerTypeMap = new HashMap<>();
+        mViewsToLayerTypeMap = new ArrayMap<>();
     }
 
     public AnimationLayerSet(View v) {
-        mViewsToLayerTypeMap = new HashMap<>(1);
+        mViewsToLayerTypeMap = new ArrayMap<>(1);
         addView(v);
     }
 
diff --git a/src/com/android/launcher3/util/CircleRevealOutlineProvider.java b/src/com/android/launcher3/anim/CircleRevealOutlineProvider.java
similarity index 97%
rename from src/com/android/launcher3/util/CircleRevealOutlineProvider.java
rename to src/com/android/launcher3/anim/CircleRevealOutlineProvider.java
index 9fe5147..9fb6b49 100644
--- a/src/com/android/launcher3/util/CircleRevealOutlineProvider.java
+++ b/src/com/android/launcher3/anim/CircleRevealOutlineProvider.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.launcher3.util;
+package com.android.launcher3.anim;
 
 public class CircleRevealOutlineProvider extends RevealOutlineAnimation {
 
diff --git a/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java b/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java
deleted file mode 100644
index be1e2d6..0000000
--- a/src/com/android/launcher3/anim/PillHeightRevealOutlineProvider.java
+++ /dev/null
@@ -1,43 +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.anim;
-
-import android.graphics.Rect;
-
-import com.android.launcher3.util.PillRevealOutlineProvider;
-
-/**
- * Extension of {@link PillRevealOutlineProvider} which only changes the height of the pill.
- * For now, we assume the height is added/removed from the bottom.
- */
-public class PillHeightRevealOutlineProvider extends PillRevealOutlineProvider {
-
-    private final int mNewHeight;
-
-    public PillHeightRevealOutlineProvider(Rect pillRect, float radius, int newHeight) {
-        super(0, 0, pillRect, radius);
-        mOutline.set(pillRect);
-        mNewHeight = newHeight;
-    }
-
-    @Override
-    public void setProgress(float progress) {
-        mOutline.top = 0;
-        int heightDifference = mPillRect.height() - mNewHeight;
-        mOutline.bottom = (int) (mPillRect.bottom - heightDifference * (1 - progress));
-    }
-}
diff --git a/src/com/android/launcher3/util/RevealOutlineAnimation.java b/src/com/android/launcher3/anim/RevealOutlineAnimation.java
similarity index 96%
rename from src/com/android/launcher3/util/RevealOutlineAnimation.java
rename to src/com/android/launcher3/anim/RevealOutlineAnimation.java
index 4560477..51d00d9 100644
--- a/src/com/android/launcher3/util/RevealOutlineAnimation.java
+++ b/src/com/android/launcher3/anim/RevealOutlineAnimation.java
@@ -1,4 +1,4 @@
-package com.android.launcher3.util;
+package com.android.launcher3.anim;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -83,4 +83,8 @@
     public void getOutline(View v, Outline outline) {
         outline.setRoundRect(mOutline, mOutlineRadius);
     }
+
+    public float getRadius() {
+        return mOutlineRadius;
+    }
 }
diff --git a/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
new file mode 100644
index 0000000..d01b26c
--- /dev/null
+++ b/src/com/android/launcher3/anim/RoundedRectRevealOutlineProvider.java
@@ -0,0 +1,77 @@
+/*
+ * 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.anim;
+
+import android.graphics.Rect;
+
+import com.android.launcher3.popup.PopupContainerWithArrow;
+
+import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_BOTTOM_CORNERS;
+import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_TOP_CORNERS;
+
+/**
+ * A {@link RevealOutlineAnimation} that provides an outline that interpolates between two radii
+ * and two {@link Rect}s.
+ *
+ * An example usage of this provider is an outline that starts out as a circle and ends
+ * as a rounded rectangle.
+ */
+public class RoundedRectRevealOutlineProvider extends RevealOutlineAnimation {
+    private final float mStartRadius;
+    private final float mEndRadius;
+
+    private final Rect mStartRect;
+    private final Rect mEndRect;
+
+    private final @PopupContainerWithArrow.RoundedCornerFlags int mRoundedCorners;
+
+    public RoundedRectRevealOutlineProvider(float startRadius, float endRadius, Rect startRect,
+            Rect endRect) {
+        this(startRadius, endRadius, startRect, endRect,
+                ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS);
+    }
+
+    public RoundedRectRevealOutlineProvider(float startRadius, float endRadius, Rect startRect,
+            Rect endRect, int roundedCorners) {
+        mStartRadius = startRadius;
+        mEndRadius = endRadius;
+        mStartRect = startRect;
+        mEndRect = endRect;
+        mRoundedCorners = roundedCorners;
+    }
+
+    @Override
+    public boolean shouldRemoveElevationDuringAnimation() {
+        return false;
+    }
+
+    @Override
+    public void setProgress(float progress) {
+        mOutlineRadius = (1 - progress) * mStartRadius + progress * mEndRadius;
+
+        mOutline.left = (int) ((1 - progress) * mStartRect.left + progress * mEndRect.left);
+        mOutline.top = (int) ((1 - progress) * mStartRect.top + progress * mEndRect.top);
+        if ((mRoundedCorners & ROUNDED_TOP_CORNERS) == 0) {
+            mOutline.top -= mOutlineRadius;
+        }
+        mOutline.right = (int) ((1 - progress) * mStartRect.right + progress * mEndRect.right);
+        mOutline.bottom = (int) ((1 - progress) * mStartRect.bottom + progress * mEndRect.bottom);
+        if ((mRoundedCorners & ROUNDED_BOTTOM_CORNERS) == 0) {
+            mOutline.bottom += mOutlineRadius;
+        }
+    }
+}
diff --git a/src/com/android/launcher3/anim/SpringAnimationHandler.java b/src/com/android/launcher3/anim/SpringAnimationHandler.java
new file mode 100644
index 0000000..038f826
--- /dev/null
+++ b/src/com/android/launcher3/anim/SpringAnimationHandler.java
@@ -0,0 +1,214 @@
+/*
+ * 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.anim;
+
+import android.support.animation.FloatPropertyCompat;
+import android.support.animation.SpringAnimation;
+import android.support.animation.SpringForce;
+import android.support.annotation.IntDef;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+
+import com.android.launcher3.R;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+
+/**
+ * Handler class that manages springs for a set of views that should all move based on the same
+ * {@link MotionEvent}s.
+ *
+ * Supports setting either X or Y velocity on the list of springs added to this handler.
+ */
+public class SpringAnimationHandler<T> {
+
+    private static final String TAG = "SpringAnimationHandler";
+    private static final boolean DEBUG = false;
+
+    private static final float VELOCITY_DAMPING_FACTOR = 0.175f;
+
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({Y_DIRECTION, X_DIRECTION})
+    public @interface Direction {}
+    public static final int Y_DIRECTION = 0;
+    public static final int X_DIRECTION = 1;
+    private int mVelocityDirection;
+
+    private VelocityTracker mVelocityTracker;
+    private float mCurrentVelocity = 0;
+    private boolean mShouldComputeVelocity = false;
+
+    private AnimationFactory<T> mAnimationFactory;
+
+    private ArrayList<SpringAnimation> mAnimations = new ArrayList<>();
+
+    /**
+     * @param direction Either {@link #X_DIRECTION} or {@link #Y_DIRECTION}.
+     *                  Determines which direction we use to calculate and set the velocity.
+     * @param factory   The AnimationFactory is responsible for initializing and updating the
+     *                  SpringAnimations added to this class.
+     */
+    public SpringAnimationHandler(@Direction int direction, AnimationFactory<T> factory) {
+        mVelocityDirection = direction;
+        mAnimationFactory = factory;
+    }
+
+    /**
+     * Adds a new or recycled animation to the list of springs handled by this class.
+     *
+     * @param view The view the spring is attached to.
+     * @param object Used to initialize and update the spring.
+     */
+    public void add(View view, T object) {
+        SpringAnimation spring = (SpringAnimation) view.getTag(R.id.spring_animation_tag);
+        if (spring == null) {
+            spring = mAnimationFactory.initialize(object);
+            view.setTag(R.id.spring_animation_tag, spring);
+        }
+        mAnimationFactory.update(spring, object);
+        spring.setStartVelocity(mCurrentVelocity);
+        mAnimations.add(spring);
+    }
+
+    /**
+     * Stops and removes the spring attached to {@param view}.
+     */
+    public void remove(View view) {
+        SpringAnimation animation = (SpringAnimation) view.getTag(R.id.spring_animation_tag);
+        if (animation.canSkipToEnd()) {
+            animation.skipToEnd();
+        }
+        mAnimations.remove(animation);
+    }
+
+    public void addMovement(MotionEvent event) {
+        int action = event.getActionMasked();
+        if (DEBUG) Log.d(TAG, "addMovement#action=" + action);
+        switch (action) {
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_DOWN:
+                reset();
+                break;
+        }
+
+        getVelocityTracker().addMovement(event);
+        mShouldComputeVelocity = true;
+    }
+
+    public void animateToFinalPosition(float position) {
+        if (DEBUG) Log.d(TAG, "animateToFinalPosition#computeVelocity=" + mShouldComputeVelocity);
+
+        if (mShouldComputeVelocity) {
+            computeVelocity();
+            setStartVelocity(mCurrentVelocity);
+        }
+
+        int size = mAnimations.size();
+        for (int i = 0; i < size; ++i) {
+            mAnimations.get(i).animateToFinalPosition(position);
+        }
+
+        reset();
+    }
+
+    public boolean isRunning() {
+        // All the animations run at the same time so we can just check the first one.
+        return !mAnimations.isEmpty() && mAnimations.get(0).isRunning();
+    }
+
+    public void skipToEnd() {
+        if (DEBUG) Log.d(TAG, "setStartVelocity#skipToEnd");
+        if (DEBUG) Log.v(TAG, "setStartVelocity#skipToEnd", new Exception());
+
+        int size = mAnimations.size();
+        for (int i = 0; i < size; ++i) {
+            if (mAnimations.get(i).canSkipToEnd()) {
+                mAnimations.get(i).skipToEnd();
+            }
+        }
+    }
+
+    public void reset() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+        mCurrentVelocity = 0;
+    }
+
+    private void setStartVelocity(float velocity) {
+        int size = mAnimations.size();
+        for (int i = 0; i < size; ++i) {
+            mAnimations.get(i).setStartVelocity(velocity);
+        }
+    }
+
+    private void computeVelocity() {
+        getVelocityTracker().computeCurrentVelocity(1000 /* millis */);
+
+        mCurrentVelocity = isVerticalDirection()
+                ? getVelocityTracker().getYVelocity()
+                : getVelocityTracker().getXVelocity();
+        mCurrentVelocity *= VELOCITY_DAMPING_FACTOR;
+        mShouldComputeVelocity = false;
+
+        if (DEBUG) Log.d(TAG, "computeVelocity=" + mCurrentVelocity);
+    }
+
+    private boolean isVerticalDirection() {
+        return mVelocityDirection == Y_DIRECTION;
+    }
+
+    private VelocityTracker getVelocityTracker() {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+        return mVelocityTracker;
+    }
+
+    /**
+     * This interface is used to initialize and update the SpringAnimations added to the
+     * {@link SpringAnimationHandler}.
+     *
+     * @param <T> The object that each SpringAnimation is attached to.
+     */
+    public interface AnimationFactory<T> {
+
+        /**
+         * Initializes a new Spring for {@param object}.
+         */
+        SpringAnimation initialize(T object);
+
+        /**
+         * Updates the value of {@param spring} based on {@param object}.
+         */
+        void update(SpringAnimation spring, T object);
+    }
+
+    /**
+     * Helper method to create a new SpringAnimation for {@param view}.
+     */
+    public static SpringAnimation forView(View view, FloatPropertyCompat property, float finalPos) {
+        SpringAnimation spring = new SpringAnimation(view, property, finalPos);
+        spring.setStartValue(1f);
+        spring.setSpring(new SpringForce(finalPos));
+        return spring;
+    }
+
+}
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index e997a99..26f4ae7 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -26,13 +26,8 @@
 import android.os.UserHandle;
 import android.support.annotation.Nullable;
 
-import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
-import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.graphics.LauncherIcons;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
-import com.android.launcher3.util.LooperExecuter;
 import com.android.launcher3.util.PackageUserKey;
 
 import java.util.List;
@@ -88,62 +83,6 @@
     public abstract List<ShortcutConfigActivityInfo> getCustomShortcutActivityList(
             @Nullable PackageUserKey packageUser);
 
-    /**
-     * request.accept() will initiate the following flow:
-     *      -> go-to-system-process for actual processing (a)
-     *      -> callback-to-launcher on UI thread (b)
-     *      -> post callback on the worker thread (c)
-     *      -> Update model and unpin (in system) any shortcut not in out model. (d)
-     *
-     * Note that (b) will take at-least one frame as it involves posting callback from binder
-     * thread to UI thread.
-     * If (d) happens before we add this shortcut to our model, we will end up unpinning
-     * the shortcut in the system.
-     * Here its the caller's responsibility to add the newly created ShortcutInfo immediately
-     * to the model (which may involves a single post-to-worker-thread). That will guarantee
-     * that (d) happens after model is updated.
-     */
-    @Nullable
-    public static ShortcutInfo createShortcutInfoFromPinItemRequest(
-            Context context, final PinItemRequestCompat request, final long acceptDelay) {
-        if (request != null &&
-                request.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT &&
-                request.isValid()) {
-
-            if (acceptDelay <= 0) {
-                if (!request.accept()) {
-                    return null;
-                }
-            } else {
-                // Block the worker thread until the accept() is called.
-                new LooperExecuter(LauncherModel.getWorkerLooper()).execute(new Runnable() {
-                    @Override
-                    public void run() {
-                        try {
-                            Thread.sleep(acceptDelay);
-                        } catch (InterruptedException e) {
-                            // Ignore
-                        }
-                        if (request.isValid()) {
-                            request.accept();
-                        }
-                    }
-                });
-            }
-
-            ShortcutInfoCompat compat = new ShortcutInfoCompat(request.getShortcutInfo());
-            ShortcutInfo info = new ShortcutInfo(compat, context);
-            // Apply the unbadged icon and fetch the actual icon asynchronously.
-            info.iconBitmap = LauncherIcons
-                    .createShortcutIcon(compat, context, false /* badged */);
-            LauncherAppState.getInstance(context).getModel()
-                    .updateAndBindShortcutInfo(info, compat);
-            return info;
-        } else {
-            return null;
-        }
-    }
-
     public void showAppDetailsForProfile(ComponentName component, UserHandle user) {
         showAppDetailsForProfile(component, user, null, null);
     }
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
index d145539..3214b46 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
@@ -18,20 +18,27 @@
 
 import android.annotation.TargetApi;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.PinItemRequest;
 import android.content.pm.PackageManager;
 import android.os.Build;
+import android.os.Parcelable;
 import android.os.Process;
 import android.os.UserHandle;
 import android.support.annotation.Nullable;
-import android.util.Log;
 
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherModel;
+import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.compat.ShortcutConfigActivityInfo.ShortcutConfigActivityInfoVO;
+import com.android.launcher3.graphics.LauncherIcons;
+import com.android.launcher3.shortcuts.ShortcutInfoCompat;
+import com.android.launcher3.util.LooperExecutor;
 import com.android.launcher3.util.PackageUserKey;
 
-import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -45,11 +52,6 @@
     @Override
     public ApplicationInfo getApplicationInfo(String packageName, int flags, UserHandle user) {
         try {
-            // TODO: Temporary workaround until the API signature is updated
-            if (false) {
-                throw new PackageManager.NameNotFoundException();
-            }
-
             ApplicationInfo info = mLauncherApps.getApplicationInfo(packageName, flags, user);
             return (info.flags & ApplicationInfo.FLAG_INSTALLED) == 0 || !info.enabled
                     ? null : info;
@@ -64,34 +66,89 @@
         List<ShortcutConfigActivityInfo> result = new ArrayList<>();
         UserHandle myUser = Process.myUserHandle();
 
-        try {
-            Method m = LauncherApps.class.getDeclaredMethod("getShortcutConfigActivityList",
-                    String.class, UserHandle.class);
-            final List<UserHandle> users;
-            final String packageName;
-            if (packageUser == null) {
-                users = UserManagerCompat.getInstance(mContext).getUserProfiles();
-                packageName = null;
-            } else {
-                users = new ArrayList<>(1);
-                users.add(packageUser.mUser);
-                packageName = packageUser.mPackageName;
-            }
-            for (UserHandle user : users) {
-                boolean ignoreTargetSdk = myUser.equals(user);
-                List<LauncherActivityInfo> activities =
-                        (List<LauncherActivityInfo>) m.invoke(mLauncherApps, packageName, user);
-                for (LauncherActivityInfo activityInfo : activities) {
-                    if (ignoreTargetSdk || activityInfo.getApplicationInfo().targetSdkVersion >=
-                            Build.VERSION_CODES.O) {
-                        result.add(new ShortcutConfigActivityInfoVO(activityInfo));
-                    }
+        final List<UserHandle> users;
+        final String packageName;
+        if (packageUser == null) {
+            users = UserManagerCompat.getInstance(mContext).getUserProfiles();
+            packageName = null;
+        } else {
+            users = new ArrayList<>(1);
+            users.add(packageUser.mUser);
+            packageName = packageUser.mPackageName;
+        }
+        for (UserHandle user : users) {
+            boolean ignoreTargetSdk = myUser.equals(user);
+            List<LauncherActivityInfo> activities =
+                    mLauncherApps.getShortcutConfigActivityList(packageName, user);
+            for (LauncherActivityInfo activityInfo : activities) {
+                if (ignoreTargetSdk || activityInfo.getApplicationInfo().targetSdkVersion >=
+                        Build.VERSION_CODES.O) {
+                    result.add(new ShortcutConfigActivityInfoVO(activityInfo));
                 }
             }
-        } catch (Exception e) {
-            Log.e("LauncherAppsCompatVO", "Error calling new API", e);
         }
 
         return result;
     }
+
+    /**
+     * request.accept() will initiate the following flow:
+     *      -> go-to-system-process for actual processing (a)
+     *      -> callback-to-launcher on UI thread (b)
+     *      -> post callback on the worker thread (c)
+     *      -> Update model and unpin (in system) any shortcut not in out model. (d)
+     *
+     * Note that (b) will take at-least one frame as it involves posting callback from binder
+     * thread to UI thread.
+     * If (d) happens before we add this shortcut to our model, we will end up unpinning
+     * the shortcut in the system.
+     * Here its the caller's responsibility to add the newly created ShortcutInfo immediately
+     * to the model (which may involves a single post-to-worker-thread). That will guarantee
+     * that (d) happens after model is updated.
+     */
+    @Nullable
+    public static ShortcutInfo createShortcutInfoFromPinItemRequest(
+            Context context, final PinItemRequest request, final long acceptDelay) {
+        if (request != null &&
+                request.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT &&
+                request.isValid()) {
+
+            if (acceptDelay <= 0) {
+                if (!request.accept()) {
+                    return null;
+                }
+            } else {
+                // Block the worker thread until the accept() is called.
+                new LooperExecutor(LauncherModel.getWorkerLooper()).execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        try {
+                            Thread.sleep(acceptDelay);
+                        } catch (InterruptedException e) {
+                            // Ignore
+                        }
+                        if (request.isValid()) {
+                            request.accept();
+                        }
+                    }
+                });
+            }
+
+            ShortcutInfoCompat compat = new ShortcutInfoCompat(request.getShortcutInfo());
+            ShortcutInfo info = new ShortcutInfo(compat, context);
+            // Apply the unbadged icon and fetch the actual icon asynchronously.
+            info.iconBitmap = LauncherIcons
+                    .createShortcutIcon(compat, context, false /* badged */);
+            LauncherAppState.getInstance(context).getModel()
+                    .updateAndBindShortcutInfo(info, compat);
+            return info;
+        } else {
+            return null;
+        }
+    }
+
+    public static PinItemRequest getPinItemRequest(Intent intent) {
+        Parcelable extra = intent.getParcelableExtra(LauncherApps.EXTRA_PIN_ITEM_REQUEST);
+        return extra instanceof PinItemRequest ? (PinItemRequest) extra : null;
+    }
 }
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompat.java b/src/com/android/launcher3/compat/PackageInstallerCompat.java
index c7fe0ce..112cca5 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompat.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompat.java
@@ -16,9 +16,13 @@
 
 package com.android.launcher3.compat;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.pm.PackageInstaller;
+import android.support.annotation.NonNull;
 
 import java.util.HashMap;
+import java.util.List;
 
 public abstract class PackageInstallerCompat {
 
@@ -46,19 +50,34 @@
     public abstract void onStop();
 
     public static final class PackageInstallInfo {
+        public final ComponentName componentName;
         public final String packageName;
+        public final int state;
+        public final int progress;
 
-        public int state;
-        public int progress;
-
-        public PackageInstallInfo(String packageName) {
-            this.packageName = packageName;
+        private PackageInstallInfo(@NonNull PackageInstaller.SessionInfo info) {
+            this.state = STATUS_INSTALLING;
+            this.packageName = info.getAppPackageName();
+            this.componentName = new ComponentName(packageName, "");
+            this.progress = (int) (info.getProgress() * 100f);
         }
 
         public PackageInstallInfo(String packageName, int state, int progress) {
-            this.packageName = packageName;
             this.state = state;
+            this.packageName = packageName;
+            this.componentName = new ComponentName(packageName, "");
             this.progress = progress;
         }
+
+        public static PackageInstallInfo fromInstallingState(PackageInstaller.SessionInfo info) {
+            return new PackageInstallInfo(info);
+        }
+
+        public static PackageInstallInfo fromState(int state, String packageName) {
+            return new PackageInstallInfo(packageName, state, 0 /* progress */);
+        }
+
     }
+
+    public abstract List<PackageInstaller.SessionInfo> getAllVerifiedSessions();
 }
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index b87582f..1ffd3da 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -17,34 +17,44 @@
 package com.android.launcher3.compat;
 
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionCallback;
 import android.content.pm.PackageInstaller.SessionInfo;
 import android.os.Handler;
 import android.os.Process;
 import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.SparseArray;
 
 import com.android.launcher3.IconCache;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherModel;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.Thunk;
 
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
 
 public class PackageInstallerCompatVL extends PackageInstallerCompat {
 
+    private static final boolean DEBUG = false;
+
     @Thunk final SparseArray<String> mActiveSessions = new SparseArray<>();
 
     @Thunk final PackageInstaller mInstaller;
     private final IconCache mCache;
     private final Handler mWorker;
+    private final Context mAppContext;
+    private final HashMap<String,Boolean> mSessionVerifiedMap = new HashMap<>();
 
     PackageInstallerCompatVL(Context context) {
+        mAppContext = context.getApplicationContext();
         mInstaller = context.getPackageManager().getPackageInstaller();
         mCache = LauncherAppState.getInstance(context).getIconCache();
         mWorker = new Handler(LauncherModel.getWorkerLooper());
-
         mInstaller.registerSessionCallback(mCallback, mWorker);
     }
 
@@ -52,7 +62,7 @@
     public HashMap<String, Integer> updateAndGetActiveSessionCache() {
         HashMap<String, Integer> activePackages = new HashMap<>();
         UserHandle user = Process.myUserHandle();
-        for (SessionInfo info : mInstaller.getAllSessions()) {
+        for (SessionInfo info : getAllVerifiedSessions()) {
             addSessionInfoToCache(info, user);
             if (info.getAppPackageName() != null) {
                 activePackages.put(info.getAppPackageName(), (int) (info.getProgress() * 100));
@@ -86,7 +96,14 @@
 
         @Override
         public void onCreated(int sessionId) {
-            pushSessionDisplayToLauncher(sessionId);
+            SessionInfo sessionInfo = pushSessionDisplayToLauncher(sessionId);
+            if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS && sessionInfo != null) {
+                LauncherAppState app = LauncherAppState.getInstanceNoCreate();
+                if (app != null) {
+                    app.getModel().onInstallSessionCreated(
+                            PackageInstallInfo.fromInstallingState(sessionInfo));
+                }
+            }
         }
 
         @Override
@@ -97,18 +114,17 @@
             mActiveSessions.remove(sessionId);
 
             if (packageName != null) {
-                sendUpdate(new PackageInstallInfo(packageName,
-                        success ? STATUS_INSTALLED : STATUS_FAILED, 0));
+                sendUpdate(PackageInstallInfo.fromState(
+                        success ? STATUS_INSTALLED : STATUS_FAILED,
+                        packageName));
             }
         }
 
         @Override
         public void onProgressChanged(int sessionId, float progress) {
-            SessionInfo session = mInstaller.getSessionInfo(sessionId);
+            SessionInfo session = verify(mInstaller.getSessionInfo(sessionId));
             if (session != null && session.getAppPackageName() != null) {
-                sendUpdate(new PackageInstallInfo(session.getAppPackageName(),
-                        STATUS_INSTALLING,
-                        (int) (session.getProgress() * 100)));
+                sendUpdate(PackageInstallInfo.fromInstallingState(session));
             }
         }
 
@@ -120,16 +136,48 @@
             pushSessionDisplayToLauncher(sessionId);
         }
 
-        private void pushSessionDisplayToLauncher(int sessionId) {
-            SessionInfo session = mInstaller.getSessionInfo(sessionId);
+        private SessionInfo pushSessionDisplayToLauncher(int sessionId) {
+            SessionInfo session = verify(mInstaller.getSessionInfo(sessionId));
             if (session != null && session.getAppPackageName() != null) {
+                mActiveSessions.put(sessionId, session.getAppPackageName());
                 addSessionInfoToCache(session, Process.myUserHandle());
                 LauncherAppState app = LauncherAppState.getInstanceNoCreate();
-
                 if (app != null) {
                     app.getModel().updateSessionDisplayInfo(session.getAppPackageName());
                 }
+                return session;
             }
+            return null;
         }
     };
+
+    private PackageInstaller.SessionInfo verify(PackageInstaller.SessionInfo sessionInfo) {
+        if (sessionInfo == null
+                || sessionInfo.getInstallerPackageName() == null
+                || TextUtils.isEmpty(sessionInfo.getAppPackageName())) {
+            return null;
+        }
+        String pkg = sessionInfo.getInstallerPackageName();
+        synchronized (mSessionVerifiedMap) {
+            if (!mSessionVerifiedMap.containsKey(pkg)) {
+                LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mAppContext);
+                boolean hasSystemFlag = launcherApps.getApplicationInfo(pkg,
+                        ApplicationInfo.FLAG_SYSTEM, Process.myUserHandle()) != null;
+                mSessionVerifiedMap.put(pkg, DEBUG || hasSystemFlag);
+            }
+        }
+        return mSessionVerifiedMap.get(pkg) ? sessionInfo : null;
+    }
+
+    @Override
+    public List<SessionInfo> getAllVerifiedSessions() {
+        List<SessionInfo> list = new ArrayList<>(mInstaller.getAllSessions());
+        Iterator<SessionInfo> it = list.iterator();
+        while (it.hasNext()) {
+            if (verify(it.next()) == null) {
+                it.remove();
+            }
+        }
+        return list;
+    }
 }
diff --git a/src/com/android/launcher3/compat/PinItemRequestCompat.java b/src/com/android/launcher3/compat/PinItemRequestCompat.java
deleted file mode 100644
index 1308cba..0000000
--- a/src/com/android/launcher3/compat/PinItemRequestCompat.java
+++ /dev/null
@@ -1,126 +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.compat;
-
-import android.appwidget.AppWidgetProviderInfo;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ShortcutInfo;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.launcher3.Utilities;
-
-/**
- * A wrapper around platform implementation of PinItemRequestCompat until the
- * updated SDK is available.
- */
-public class PinItemRequestCompat implements Parcelable {
-
-    public static final String EXTRA_PIN_ITEM_REQUEST = "android.content.pm.extra.PIN_ITEM_REQUEST";
-
-    public static final int REQUEST_TYPE_SHORTCUT = 1;
-    public static final int REQUEST_TYPE_APPWIDGET = 2;
-
-    private final Parcelable mObject;
-
-    private PinItemRequestCompat(Parcelable object) {
-        mObject = object;
-    }
-
-    public int getRequestType() {
-        return (Integer) invokeMethod("getRequestType");
-    }
-
-    public ShortcutInfo getShortcutInfo() {
-        return (ShortcutInfo) invokeMethod("getShortcutInfo");
-    }
-
-    public AppWidgetProviderInfo getAppWidgetProviderInfo(Context context) {
-        try {
-            return (AppWidgetProviderInfo) mObject.getClass()
-                    .getDeclaredMethod("getAppWidgetProviderInfo", Context.class)
-                    .invoke(mObject, context);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public boolean isValid() {
-        return (Boolean) invokeMethod("isValid");
-    }
-
-    public boolean accept() {
-        return (Boolean) invokeMethod("accept");
-    }
-
-    public boolean accept(Bundle options) {
-        try {
-            return (Boolean) mObject.getClass().getDeclaredMethod("accept", Bundle.class)
-                    .invoke(mObject, options);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public Bundle getExtras() {
-        try {
-            return (Bundle) mObject.getClass().getDeclaredMethod("getExtras").invoke(mObject);
-        } catch (Exception e) {
-            return null;
-        }
-    }
-
-    private Object invokeMethod(String methodName) {
-        try {
-            return mObject.getClass().getDeclaredMethod(methodName).invoke(mObject);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int i) {
-        parcel.writeParcelable(mObject, i);
-    }
-
-    public static final Parcelable.Creator<PinItemRequestCompat> CREATOR =
-            new Parcelable.Creator<PinItemRequestCompat>() {
-                public PinItemRequestCompat createFromParcel(Parcel source) {
-                    Parcelable object = source.readParcelable(null);
-                    return new PinItemRequestCompat(object);
-                }
-
-                public PinItemRequestCompat[] newArray(int size) {
-                    return new PinItemRequestCompat[size];
-                }
-            };
-
-    public static PinItemRequestCompat getPinItemRequest(Intent intent) {
-        if (!Utilities.isAtLeastO()) {
-            return null;
-        }
-        Parcelable extra = intent.getParcelableExtra(EXTRA_PIN_ITEM_REQUEST);
-        return extra == null ? null : new PinItemRequestCompat(extra);
-    }
-}
diff --git a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
index 4a55e8c..6bdc627 100644
--- a/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
+++ b/src/com/android/launcher3/compat/ShortcutConfigActivityInfo.java
@@ -37,8 +37,6 @@
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
 
-import java.lang.reflect.Method;
-
 /**
  * Wrapper class for representing a shortcut configure activity.
  */
@@ -151,15 +149,13 @@
             if (getUser().equals(Process.myUserHandle())) {
                 return super.startConfigActivity(activity, requestCode);
             }
+            IntentSender is = activity.getSystemService(LauncherApps.class)
+                    .getShortcutConfigActivityIntent(mInfo);
             try {
-                Method m = LauncherApps.class.getDeclaredMethod(
-                        "getShortcutConfigActivityIntent", LauncherActivityInfo.class);
-                IntentSender is = (IntentSender) m.invoke(
-                        activity.getSystemService(LauncherApps.class), mInfo);
                 activity.startIntentSenderForResult(is, requestCode, null, 0, 0, 0);
                 return true;
-            } catch (Exception e) {
-                Log.e(TAG, "Error calling new API", e);
+            } catch (IntentSender.SendIntentException e) {
+                Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
                 return false;
             }
         }
diff --git a/src/com/android/launcher3/compat/UserManagerCompatVL.java b/src/com/android/launcher3/compat/UserManagerCompatVL.java
index 45525f5..c7f88f6 100644
--- a/src/com/android/launcher3/compat/UserManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/UserManagerCompatVL.java
@@ -22,8 +22,8 @@
 import android.os.UserHandle;
 import android.os.UserManager;
 
-import com.android.launcher3.Utilities;
 import com.android.launcher3.util.LongArrayMap;
+import com.android.launcher3.util.ManagedProfileHeuristic;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -122,7 +122,7 @@
 
     @Override
     public long getUserCreationTime(UserHandle user) {
-        SharedPreferences prefs = Utilities.getPrefs(mContext);
+        SharedPreferences prefs = ManagedProfileHeuristic.prefs(mContext);
         String key = USER_CREATION_TIME_KEY + getSerialNumberForUser(user);
         if (!prefs.contains(key)) {
             prefs.edit().putLong(key, System.currentTimeMillis()).apply();
diff --git a/src/com/android/launcher3/compat/WallpaperColorsCompat.java b/src/com/android/launcher3/compat/WallpaperColorsCompat.java
new file mode 100644
index 0000000..fd08f94
--- /dev/null
+++ b/src/com/android/launcher3/compat/WallpaperColorsCompat.java
@@ -0,0 +1,43 @@
+/*
+ * 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.compat;
+
+import android.util.SparseIntArray;
+
+/**
+ * A compatibility layer around platform implementation of WallpaperColors
+ */
+public class WallpaperColorsCompat {
+
+    private final SparseIntArray mColors;
+    private final boolean mSupportsDarkText;
+
+    public WallpaperColorsCompat(SparseIntArray colors, boolean supportsDarkText) {
+        mColors = colors;
+        mSupportsDarkText = supportsDarkText;
+    }
+
+    /**
+     * A map of color code to their occurrences. The bigger the int, the more relevant the color.
+     */
+    public SparseIntArray getColors() {
+        return mColors;
+    }
+
+    public boolean supportsDarkText() {
+        return mSupportsDarkText;
+    }
+}
diff --git a/src/com/android/launcher3/compat/WallpaperManagerCompat.java b/src/com/android/launcher3/compat/WallpaperManagerCompat.java
new file mode 100644
index 0000000..cbcabdf
--- /dev/null
+++ b/src/com/android/launcher3/compat/WallpaperManagerCompat.java
@@ -0,0 +1,61 @@
+/*
+ * 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.compat;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+
+import com.android.launcher3.Utilities;
+
+public abstract class WallpaperManagerCompat {
+
+    private static final Object sInstanceLock = new Object();
+    private static WallpaperManagerCompat sInstance;
+
+    public static WallpaperManagerCompat getInstance(Context context) {
+        synchronized (sInstanceLock) {
+            if (sInstance == null) {
+                context = context.getApplicationContext();
+
+                if (Utilities.isAtLeastO()) {
+                    try {
+                        sInstance = new WallpaperManagerCompatVOMR1(context);
+                    } catch (Exception e) {
+                        // The wallpaper APIs do not yet exist
+                    }
+                }
+                if (sInstance == null) {
+                    sInstance = new WallpaperManagerCompatVL(context);
+                }
+            }
+            return sInstance;
+        }
+    }
+
+
+    public abstract @Nullable WallpaperColorsCompat getWallpaperColors(int which);
+
+    public abstract void addOnColorsChangedListener(OnColorsChangedListenerCompat listener);
+
+    /**
+     * Interface definition for a callback to be invoked when colors change on a wallpaper.
+     */
+    public interface OnColorsChangedListenerCompat {
+
+        void onColorsChanged(WallpaperColorsCompat colors, int which);
+    }
+}
diff --git a/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java b/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java
new file mode 100644
index 0000000..8bdcedb
--- /dev/null
+++ b/src/com/android/launcher3/compat/WallpaperManagerCompatVL.java
@@ -0,0 +1,280 @@
+/*
+ * 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.compat;
+
+import static android.app.WallpaperManager.FLAG_SYSTEM;
+
+import static com.android.launcher3.Utilities.getDevicePrefs;
+
+import android.app.WallpaperInfo;
+import android.app.WallpaperManager;
+import android.app.job.JobInfo;
+import android.app.job.JobParameters;
+import android.app.job.JobScheduler;
+import android.app.job.JobService;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.pm.PermissionInfo;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.BitmapRegionDecoder;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.ParcelFileDescriptor;
+import android.support.annotation.Nullable;
+import android.support.v7.graphics.Palette;
+import android.util.Log;
+import android.util.Pair;
+import android.util.SparseIntArray;
+
+import com.android.launcher3.Utilities;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class WallpaperManagerCompatVL extends WallpaperManagerCompat {
+
+    private static final String TAG = "WMCompatVL";
+
+    private static final String VERSION_PREFIX = "1,";
+    private static final String KEY_COLORS = "wallpaper_parsed_colors";
+    private static final String ACTION_EXTRACTION_COMPLETE =
+            "com.android.launcher3.compat.WallpaperManagerCompatVL.EXTRACTION_COMPLETE";
+
+    private final ArrayList<OnColorsChangedListenerCompat> mListeners = new ArrayList<>();
+
+    private final Context mContext;
+    private WallpaperColorsCompat mColorsCompat;
+
+    WallpaperManagerCompatVL(Context context) {
+        mContext = context;
+
+        String colors = getDevicePrefs(mContext).getString(KEY_COLORS, "");
+        int wallpaperId = -1;
+        if (colors.startsWith(VERSION_PREFIX)) {
+            Pair<Integer, WallpaperColorsCompat> storedValue = parseValue(colors);
+            wallpaperId = storedValue.first;
+            mColorsCompat = storedValue.second;
+        }
+
+        if (wallpaperId == -1 || wallpaperId != getWallpaperId(context)) {
+            reloadColors();
+        }
+        context.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                reloadColors();
+            }
+        }, new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED));
+
+        // Register a receiver for results
+        String permission = null;
+        // Find a permission which only we can use.
+        try {
+            for (PermissionInfo info : context.getPackageManager().getPackageInfo(
+                    context.getPackageName(),
+                    PackageManager.GET_PERMISSIONS).permissions) {
+                if ((info.protectionLevel & PermissionInfo.PROTECTION_SIGNATURE) != 0) {
+                    permission = info.name;
+                }
+            }
+        } catch (PackageManager.NameNotFoundException e) {
+            // Something went wrong. ignore
+            Log.d(TAG, "Unable to get permission info", e);
+        }
+        mContext.registerReceiver(new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                handleResult(intent.getStringExtra(KEY_COLORS));
+            }
+        }, new IntentFilter(ACTION_EXTRACTION_COMPLETE), permission, new Handler());
+    }
+
+    @Nullable
+    @Override
+    public WallpaperColorsCompat getWallpaperColors(int which) {
+        return which == FLAG_SYSTEM ? mColorsCompat : null;
+    }
+
+    @Override
+    public void addOnColorsChangedListener(OnColorsChangedListenerCompat listener) {
+        mListeners.add(listener);
+    }
+
+    private void reloadColors() {
+        JobInfo job = new JobInfo.Builder(Utilities.WALLPAPER_COMPAT_JOB_ID,
+                new ComponentName(mContext, ColorExtractionService.class))
+                .setMinimumLatency(0).build();
+        ((JobScheduler) mContext.getSystemService(Context.JOB_SCHEDULER_SERVICE)).schedule(job);
+    }
+
+    private void handleResult(String result) {
+        getDevicePrefs(mContext).edit().putString(KEY_COLORS, result).apply();
+        mColorsCompat = parseValue(result).second;
+        for (OnColorsChangedListenerCompat listener : mListeners) {
+            listener.onColorsChanged(mColorsCompat, FLAG_SYSTEM);
+        }
+    }
+
+    private static final int getWallpaperId(Context context) {
+        if (!Utilities.ATLEAST_NOUGAT) {
+            return -1;
+        }
+        return context.getSystemService(WallpaperManager.class).getWallpaperId(FLAG_SYSTEM);
+    }
+
+    /**
+     * Parses the stored value and returns the wallpaper id and wallpaper colors.
+     */
+    private static Pair<Integer, WallpaperColorsCompat> parseValue(String value) {
+        String[] parts = value.split(",");
+        Integer wallpaperId = Integer.parseInt(parts[1]);
+        if (parts.length == 2) {
+            // There is no wallpaper color info present, eg when live wallpaper has no preview.
+            return Pair.create(wallpaperId, null);
+        }
+
+        SparseIntArray colorsToOccurrences = new SparseIntArray((parts.length - 2) / 2);
+        for (int i = 2; i < parts.length; i += 2) {
+            colorsToOccurrences.put(Integer.parseInt(parts[i]), Integer.parseInt(parts[i + 1]));
+        }
+        return Pair.create(wallpaperId, new WallpaperColorsCompat(colorsToOccurrences, false));
+    }
+
+    /**
+     * Intent service to handle color extraction
+     */
+    public static class ColorExtractionService extends JobService implements Runnable {
+        private static final int MAX_WALLPAPER_EXTRACTION_AREA = 112 * 112;
+
+        private HandlerThread mWorkerThread;
+        private Handler mWorkerHandler;
+
+        @Override
+        public void onCreate() {
+            super.onCreate();
+            mWorkerThread = new HandlerThread("ColorExtractionService");
+            mWorkerThread.start();
+            mWorkerHandler = new Handler(mWorkerThread.getLooper());
+        }
+
+        @Override
+        public void onDestroy() {
+            super.onDestroy();
+            mWorkerThread.quit();
+        }
+
+        @Override
+        public boolean onStartJob(final JobParameters jobParameters) {
+            mWorkerHandler.post(this);
+            return true;
+        }
+
+        @Override
+        public boolean onStopJob(JobParameters jobParameters) {
+            mWorkerHandler.removeCallbacksAndMessages(null);
+            return true;
+        }
+
+        /**
+         * Extracts the wallpaper colors and sends the result back through the receiver.
+         */
+        @Override
+        public void run() {
+            int wallpaperId = getWallpaperId(this);
+
+            Bitmap bitmap = null;
+            Drawable drawable = null;
+
+            WallpaperManager wm = WallpaperManager.getInstance(this);
+            WallpaperInfo info = wm.getWallpaperInfo();
+            if (info != null) {
+                // For live wallpaper, extract colors from thumbnail
+                drawable = info.loadThumbnail(getPackageManager());
+            } else {
+                if (Utilities.ATLEAST_NOUGAT) {
+                    try (ParcelFileDescriptor fd = wm.getWallpaperFile(FLAG_SYSTEM)) {
+                        BitmapRegionDecoder decoder = BitmapRegionDecoder
+                                .newInstance(fd.getFileDescriptor(), false);
+
+                        int requestedArea = decoder.getWidth() * decoder.getHeight();
+                        BitmapFactory.Options options = new BitmapFactory.Options();
+
+                        if (requestedArea > MAX_WALLPAPER_EXTRACTION_AREA) {
+                            double areaRatio =
+                                    (double) requestedArea / MAX_WALLPAPER_EXTRACTION_AREA;
+                            double nearestPowOf2 =
+                                    Math.floor(Math.log(areaRatio) / (2 * Math.log(2)));
+                            options.inSampleSize = (int) Math.pow(2, nearestPowOf2);
+                        }
+                        Rect region = new Rect(0, 0, decoder.getWidth(), decoder.getHeight());
+                        bitmap = decoder.decodeRegion(region, options);
+                        decoder.recycle();
+                    } catch (IOException | NullPointerException e) {
+                        Log.e(TAG, "Fetching partial bitmap failed, trying old method", e);
+                    }
+                }
+                if (bitmap == null) {
+                    drawable = wm.getDrawable();
+                }
+            }
+
+            if (drawable != null) {
+                // Calculate how big the bitmap needs to be.
+                // This avoids unnecessary processing and allocation inside Palette.
+                final int requestedArea = drawable.getIntrinsicWidth() *
+                        drawable.getIntrinsicHeight();
+                double scale = 1;
+                if (requestedArea > MAX_WALLPAPER_EXTRACTION_AREA) {
+                    scale = Math.sqrt(MAX_WALLPAPER_EXTRACTION_AREA / (double) requestedArea);
+                }
+                bitmap = Bitmap.createBitmap((int) (drawable.getIntrinsicWidth() * scale),
+                        (int) (drawable.getIntrinsicHeight() * scale), Bitmap.Config.ARGB_8888);
+                final Canvas bmpCanvas = new Canvas(bitmap);
+                drawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
+                drawable.draw(bmpCanvas);
+            }
+
+            String value = VERSION_PREFIX + wallpaperId;
+
+            if (bitmap != null) {
+                Palette palette = Palette.from(bitmap).generate();
+                bitmap.recycle();
+
+                StringBuilder builder = new StringBuilder(value);
+                for (Palette.Swatch swatch : palette.getSwatches()) {
+                    builder.append(',')
+                            .append(swatch.getRgb())
+                            .append(',')
+                            .append(swatch.getPopulation());
+                }
+                value = builder.toString();
+            }
+
+            // Send the result
+            sendBroadcast(new Intent(ACTION_EXTRACTION_COMPLETE)
+                    .setPackage(getPackageName())
+                    .putExtra(KEY_COLORS, value));
+        }
+    }
+}
diff --git a/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java b/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java
new file mode 100644
index 0000000..c74ccc0
--- /dev/null
+++ b/src/com/android/launcher3/compat/WallpaperManagerCompatVOMR1.java
@@ -0,0 +1,109 @@
+/*
+ * 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.compat;
+
+import android.annotation.TargetApi;
+import android.app.WallpaperManager;
+import android.content.Context;
+import android.graphics.Color;
+import android.os.Build;
+import android.support.annotation.Nullable;
+import android.util.Log;
+import android.util.Pair;
+import android.util.SparseIntArray;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.List;
+
+@TargetApi(Build.VERSION_CODES.O)
+public class WallpaperManagerCompatVOMR1 extends WallpaperManagerCompat {
+
+    private static final String TAG = "WMCompatVOMR1";
+
+    private final WallpaperManager mWm;
+
+    private final Class mOCLClass;
+    private final Method mAddOCLMethod;
+
+    private final Method mWCGetMethod;
+    private final Method mWCGetColorsMethod;
+    private final Method mWCSupportsDarkTextMethod;
+
+    WallpaperManagerCompatVOMR1(Context context) throws Exception {
+        mWm = context.getSystemService(WallpaperManager.class);
+
+        mOCLClass = Class.forName("android.app.WallpaperManager$OnColorsChangedListener");
+        mAddOCLMethod = WallpaperManager.class.getDeclaredMethod(
+                "addOnColorsChangedListener", mOCLClass);
+
+        mWCGetMethod = WallpaperManager.class.getDeclaredMethod("getWallpaperColors", int.class);
+        Class wallpaperColorsClass = mWCGetMethod.getReturnType();
+        mWCGetColorsMethod = wallpaperColorsClass.getDeclaredMethod("getColors");
+        mWCSupportsDarkTextMethod = wallpaperColorsClass.getDeclaredMethod("supportsDarkText");
+    }
+
+    @Nullable
+    @Override
+    public WallpaperColorsCompat getWallpaperColors(int which) {
+        try {
+            return convertColorsObject(mWCGetMethod.invoke(mWm, which));
+        } catch (Exception e) {
+            Log.e(TAG, "Error calling wallpaper API", e);
+            return null;
+        }
+    }
+
+    @Override
+    public void addOnColorsChangedListener(final OnColorsChangedListenerCompat listener) {
+        Object onChangeListener = Proxy.newProxyInstance(
+                WallpaperManager.class.getClassLoader(),
+                new Class[]{mOCLClass},
+                new InvocationHandler() {
+                    @Override
+                    public Object invoke(Object o, Method method, Object[] objects)
+                            throws Throwable {
+                        String methodName = method.getName();
+                        if ("onColorsChanged".equals(methodName)) {
+                            listener.onColorsChanged(
+                                    convertColorsObject(objects[0]), (Integer) objects[1]);
+                        } else if ("toString".equals(methodName)) {
+                            return listener.toString();
+                        }
+                        return null;
+                    }
+                });
+        try {
+            mAddOCLMethod.invoke(mWm, onChangeListener);
+        } catch (Exception e) {
+            Log.e(TAG, "Error calling wallpaper API", e);
+        }
+    }
+
+    private WallpaperColorsCompat convertColorsObject(Object colors) throws Exception {
+        if (colors == null) {
+            return null;
+        }
+        List<Pair<Color, Integer>> list = (List) mWCGetColorsMethod.invoke(colors);
+        boolean supportsDarkText = (Boolean) mWCSupportsDarkTextMethod.invoke(colors);
+        SparseIntArray colorMap = new SparseIntArray(list.size());
+        for (Pair<Color, Integer> color : list) {
+            colorMap.put(color.first.toArgb(), color.second);
+        }
+        return new WallpaperColorsCompat(colorMap, supportsDarkText);
+    }
+}
diff --git a/src/com/android/launcher3/discovery/AppDiscoveryItem.java b/src/com/android/launcher3/discovery/AppDiscoveryItem.java
index 09c91ac..2e48b25 100644
--- a/src/com/android/launcher3/discovery/AppDiscoveryItem.java
+++ b/src/com/android/launcher3/discovery/AppDiscoveryItem.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3.discovery;
 
-import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
 
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 09592a8..29789c8 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -28,6 +28,7 @@
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Intent;
+import android.content.pm.LauncherApps.PinItemRequest;
 import android.content.res.Configuration;
 import android.graphics.Canvas;
 import android.graphics.Point;
@@ -50,7 +51,7 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.compat.PinItemRequestCompat;
+import com.android.launcher3.compat.LauncherAppsCompatVO;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.shortcuts.ShortcutInfoCompat;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
@@ -60,7 +61,7 @@
 import com.android.launcher3.widget.WidgetHostViewLoader;
 import com.android.launcher3.widget.WidgetImageView;
 
-@TargetApi(Build.VERSION_CODES.N_MR1)
+@TargetApi(Build.VERSION_CODES.O)
 public class AddItemActivity extends BaseActivity implements OnLongClickListener, OnTouchListener {
 
     private static final int SHADOW_SIZE = 10;
@@ -70,7 +71,7 @@
 
     private final PointF mLastTouchPos = new PointF();
 
-    private PinItemRequestCompat mRequest;
+    private PinItemRequest mRequest;
     private LauncherAppState mApp;
     private InvariantDeviceProfile mIdp;
 
@@ -87,7 +88,7 @@
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        mRequest = PinItemRequestCompat.getPinItemRequest(getIntent());
+        mRequest = LauncherAppsCompatVO.getPinItemRequest(getIntent());
         if (mRequest == null) {
             finish();
             return;
@@ -101,9 +102,9 @@
         mDeviceProfile = mIdp.getDeviceProfile(getApplicationContext());
 
         setContentView(R.layout.add_item_confirmation_activity);
-        mWidgetCell = (LivePreviewWidgetCell) findViewById(R.id.widget_cell);
+        mWidgetCell = findViewById(R.id.widget_cell);
 
-        if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT) {
+        if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT) {
             setupShortcut();
         } else {
             if (!setupWidget()) {
@@ -226,7 +227,7 @@
      * Called when place-automatically button is clicked.
      */
     public void onPlaceAutomaticallyClick(View v) {
-        if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT) {
+        if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT) {
             InstallShortcutReceiver.queueShortcut(
                     new ShortcutInfoCompat(mRequest.getShortcutInfo()), this);
             logCommand(Action.Command.CONFIRM);
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index 7178c5e..be5f01a 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -27,6 +27,7 @@
 import android.graphics.Color;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -54,10 +55,12 @@
 import com.android.launcher3.Utilities;
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.dynamicui.WallpaperColorInfo;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.folder.FolderIcon;
 import com.android.launcher3.keyboard.ViewGroupFocusHelper;
 import com.android.launcher3.logging.LoggerUtils;
+import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 import com.android.launcher3.util.TouchController;
 import com.android.launcher3.widget.WidgetsBottomSheet;
@@ -72,9 +75,6 @@
     public static final int ANIMATION_END_DISAPPEAR = 0;
     public static final int ANIMATION_END_REMAIN_VISIBLE = 2;
 
-    // Scrim color without any alpha component.
-    private static final int SCRIM_COLOR = Color.BLACK & 0x00FFFFFF;
-
     private final int[] mTmpXY = new int[2];
 
     @Thunk DragController mDragController;
@@ -107,6 +107,7 @@
     // Related to adjacent page hints
     private final Rect mScrollChildPosition = new Rect();
     private final ViewGroupFocusHelper mFocusIndicatorHelper;
+    private final WallpaperColorInfo mWallpaperColorInfo;
 
     // Related to pinch-to-go-to-overview gesture.
     private PinchToOverviewListener mPinchListener = null;
@@ -130,6 +131,7 @@
 
         mIsRtl = Utilities.isRtl(getResources());
         mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
+        mWallpaperColorInfo = WallpaperColorInfo.getInstance(getContext());
     }
 
     public void setup(Launcher launcher, DragController dragController,
@@ -451,7 +453,8 @@
     @Override
     public void setInsets(Rect insets) {
         super.setInsets(insets);
-        setBackgroundResource(insets.top == 0 ? 0 : R.drawable.workspace_bg);
+        setBackground(insets.top == 0 ? null
+                : Themes.getAttrDrawable(getContext(), R.attr.workspaceStatusBarScrim));
     }
 
     @Override
@@ -876,7 +879,10 @@
                 getDescendantRectRelativeToSelf(currCellLayout, mHighlightRect);
                 canvas.clipRect(mHighlightRect, Region.Op.DIFFERENCE);
             }
-            canvas.drawColor((alpha << 24) | SCRIM_COLOR);
+            // for super light wallpaper it needs to be darken for contrast to workspace
+            // for dark wallpapers the text is white so darkening works as well
+            int color = ColorUtils.compositeColors(0x66000000, mWallpaperColorInfo.getMainColor());
+            canvas.drawColor(ColorUtils.setAlphaComponent(color, alpha));
             canvas.restore();
         }
 
diff --git a/src/com/android/launcher3/dragndrop/DragOptions.java b/src/com/android/launcher3/dragndrop/DragOptions.java
index 230fa2d..9433aad 100644
--- a/src/com/android/launcher3/dragndrop/DragOptions.java
+++ b/src/com/android/launcher3/dragndrop/DragOptions.java
@@ -17,8 +17,6 @@
 package com.android.launcher3.dragndrop;
 
 import android.graphics.Point;
-import android.support.annotation.CallSuper;
-import android.view.View;
 
 import com.android.launcher3.DropTarget;
 
diff --git a/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
index 36a0292..e36f607 100644
--- a/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
+++ b/src/com/android/launcher3/dragndrop/LivePreviewWidgetCell.java
@@ -4,7 +4,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 import android.widget.FrameLayout;
 import android.widget.RemoteViews;
diff --git a/src/com/android/launcher3/dragndrop/PinItemDragListener.java b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
index df0c47c..f9f4e50 100644
--- a/src/com/android/launcher3/dragndrop/PinItemDragListener.java
+++ b/src/com/android/launcher3/dragndrop/PinItemDragListener.java
@@ -16,11 +16,14 @@
 
 package com.android.launcher3.dragndrop;
 
+import android.annotation.TargetApi;
 import android.appwidget.AppWidgetManager;
 import android.content.ClipDescription;
 import android.content.Intent;
+import android.content.pm.LauncherApps.PinItemRequest;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Looper;
@@ -40,7 +43,7 @@
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.R;
-import com.android.launcher3.compat.PinItemRequestCompat;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.folder.Folder;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -55,6 +58,7 @@
  * {@link DragSource} for handling drop from a different window. This object is initialized
  * in the source window and is passed on to the Launcher activity as an Intent extra.
  */
+@TargetApi(Build.VERSION_CODES.O)
 public class PinItemDragListener
         implements Parcelable, View.OnDragListener, DragSource, DragOptions.PreDragCondition {
 
@@ -63,7 +67,7 @@
     private static final String MIME_TYPE_PREFIX = "com.android.launcher3.drag_and_drop/";
     public static final String EXTRA_PIN_ITEM_DRAG_LISTENER = "pin_item_drag_listener";
 
-    private final PinItemRequestCompat mRequest;
+    private final PinItemRequest mRequest;
 
     // Position of preview relative to the touch location
     private final Rect mPreviewRect;
@@ -78,7 +82,7 @@
     private DragController mDragController;
     private long mDragStartTime;
 
-    public PinItemDragListener(PinItemRequestCompat request, Rect previewRect,
+    public PinItemDragListener(PinItemRequest request, Rect previewRect,
             int previewBitmapWidth, int previewViewWidth) {
         mRequest = request;
         mPreviewRect = previewRect;
@@ -88,7 +92,7 @@
     }
 
     private PinItemDragListener(Parcel parcel) {
-        mRequest = PinItemRequestCompat.CREATOR.createFromParcel(parcel);
+        mRequest = PinItemRequest.CREATOR.createFromParcel(parcel);
         mPreviewRect = Rect.CREATOR.createFromParcel(parcel);
         mPreviewBitmapWidth = parcel.readInt();
         mPreviewViewWidth = parcel.readInt();
@@ -146,7 +150,7 @@
         }
 
         final PendingAddItemInfo item;
-        if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT) {
+        if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_SHORTCUT) {
             item = new PendingAddShortcutInfo(
                     new PinShortcutRequestActivityInfo(mRequest, mLauncher));
         } else {
@@ -177,7 +181,7 @@
         // across windows, using drag position here give a good estimate for relative position
         // to source window.
         PendingItemDragHelper dragHelper = new PendingItemDragHelper(view);
-        if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_APPWIDGET) {
+        if (mRequest.getRequestType() == PinItemRequest.REQUEST_TYPE_APPWIDGET) {
             dragHelper.setPreview(getPreview(mRequest));
         }
 
@@ -271,7 +275,7 @@
         }
     }
 
-    public static RemoteViews getPreview(PinItemRequestCompat request) {
+    public static RemoteViews getPreview(PinItemRequest request) {
         Bundle extras = request.getExtras();
         if (extras != null &&
                 extras.get(AppWidgetManager.EXTRA_APPWIDGET_PREVIEW) instanceof RemoteViews) {
@@ -281,6 +285,9 @@
     }
 
     public static boolean handleDragRequest(Launcher launcher, Intent intent) {
+        if (!Utilities.isAtLeastO()) {
+            return false;
+        }
         if (intent == null || !Intent.ACTION_MAIN.equals(intent.getAction())) {
             return false;
         }
diff --git a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
index bb5ac5b..52abbc7 100644
--- a/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
+++ b/src/com/android/launcher3/dragndrop/PinShortcutRequestActivityInfo.java
@@ -21,6 +21,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.PinItemRequest;
 import android.content.pm.ShortcutInfo;
 import android.graphics.drawable.Drawable;
 import android.os.Build;
@@ -30,26 +31,25 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.R;
-import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.PinItemRequestCompat;
+import com.android.launcher3.compat.LauncherAppsCompatVO;
 import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 
 /**
  * Extension of ShortcutConfigActivityInfo to be used in the confirmation prompt for pin item
  * request.
  */
-@TargetApi(Build.VERSION_CODES.N_MR1)
+@TargetApi(Build.VERSION_CODES.O)
 class PinShortcutRequestActivityInfo extends ShortcutConfigActivityInfo {
 
     // Class name used in the target component, such that it will never represent an
     // actual existing class.
     private static final String DUMMY_COMPONENT_CLASS = "pinned-shortcut";
 
-    private final PinItemRequestCompat mRequest;
+    private final PinItemRequest mRequest;
     private final ShortcutInfo mInfo;
     private final Context mContext;
 
-    public PinShortcutRequestActivityInfo(PinItemRequestCompat request, Context context) {
+    public PinShortcutRequestActivityInfo(PinItemRequest request, Context context) {
         super(new ComponentName(request.getShortcutInfo().getPackage(), DUMMY_COMPONENT_CLASS),
                 request.getShortcutInfo().getUserHandle());
         mRequest = request;
@@ -80,7 +80,7 @@
                 Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT +
                 mContext.getResources().getInteger(R.integer.config_overlayTransitionTime) / 2;
         // Delay the actual accept() call until the drop animation is complete.
-        return LauncherAppsCompat.createShortcutInfoFromPinItemRequest(
+        return LauncherAppsCompatVO.createShortcutInfoFromPinItemRequest(
                 mContext, mRequest, duration);
     }
 
diff --git a/src/com/android/launcher3/dragndrop/PinWidgetFlowHandler.java b/src/com/android/launcher3/dragndrop/PinWidgetFlowHandler.java
index b6da6ad..9f617e4 100644
--- a/src/com/android/launcher3/dragndrop/PinWidgetFlowHandler.java
+++ b/src/com/android/launcher3/dragndrop/PinWidgetFlowHandler.java
@@ -16,15 +16,17 @@
 
 package com.android.launcher3.dragndrop;
 
+import android.annotation.TargetApi;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
+import android.content.pm.LauncherApps.PinItemRequest;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
 
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.compat.PinItemRequestCompat;
 import com.android.launcher3.widget.WidgetAddFlowHandler;
 
 /**
@@ -33,18 +35,19 @@
  * No config activity is shown even if it is defined in widget config. And a callback is sent when
  * the widget is bound.
  */
+@TargetApi(Build.VERSION_CODES.O)
 public class PinWidgetFlowHandler extends WidgetAddFlowHandler implements Parcelable {
 
-    private final PinItemRequestCompat mRequest;
+    private final PinItemRequest mRequest;
 
-    public PinWidgetFlowHandler(AppWidgetProviderInfo providerInfo, PinItemRequestCompat request) {
+    public PinWidgetFlowHandler(AppWidgetProviderInfo providerInfo, PinItemRequest request) {
         super(providerInfo);
         mRequest = request;
     }
 
     protected PinWidgetFlowHandler(Parcel parcel) {
         super(parcel);
-        mRequest = PinItemRequestCompat.CREATOR.createFromParcel(parcel);
+        mRequest = PinItemRequest.CREATOR.createFromParcel(parcel);
     }
 
     @Override
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java b/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java
new file mode 100644
index 0000000..21d5b27
--- /dev/null
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionAlgorithm.java
@@ -0,0 +1,760 @@
+/*
+ * 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.dynamicui;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.v4.graphics.ColorUtils;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Range;
+import android.util.SparseIntArray;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.WallpaperColorsCompat;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * Implementation of tonal color extraction
+ **/
+public class ColorExtractionAlgorithm {
+
+    public static ColorExtractionAlgorithm newInstance(Context context) {
+        return Utilities.getOverrideObject(ColorExtractionAlgorithm.class,
+                context.getApplicationContext(), R.string.color_extraction_impl_class);
+    }
+
+    private static final String TAG = "Tonal";
+
+    // Used for tonal palette fitting
+    private static final float FIT_WEIGHT_H = 1.0f;
+    private static final float FIT_WEIGHT_S = 1.0f;
+    private static final float FIT_WEIGHT_L = 10.0f;
+
+    // When extracting the main color, only consider colors
+    // present in at least MIN_COLOR_OCCURRENCE of the image
+    private static final float MIN_COLOR_OCCURRENCE = 0.1f;
+
+    // Temporary variable to avoid allocations
+    private final float[] mTmpHSL = new float[3];
+
+    public @Nullable Pair<Integer, Integer> extractInto(WallpaperColorsCompat wallpaperColors) {
+        if (wallpaperColors == null) {
+            return null;
+        }
+
+        SparseIntArray colorsArray = wallpaperColors.getColors();
+        if (colorsArray.size() == 0) {
+            return null;
+        }
+        // Tonal is not really a sort, it takes a color from the extracted
+        // palette and finds a best fit amongst a collection of pre-defined
+        // palettes. The best fit is tweaked to be closer to the source color
+        // and replaces the original palette
+
+        List<Pair<Integer, Integer>> colors = new ArrayList<>(colorsArray.size());
+        for (int i = colorsArray.size() - 1; i >= 0; i--) {
+            colors.add(Pair.create(colorsArray.keyAt(i), colorsArray.valueAt(i)));
+        }
+
+        // First find the most representative color in the image
+        populationSort(colors);
+        // Calculate total
+        int total = 0;
+        for (Pair<Integer, Integer> weightedColor : colors) {
+            total += weightedColor.second;
+        }
+
+        // Get bright colors that occur often enough in this image
+        Pair<Integer, Integer> bestColor = null;
+        float[] hsl = new float[3];
+        for (Pair<Integer, Integer> weightedColor : colors) {
+            float colorOccurrence = weightedColor.second / (float) total;
+            if (colorOccurrence < MIN_COLOR_OCCURRENCE) {
+                break;
+            }
+
+            int colorValue = weightedColor.first;
+            ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue),
+                    Color.blue(colorValue), hsl);
+
+            // Stop when we find a color that meets our criteria
+            if (!isBlacklisted(hsl)) {
+                bestColor = weightedColor;
+                break;
+            }
+        }
+
+        // Fail if not found
+        if (bestColor == null) {
+            return null;
+        }
+
+        int colorValue = bestColor.first;
+        ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue),
+                hsl);
+
+        // The Android HSL definition requires the hue to go from 0 to 360 but
+        // the Material Tonal Palette defines hues from 0 to 1.
+        hsl[0] /= 360f;
+
+        // Find the palette that contains the closest color
+        TonalPalette palette = findTonalPalette(hsl[0]);
+
+        if (palette == null) {
+            Log.w(TAG, "Could not find a tonal palette!");
+            return null;
+        }
+
+        // Figure out what's the main color index in the optimal palette
+        int fitIndex = bestFit(palette, hsl[0], hsl[1], hsl[2]);
+        if (fitIndex == -1) {
+            Log.w(TAG, "Could not find best fit!");
+            return null;
+        }
+
+        // Generate the 10 colors palette by offsetting each one of them
+        float[] h = fit(palette.h, hsl[0], fitIndex,
+                Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
+        float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f);
+        float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f);
+
+        final int textInversionIndex = h.length - 3;
+
+        // best fit + a 2 colors offset
+        int primaryIndex = fitIndex;
+        int secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
+        int mainColor = getColorInt(primaryIndex, h, s, l);
+        int secondaryColor = getColorInt(secondaryIndex, h, s, l);
+
+        return new Pair<>(mainColor, secondaryColor);
+    }
+
+    private int getColorInt(int fitIndex, float[] h, float[] s, float[] l) {
+        mTmpHSL[0] = fract(h[fitIndex]) * 360.0f;
+        mTmpHSL[1] = s[fitIndex];
+        mTmpHSL[2] = l[fitIndex];
+        return ColorUtils.HSLToColor(mTmpHSL);
+    }
+
+    /**
+     * Checks if a given color exists in the blacklist
+     * @param hsl float array with 3 components (H 0..360, S 0..1 and L 0..1)
+     * @return true if color should be avoided
+     */
+    private boolean isBlacklisted(float[] hsl) {
+        for (ColorRange badRange: BLACKLISTED_COLORS) {
+            if (badRange.containsColor(hsl[0], hsl[1], hsl[2])) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static void populationSort(@NonNull List<Pair<Integer, Integer>> wallpaperColors) {
+        Collections.sort(wallpaperColors, new Comparator<Pair<Integer, Integer>>() {
+            @Override
+            public int compare(Pair<Integer, Integer> a, Pair<Integer, Integer> b) {
+                return b.second - a.second;
+            }
+        });
+    }
+
+    /**
+     * Offsets all colors by a delta, clamping values that go beyond what's
+     * supported on the color space.
+     * @param data what you want to fit
+     * @param v how big should be the offset
+     * @param index which index to calculate the delta against
+     * @param min minimum accepted value (clamp)
+     * @param max maximum accepted value (clamp)
+     * @return new shifted palette
+     */
+    private static float[] fit(float[] data, float v, int index, float min, float max) {
+        float[] fitData = new float[data.length];
+        float delta = v - data[index];
+
+        for (int i = 0; i < data.length; i++) {
+            fitData[i] = Utilities.boundToRange(data[i] + delta, min, max);
+        }
+
+        return fitData;
+    }
+
+    /**
+     * Finds the closest color in a palette, given another HSL color
+     *
+     * @param palette where to search
+     * @param h hue
+     * @param s saturation
+     * @param l lightness
+     * @return closest index or -1 if palette is empty.
+     */
+    private static int bestFit(@NonNull TonalPalette palette, float h, float s, float l) {
+        int minErrorIndex = -1;
+        float minError = Float.POSITIVE_INFINITY;
+
+        for (int i = 0; i < palette.h.length; i++) {
+            float error =
+                    FIT_WEIGHT_H * Math.abs(h - palette.h[i])
+                            + FIT_WEIGHT_S * Math.abs(s - palette.s[i])
+                            + FIT_WEIGHT_L * Math.abs(l - palette.l[i]);
+            if (error < minError) {
+                minError = error;
+                minErrorIndex = i;
+            }
+        }
+
+        return minErrorIndex;
+    }
+
+    @Nullable
+    private static TonalPalette findTonalPalette(float h) {
+        TonalPalette best = null;
+        float error = Float.POSITIVE_INFINITY;
+
+        for (TonalPalette candidate : TONAL_PALETTES) {
+            if (h >= candidate.minHue && h <= candidate.maxHue) {
+                best = candidate;
+                break;
+            }
+
+            if (candidate.maxHue > 1.0f && h >= 0.0f && h <= fract(candidate.maxHue)) {
+                best = candidate;
+                break;
+            }
+
+            if (candidate.minHue < 0.0f && h >= fract(candidate.minHue) && h <= 1.0f) {
+                best = candidate;
+                break;
+            }
+
+            if (h <= candidate.minHue && candidate.minHue - h < error) {
+                best = candidate;
+                error = candidate.minHue - h;
+            } else if (h >= candidate.maxHue && h - candidate.maxHue < error) {
+                best = candidate;
+                error = h - candidate.maxHue;
+            } else if (candidate.maxHue > 1.0f && h >= fract(candidate.maxHue)
+                    && h - fract(candidate.maxHue) < error) {
+                best = candidate;
+                error = h - fract(candidate.maxHue);
+            } else if (candidate.minHue < 0.0f && h <= fract(candidate.minHue)
+                    && fract(candidate.minHue) - h < error) {
+                best = candidate;
+                error = fract(candidate.minHue) - h;
+            }
+        }
+
+        return best;
+    }
+
+    private static float fract(float v) {
+        return v - (float) Math.floor(v);
+    }
+
+    static class TonalPalette {
+        final float[] h;
+        final float[] s;
+        final float[] l;
+        final float minHue;
+        final float maxHue;
+
+        TonalPalette(float[] h, float[] s, float[] l) {
+            this.h = h;
+            this.s = s;
+            this.l = l;
+
+            float minHue = Float.POSITIVE_INFINITY;
+            float maxHue = Float.NEGATIVE_INFINITY;
+
+            for (float v : h) {
+                minHue = Math.min(v, minHue);
+                maxHue = Math.max(v, maxHue);
+            }
+
+            this.minHue = minHue;
+            this.maxHue = maxHue;
+        }
+    }
+
+    // Data definition of Material Design tonal palettes
+    // When the sort type is set to TONAL, these palettes are used to find
+    // a best fit. Each palette is defined as 22 HSL colors
+    private static final TonalPalette[] TONAL_PALETTES = {
+            new TonalPalette(
+                    new float[]{0.991f, 0.9833333333333333f, 0f, 0f, 0f, 0.01134380453752181f,
+                            0.015625000000000003f, 0.024193548387096798f, 0.027397260273972573f,
+                            0.017543859649122865f},
+                    new float[]{1f, 1f, 1f, 1f, 0.8434782608695652f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.2f, 0.27450980392156865f, 0.34901960784313724f,
+                            0.4235294117647059f, 0.5490196078431373f, 0.6254901960784314f,
+                            0.6862745098039216f, 0.7568627450980392f, 0.8568627450980393f,
+                            0.9254901960784314f}
+            ),
+            new TonalPalette(
+                    new float[]{0.6385767790262171f, 0.6301169590643275f, 0.6223958333333334f,
+                            0.6151079136690647f, 0.6065400843881856f, 0.5986964618249534f,
+                            0.5910746812386157f, 0.5833333333333334f, 0.5748031496062993f,
+                            0.5582010582010583f},
+                    new float[]{1f, 1f, 0.9014084507042253f, 0.8128654970760234f,
+                            0.7979797979797981f, 0.7816593886462883f, 0.778723404255319f,
+                            1f, 1f, 1f},
+                    new float[]{0.17450980392156862f, 0.2235294117647059f, 0.2784313725490196f,
+                            0.3352941176470588f, 0.388235294117647f, 0.44901960784313727f,
+                            0.5392156862745098f, 0.6509803921568628f, 0.7509803921568627f,
+                            0.8764705882352941f}
+            ),
+            new TonalPalette(
+                    new float[]{0.5669934640522876f, 0.5748031496062993f,
+                            0.5595238095238095f, 0.5473118279569893f, 0.5393258426966292f,
+                            0.5315955766192734f, 0.524031007751938f, 0.5154711673699016f,
+                            0.508080808080808f, 0.5f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 0.8847736625514403f, 1f, 1f, 1f},
+                    new float[]{0.2f, 0.24901960784313726f, 0.27450980392156865f,
+                            0.30392156862745096f, 0.34901960784313724f, 0.4137254901960784f,
+                            0.47647058823529415f, 0.5352941176470588f, 0.6764705882352942f, 0.8f}
+            ),
+            new TonalPalette(
+                    new float[]{0.5082304526748972f, 0.5069444444444444f, 0.5f, 0.5f,
+                            0.5f, 0.48724954462659376f, 0.4800347222222222f,
+                            0.4755134281200632f, 0.4724409448818897f, 0.4671052631578947f},
+                    new float[]{1f, 0.8888888888888887f, 0.9242424242424242f, 1f, 1f,
+                            0.8133333333333332f, 0.7868852459016393f, 1f, 1f, 1f},
+                    new float[]{0.1588235294117647f, 0.21176470588235297f,
+                            0.25882352941176473f, 0.3f, 0.34901960784313724f,
+                            0.44117647058823534f, 0.5215686274509804f, 0.5862745098039216f,
+                            0.7509803921568627f, 0.8509803921568627f}
+            ),
+            new TonalPalette(
+                    new float[]{0.3333333333333333f, 0.3333333333333333f,
+                            0.34006734006734f, 0.34006734006734f, 0.34006734006734f,
+                            0.34259259259259256f, 0.3475783475783476f, 0.34767025089605735f,
+                            0.3467741935483871f, 0.3703703703703704f},
+                    new float[]{0.6703296703296703f, 0.728813559322034f,
+                            0.5657142857142856f, 0.5076923076923077f, 0.3944223107569721f,
+                            0.6206896551724138f, 0.8931297709923666f, 1f, 1f, 1f},
+                    new float[]{0.1784313725490196f, 0.23137254901960785f,
+                            0.3431372549019608f, 0.38235294117647056f, 0.49215686274509807f,
+                            0.6588235294117647f, 0.7431372549019608f, 0.8176470588235294f,
+                            0.8784313725490196f, 0.9294117647058824f}
+            ),
+            new TonalPalette(
+                    new float[]{0.162280701754386f, 0.15032679738562088f,
+                            0.15879265091863518f, 0.16236559139784948f, 0.17443868739205526f,
+                            0.17824074074074076f, 0.18674698795180725f,
+                            0.18692449355432778f, 0.1946778711484594f, 0.18604651162790695f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.14901960784313725f, 0.2f, 0.24901960784313726f,
+                            0.30392156862745096f, 0.3784313725490196f, 0.4235294117647059f,
+                            0.48823529411764705f, 0.6450980392156863f, 0.7666666666666666f,
+                            0.8313725490196078f}
+            ),
+            new TonalPalette(
+                    new float[]{0.10619469026548674f, 0.11924686192468618f,
+                            0.13046448087431692f, 0.14248366013071895f, 0.1506024096385542f,
+                            0.16220238095238093f, 0.16666666666666666f,
+                            0.16666666666666666f, 0.162280701754386f, 0.15686274509803924f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.44313725490196076f, 0.46862745098039216f,
+                            0.47843137254901963f, 0.5f, 0.5117647058823529f,
+                            0.5607843137254902f, 0.6509803921568628f, 0.7509803921568627f,
+                            0.8509803921568627f, 0.9f}
+            ),
+            new TonalPalette(
+                    new float[]{0.03561253561253561f, 0.05098039215686275f,
+                            0.07516339869281045f, 0.09477124183006536f, 0.1150326797385621f,
+                            0.134640522875817f, 0.14640522875816991f, 0.1582397003745319f,
+                            0.15773809523809523f, 0.15359477124183002f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.4588235294117647f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
+                            0.5f, 0.6509803921568628f, 0.7803921568627451f, 0.9f}
+            ),
+            new TonalPalette(
+                    new float[]{0.9596491228070175f, 0.9593837535014005f,
+                            0.9514767932489452f, 0.943859649122807f, 0.9396825396825397f,
+                            0.9395424836601307f, 0.9393939393939394f, 0.9362745098039216f,
+                            0.9754098360655739f, 0.9824561403508771f},
+                    new float[]{0.84070796460177f, 0.8206896551724138f,
+                            0.7979797979797981f, 0.7661290322580644f, 0.9051724137931036f,
+                            1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.22156862745098038f, 0.2843137254901961f,
+                            0.388235294117647f, 0.48627450980392156f, 0.5450980392156863f,
+                            0.6f, 0.6764705882352942f, 0.8f, 0.8803921568627451f,
+                            0.9254901960784314f}
+            ),
+            new TonalPalette(
+                    new float[]{0.841025641025641f, 0.8333333333333334f,
+                            0.8285256410256411f, 0.821522309711286f, 0.8083333333333333f,
+                            0.8046594982078853f, 0.8005822416302766f, 0.7842377260981912f,
+                            0.7771084337349398f, 0.7747747747747749f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f,
+                            0.737142857142857f, 0.6434108527131781f, 0.46835443037974644f},
+                    new float[]{0.12745098039215685f, 0.15490196078431373f,
+                            0.20392156862745098f, 0.24901960784313726f, 0.3137254901960784f,
+                            0.36470588235294116f, 0.44901960784313727f,
+                            0.6568627450980392f, 0.7470588235294118f, 0.8450980392156863f}
+            ),
+            new TonalPalette(
+                    new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+                    new float[]{0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f},
+                    new float[]{0.14901960784313725f, 0.2f, 0.2980392156862745f, 0.4f,
+                            0.4980392156862745f, 0.6196078431372549f, 0.7176470588235294f,
+                            0.8196078431372549f, 0.9176470588235294f, 0.9490196078431372f}
+            ),
+            new TonalPalette(
+                    new float[]{0.955952380952381f, 0.9681069958847737f,
+                            0.9760479041916167f, 0.9873563218390804f, 0f, 0f,
+                            0.009057971014492771f, 0.026748971193415648f,
+                            0.041666666666666616f, 0.05303030303030304f},
+                    new float[]{1f, 0.8350515463917526f, 0.6929460580912863f,
+                            0.6387665198237885f, 0.6914893617021276f, 0.7583892617449666f,
+                            0.8070175438596495f, 0.9310344827586209f, 1f, 1f},
+                    new float[]{0.27450980392156865f, 0.3803921568627451f,
+                            0.4725490196078432f, 0.5549019607843138f, 0.6313725490196078f,
+                            0.707843137254902f, 0.7764705882352941f, 0.8294117647058823f,
+                            0.9058823529411765f, 0.9568627450980391f}
+            ),
+            new TonalPalette(
+                    new float[]{0.7514619883040936f, 0.7679738562091503f,
+                            0.7802083333333333f, 0.7844311377245509f, 0.796875f,
+                            0.8165618448637316f, 0.8487179487179487f, 0.8582375478927203f,
+                            0.8562091503267975f, 0.8666666666666667f},
+                    new float[]{1f, 1f, 0.8163265306122449f, 0.6653386454183268f,
+                            0.7547169811320753f, 0.929824561403509f, 0.9558823529411766f,
+                            0.9560439560439562f, 1f, 1f},
+                    new float[]{0.2235294117647059f, 0.3f, 0.38431372549019605f,
+                            0.492156862745098f, 0.5843137254901961f, 0.6647058823529411f,
+                            0.7333333333333334f, 0.8215686274509804f, 0.9f,
+                            0.9411764705882353f}
+            ),
+            new TonalPalette(
+                    new float[]{0.6666666666666666f, 0.6666666666666666f,
+                            0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
+                            0.6666666666666666f, 0.6666666666666666f, 0.6666666666666666f,
+                            0.6666666666666666f, 0.6666666666666666f},
+                    new float[]{0.24590163934426232f, 0.17880794701986752f,
+                            0.14606741573033713f, 0.13761467889908252f, 0.14893617021276592f,
+                            0.16756756756756758f, 0.20312500000000017f,
+                            0.26086956521739135f, 0.29999999999999966f, 0.5000000000000004f},
+                    new float[]{0.2392156862745098f, 0.296078431372549f,
+                            0.34901960784313724f, 0.4274509803921569f, 0.5392156862745098f,
+                            0.6372549019607843f, 0.7490196078431373f, 0.8196078431372549f,
+                            0.8823529411764706f, 0.9372549019607843f}
+            ),
+            new TonalPalette(
+                    new float[]{0.9678571428571429f, 0.9944812362030905f, 0f, 0f,
+                            0.0047348484848484815f, 0.00316455696202532f, 0f,
+                            0.9980392156862745f, 0.9814814814814816f, 0.9722222222222221f},
+                    new float[]{1f, 0.7023255813953488f, 0.6638655462184874f,
+                            0.6521739130434782f, 0.7719298245614035f, 0.8315789473684211f,
+                            0.6867469879518071f, 0.7264957264957265f, 0.8181818181818182f,
+                            0.8181818181818189f},
+                    new float[]{0.27450980392156865f, 0.4215686274509804f,
+                            0.4666666666666667f, 0.503921568627451f, 0.5529411764705883f,
+                            0.6274509803921569f, 0.6745098039215687f, 0.7705882352941176f,
+                            0.892156862745098f, 0.9568627450980391f}
+            ),
+            new TonalPalette(
+                    new float[]{0.9052287581699346f, 0.9112021857923498f, 0.9270152505446624f,
+                            0.9343137254901961f, 0.9391534391534391f, 0.9437984496124031f,
+                            0.943661971830986f, 0.9438943894389439f, 0.9426229508196722f,
+                            0.9444444444444444f},
+                    new float[]{1f, 0.8133333333333332f, 0.7927461139896375f, 0.7798165137614679f,
+                            0.7777777777777779f, 0.8190476190476191f, 0.8255813953488372f,
+                            0.8211382113821142f, 0.8133333333333336f, 0.8000000000000006f},
+                    new float[]{0.2f, 0.29411764705882354f, 0.3784313725490196f,
+                            0.42745098039215684f, 0.4764705882352941f, 0.5882352941176471f,
+                            0.6627450980392157f, 0.7588235294117647f, 0.8529411764705882f,
+                            0.9411764705882353f}
+            ),
+            new TonalPalette(
+                    new float[]{0.6884057971014492f, 0.6974789915966387f, 0.7079889807162534f,
+                            0.7154471544715447f, 0.7217741935483872f, 0.7274143302180687f,
+                            0.7272727272727273f, 0.7258064516129031f, 0.7252252252252251f,
+                            0.7333333333333333f},
+                    new float[]{0.8214285714285715f, 0.6878612716763006f, 0.6080402010050251f,
+                            0.5774647887323943f, 0.5391304347826086f, 0.46724890829694316f,
+                            0.4680851063829788f, 0.462686567164179f, 0.45679012345678977f,
+                            0.4545454545454551f},
+                    new float[]{0.2196078431372549f, 0.33921568627450976f, 0.39019607843137255f,
+                            0.4176470588235294f, 0.45098039215686275f,
+                            0.5509803921568628f, 0.6313725490196078f, 0.7372549019607844f,
+                            0.8411764705882353f, 0.9352941176470588f}
+            ),
+            new TonalPalette(
+                    new float[]{0.6470588235294118f, 0.6516666666666667f, 0.6464174454828661f,
+                            0.6441441441441442f, 0.6432748538011696f, 0.6416666666666667f,
+                            0.6402439024390243f, 0.6412429378531074f, 0.6435185185185186f,
+                            0.6428571428571429f},
+                    new float[]{0.8095238095238095f, 0.6578947368421053f, 0.5721925133689839f,
+                            0.5362318840579711f, 0.5f, 0.4424778761061947f, 0.44086021505376327f,
+                            0.44360902255639095f,
+                            0.4499999999999997f, 0.4375000000000006f},
+                    new float[]{0.16470588235294117f, 0.2980392156862745f, 0.36666666666666664f,
+                            0.40588235294117647f, 0.44705882352941173f,
+                            0.5568627450980392f, 0.6352941176470588f, 0.7392156862745098f,
+                            0.8431372549019608f, 0.9372549019607843f}
+            ),
+            new TonalPalette(
+                    new float[]{0.46732026143790845f, 0.4718614718614719f, 0.4793650793650794f,
+                            0.48071625344352614f, 0.4829683698296837f, 0.484375f,
+                            0.4841269841269842f, 0.48444444444444457f, 0.48518518518518516f,
+                            0.4907407407407408f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 0.6274509803921569f, 0.41832669322709176f,
+                            0.41899441340782106f, 0.4128440366972478f,
+                            0.4090909090909088f},
+                    new float[]{0.1f, 0.15098039215686274f, 0.20588235294117646f,
+                            0.2372549019607843f, 0.26862745098039215f, 0.4f, 0.5078431372549019f,
+                            0.6490196078431372f, 0.7862745098039216f, 0.9137254901960784f}
+            ),
+            new TonalPalette(
+                    new float[]{0.5444444444444444f, 0.5555555555555556f, 0.5555555555555556f,
+                            0.553763440860215f, 0.5526315789473684f, 0.5555555555555556f,
+                            0.5555555555555555f, 0.5555555555555556f, 0.5512820512820514f,
+                            0.5666666666666667f},
+                    new float[]{0.24590163934426232f, 0.19148936170212766f, 0.1791044776119403f,
+                            0.18343195266272191f, 0.18446601941747576f,
+                            0.1538461538461539f, 0.15625000000000003f, 0.15328467153284678f,
+                            0.15662650602409653f, 0.151515151515151f},
+                    new float[]{0.1196078431372549f, 0.1843137254901961f, 0.2627450980392157f,
+                            0.33137254901960783f, 0.403921568627451f, 0.5411764705882354f,
+                            0.6235294117647059f, 0.7313725490196079f, 0.8372549019607843f,
+                            0.9352941176470588f}
+            ),
+            new TonalPalette(
+                    new float[]{0.022222222222222223f, 0.02469135802469136f, 0.031249999999999997f,
+                            0.03947368421052631f, 0.04166666666666668f,
+                            0.043650793650793655f, 0.04411764705882352f, 0.04166666666666652f,
+                            0.04444444444444459f, 0.05555555555555529f},
+                    new float[]{0.33333333333333337f, 0.2783505154639175f, 0.2580645161290323f,
+                            0.25675675675675674f, 0.2528735632183908f, 0.17500000000000002f,
+                            0.15315315315315312f, 0.15189873417721522f,
+                            0.15789473684210534f, 0.15789473684210542f},
+                    new float[]{0.08823529411764705f, 0.19019607843137254f, 0.2431372549019608f,
+                            0.2901960784313725f, 0.3411764705882353f, 0.47058823529411764f,
+                            0.5647058823529412f, 0.6901960784313725f, 0.8137254901960784f,
+                            0.9254901960784314f}
+            ),
+            new TonalPalette(
+                    new float[]{0.050884955752212385f, 0.07254901960784313f, 0.0934640522875817f,
+                            0.10457516339869281f, 0.11699346405228758f,
+                            0.1255813953488372f, 0.1268939393939394f, 0.12533333333333332f,
+                            0.12500000000000003f, 0.12777777777777777f},
+                    new float[]{1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f, 1f},
+                    new float[]{0.44313725490196076f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5784313725490196f,
+                            0.6549019607843137f, 0.7549019607843137f, 0.8509803921568627f,
+                            0.9411764705882353f}
+            )
+    };
+
+    @SuppressWarnings("WeakerAccess")
+    static final ColorRange[] BLACKLISTED_COLORS = new ColorRange[] {
+
+            // Red
+            new ColorRange(
+                    new Range<>(0f, 20f) /* H */,
+                    new Range<>(0.7f, 1f) /* S */,
+                    new Range<>(0.21f, 0.79f)) /* L */,
+            new ColorRange(
+                    new Range<>(0f, 20f),
+                    new Range<>(0.3f, 0.7f),
+                    new Range<>(0.355f, 0.653f)),
+
+            // Red Orange
+            new ColorRange(
+                    new Range<>(20f, 40f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.28f, 0.643f)),
+            new ColorRange(
+                    new Range<>(20f, 40f),
+                    new Range<>(0.3f, 0.7f),
+                    new Range<>(0.414f, 0.561f)),
+            new ColorRange(
+                    new Range<>(20f, 40f),
+                    new Range<>(0f, 3f),
+                    new Range<>(0.343f, 0.584f)),
+
+            // Orange
+            new ColorRange(
+                    new Range<>(40f, 60f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.173f, 0.349f)),
+            new ColorRange(
+                    new Range<>(40f, 60f),
+                    new Range<>(0.3f, 0.7f),
+                    new Range<>(0.233f, 0.427f)),
+            new ColorRange(
+                    new Range<>(40f, 60f),
+                    new Range<>(0f, 0.3f),
+                    new Range<>(0.231f, 0.484f)),
+
+            // Yellow 60
+            new ColorRange(
+                    new Range<>(60f, 80f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.488f, 0.737f)),
+            new ColorRange(
+                    new Range<>(60f, 80f),
+                    new Range<>(0.3f, 0.7f),
+                    new Range<>(0.673f, 0.837f)),
+
+            // Yellow Green 80
+            new ColorRange(
+                    new Range<>(80f, 100f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.469f, 0.61f)),
+
+            // Yellow green 100
+            new ColorRange(
+                    new Range<>(100f, 120f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.388f, 0.612f)),
+            new ColorRange(
+                    new Range<>(100f, 120f),
+                    new Range<>(0.3f, 0.7f),
+                    new Range<>(0.424f, 0.541f)),
+
+            // Green
+            new ColorRange(
+                    new Range<>(120f, 140f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.375f, 0.52f)),
+            new ColorRange(
+                    new Range<>(120f, 140f),
+                    new Range<>(0.3f, 0.7f),
+                    new Range<>(0.435f, 0.524f)),
+
+            // Green Blue 140
+            new ColorRange(
+                    new Range<>(140f, 160f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.496f, 0.641f)),
+
+            // Seafoam
+            new ColorRange(
+                    new Range<>(160f, 180f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.496f, 0.567f)),
+
+            // Cyan
+            new ColorRange(
+                    new Range<>(180f, 200f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.52f, 0.729f)),
+
+            // Blue
+            new ColorRange(
+                    new Range<>(220f, 240f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.396f, 0.571f)),
+            new ColorRange(
+                    new Range<>(220f, 240f),
+                    new Range<>(0.3f, 0.7f),
+                    new Range<>(0.425f, 0.551f)),
+
+            // Blue Purple 240
+            new ColorRange(
+                    new Range<>(240f, 260f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.418f, 0.639f)),
+            new ColorRange(
+                    new Range<>(220f, 240f),
+                    new Range<>(0.3f, 0.7f),
+                    new Range<>(0.441f, 0.576f)),
+
+            // Blue Purple 260
+            new ColorRange(
+                    new Range<>(260f, 280f),
+                    new Range<>(0.3f, 1f), // Bigger range
+                    new Range<>(0.461f, 0.553f)),
+
+            // Fuchsia
+            new ColorRange(
+                    new Range<>(300f, 320f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.484f, 0.588f)),
+            new ColorRange(
+                    new Range<>(300f, 320f),
+                    new Range<>(0.3f, 0.7f),
+                    new Range<>(0.48f, 0.592f)),
+
+            // Pink
+            new ColorRange(
+                    new Range<>(320f, 340f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.466f, 0.629f)),
+
+            // Soft red
+            new ColorRange(
+                    new Range<>(340f, 360f),
+                    new Range<>(0.7f, 1f),
+                    new Range<>(0.437f, 0.596f))
+    };
+
+    /**
+     * Representation of an HSL color range.
+     * <ul>
+     * <li>hsl[0] is Hue [0 .. 360)</li>
+     * <li>hsl[1] is Saturation [0...1]</li>
+     * <li>hsl[2] is Lightness [0...1]</li>
+     * </ul>
+     */
+    static class ColorRange {
+        private Range<Float> mHue;
+        private Range<Float> mSaturation;
+        private Range<Float> mLightness;
+
+        ColorRange(Range<Float> hue, Range<Float> saturation, Range<Float> lightness) {
+            mHue = hue;
+            mSaturation = saturation;
+            mLightness = lightness;
+        }
+
+        boolean containsColor(float h, float s, float l) {
+            if (!mHue.contains(h)) {
+                return false;
+            } else if (!mSaturation.contains(s)) {
+                return false;
+            } else if (!mLightness.contains(l)) {
+                return false;
+            }
+            return true;
+        }
+
+        float[] getCenter() {
+            return new float[] {
+                    mHue.getLower() + (mHue.getUpper() - mHue.getLower()) / 2f,
+                    mSaturation.getLower() + (mSaturation.getUpper() - mSaturation.getLower()) / 2f,
+                    mLightness.getLower() + (mLightness.getUpper() - mLightness.getLower()) / 2f
+            };
+        }
+
+        @Override
+        public String toString() {
+            return String.format("H: %s, S: %s, L %s", mHue, mSaturation, mLightness);
+        }
+    }
+
+}
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionService.java b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
index a2e118e..b9dd3b5 100644
--- a/src/com/android/launcher3/dynamicui/ColorExtractionService.java
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
@@ -21,6 +21,7 @@
 import android.app.job.JobParameters;
 import android.app.job.JobService;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.graphics.BitmapRegionDecoder;
 import android.graphics.Rect;
 import android.graphics.drawable.BitmapDrawable;
@@ -82,6 +83,10 @@
                 if (wallpaperManager.getWallpaperInfo() != null) {
                     // We can't extract colors from live wallpapers; always use the default color.
                     extractedColors.updateHotseatPalette(null);
+
+                    if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+                        extractedColors.updateWallpaperThemePalette(null);
+                    }
                 } else {
                     // We extract colors for the hotseat and status bar separately,
                     // since they only consider part of the wallpaper.
@@ -90,6 +95,10 @@
                     if (FeatureFlags.LIGHT_STATUS_BAR) {
                         extractedColors.updateStatusBarPalette(getStatusBarPalette());
                     }
+
+                    if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+                        extractedColors.updateWallpaperThemePalette(getWallpaperPalette());
+                    }
                 }
 
                 // Save the extracted colors and wallpaper id to LauncherProvider.
@@ -173,4 +182,23 @@
                 .clearFilters()
                 .generate();
     }
+
+    @TargetApi(Build.VERSION_CODES.N)
+    private Palette getWallpaperPalette() {
+        WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
+        if (Utilities.ATLEAST_NOUGAT) {
+            try (ParcelFileDescriptor fd = wallpaperManager
+                    .getWallpaperFile(WallpaperManager.FLAG_SYSTEM)) {
+                Bitmap bitmap = BitmapFactory.decodeFileDescriptor(fd.getFileDescriptor());
+                if (bitmap != null) {
+                    return Palette.from(bitmap).clearFilters().generate();
+                }
+            } catch (IOException | NullPointerException e) {
+                Log.e(TAG, "Fetching partial bitmap failed, trying old method", e);
+            }
+        }
+
+        Bitmap wallpaper = ((BitmapDrawable) wallpaperManager.getDrawable()).getBitmap();
+        return Palette.from(wallpaper).clearFilters().generate();
+    }
 }
diff --git a/src/com/android/launcher3/dynamicui/ExtractedColors.java b/src/com/android/launcher3/dynamicui/ExtractedColors.java
index 711508e..2d8bb86 100644
--- a/src/com/android/launcher3/dynamicui/ExtractedColors.java
+++ b/src/com/android/launcher3/dynamicui/ExtractedColors.java
@@ -16,13 +16,19 @@
 
 package com.android.launcher3.dynamicui;
 
+import android.app.WallpaperManager;
 import android.content.Context;
 import android.graphics.Color;
+import android.support.annotation.Nullable;
 import android.support.v4.graphics.ColorUtils;
 import android.support.v7.graphics.Palette;
 import android.util.Log;
 
 import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
+
+import java.util.ArrayList;
+import java.util.Arrays;
 
 /**
  * Saves and loads colors extracted from the wallpaper, as well as the associated wallpaper id.
@@ -32,31 +38,56 @@
 
     public static final int DEFAULT_LIGHT = Color.WHITE;
     public static final int DEFAULT_DARK = Color.BLACK;
-    public static final int DEFAULT_COLOR = DEFAULT_LIGHT;
 
     // These color profile indices should NOT be changed, since they are used when saving and
     // loading extracted colors. New colors should always be added at the end.
     public static final int VERSION_INDEX = 0;
     public static final int HOTSEAT_INDEX = 1;
     public static final int STATUS_BAR_INDEX = 2;
-    // public static final int VIBRANT_INDEX = 2;
-    // public static final int VIBRANT_DARK_INDEX = 3;
-    // public static final int VIBRANT_LIGHT_INDEX = 4;
-    // public static final int MUTED_INDEX = 5;
-    // public static final int MUTED_DARK_INDEX = 6;
-    // public static final int MUTED_LIGHT_INDEX = 7;
+    public static final int WALLPAPER_VIBRANT_INDEX = 3;
+    public static final int ALLAPPS_GRADIENT_MAIN_INDEX = 4;
+    public static final int ALLAPPS_GRADIENT_SECONDARY_INDEX = 5;
 
-    public static final int NUM_COLOR_PROFILES = 2;
-    private static final int VERSION = 1;
+    private static final int VERSION;
+    private static final int[] DEFAULT_VALUES;
+
+    static {
+        if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
+            VERSION = 3;
+            DEFAULT_VALUES = new int[] {
+                    VERSION,            // VERSION_INDEX
+                    0x40FFFFFF,         // HOTSEAT_INDEX: White with 25% alpha
+                    DEFAULT_DARK,       // STATUS_BAR_INDEX
+                    0xFFCCCCCC,         // WALLPAPER_VIBRANT_INDEX
+                    0xFF000000,         // ALLAPPS_GRADIENT_MAIN_INDEX
+                    0xFF000000          // ALLAPPS_GRADIENT_SECONDARY_INDEX
+            };
+        } else if (FeatureFlags.QSB_IN_HOTSEAT) {
+            VERSION = 2;
+            DEFAULT_VALUES = new int[] {
+                    VERSION,            // VERSION_INDEX
+                    0x40FFFFFF,         // HOTSEAT_INDEX: White with 25% alpha
+                    DEFAULT_DARK,       // STATUS_BAR_INDEX
+                    0xFFCCCCCC,         // WALLPAPER_VIBRANT_INDEX
+            };
+        } else {
+            VERSION = 1;
+            DEFAULT_VALUES = new int[] {
+                    VERSION,            // VERSION_INDEX
+                    0x40FFFFFF,         // HOTSEAT_INDEX: White with 25% alpha
+                    DEFAULT_DARK,       // STATUS_BAR_INDEX
+            };
+        }
+    }
 
     private static final String COLOR_SEPARATOR = ",";
 
-    private int[] mColors;
+    private final ArrayList<OnChangeListener> mListeners = new ArrayList<>();
+    private final int[] mColors;
 
     public ExtractedColors() {
         // The first entry is reserved for the version number.
-        mColors = new int[NUM_COLOR_PROFILES + 1];
-        mColors[VERSION_INDEX] = VERSION;
+        mColors = Arrays.copyOf(DEFAULT_VALUES, DEFAULT_VALUES.length);
     }
 
     public void setColorAtIndex(int index, int color) {
@@ -79,17 +110,6 @@
     }
 
     /**
-     * Decodes a comma-separated String into {@link #mColors}.
-     */
-    void decodeFromString(String colorsString) {
-        String[] splitColorsString = colorsString.split(COLOR_SEPARATOR);
-        mColors = new int[splitColorsString.length];
-        for (int i = 0; i < mColors.length; i++) {
-            mColors[i] = Integer.parseInt(splitColorsString[i]);
-        }
-    }
-
-    /**
      * Loads colors and wallpaper id from {@link Utilities#getPrefs(Context)}.
      * These were saved there in {@link ColorExtractionService}.
      */
@@ -97,19 +117,22 @@
         String encodedString = Utilities.getPrefs(context).getString(
                 ExtractionUtils.EXTRACTED_COLORS_PREFERENCE_KEY, VERSION + "");
 
-        decodeFromString(encodedString);
-
-        if (mColors[VERSION_INDEX] != VERSION) {
+        String[] splitColorsString = encodedString.split(COLOR_SEPARATOR);
+        if (splitColorsString.length == DEFAULT_VALUES.length &&
+                Integer.parseInt(splitColorsString[VERSION_INDEX]) == VERSION) {
+            // Parse and apply the saved values.
+            for (int i = 0; i < mColors.length; i++) {
+                mColors[i] = Integer.parseInt(splitColorsString[i]);
+            }
+        } else {
+            // Leave the values as default values as the saved values may not be compatible.
             ExtractionUtils.startColorExtractionService(context);
         }
     }
 
     /** @param index must be one of the index values defined at the top of this class. */
-    public int getColor(int index, int defaultColor) {
-        if (index > VERSION_INDEX && index < mColors.length) {
-            return mColors[index];
-        }
-        return defaultColor;
+    public int getColor(int index) {
+        return mColors[index];
     }
 
     /**
@@ -125,7 +148,7 @@
         } else if (hotseatPalette != null && ExtractionUtils.isSuperDark(hotseatPalette)) {
             hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.18f * 255));
         } else {
-            hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.25f * 255));
+            hotseatColor = DEFAULT_VALUES[HOTSEAT_INDEX];
         }
         setColorAtIndex(HOTSEAT_INDEX, hotseatColor);
     }
@@ -134,4 +157,28 @@
         setColorAtIndex(STATUS_BAR_INDEX, ExtractionUtils.isSuperLight(statusBarPalette) ?
                 DEFAULT_LIGHT : DEFAULT_DARK);
     }
+
+    public void updateWallpaperThemePalette(@Nullable Palette wallpaperPalette) {
+        int defaultColor = DEFAULT_VALUES[WALLPAPER_VIBRANT_INDEX];
+        setColorAtIndex(WALLPAPER_VIBRANT_INDEX, wallpaperPalette == null
+                ? defaultColor : wallpaperPalette.getVibrantColor(defaultColor));
+    }
+
+    public void addOnChangeListener(OnChangeListener listener) {
+        mListeners.add(listener);
+    }
+
+    public void notifyChange() {
+        for (OnChangeListener listener : mListeners) {
+            listener.onExtractedColorsChanged();
+        }
+    }
+
+    /**
+     * Interface for listening for extracted color changes
+     */
+    public interface OnChangeListener {
+
+        void onExtractedColorsChanged();
+    }
 }
diff --git a/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java b/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java
new file mode 100644
index 0000000..e23f42f
--- /dev/null
+++ b/src/com/android/launcher3/dynamicui/WallpaperColorInfo.java
@@ -0,0 +1,118 @@
+package com.android.launcher3.dynamicui;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.support.v4.graphics.ColorUtils;
+import android.util.Pair;
+
+import com.android.launcher3.compat.WallpaperColorsCompat;
+import com.android.launcher3.compat.WallpaperManagerCompat;
+
+import java.util.ArrayList;
+
+import static android.app.WallpaperManager.FLAG_SYSTEM;
+
+public class WallpaperColorInfo implements WallpaperManagerCompat.OnColorsChangedListenerCompat {
+
+    private static final int FALLBACK_COLOR = Color.WHITE;
+    private static final Object sInstanceLock = new Object();
+    private static WallpaperColorInfo sInstance;
+
+    public static WallpaperColorInfo getInstance(Context context) {
+        synchronized (sInstanceLock) {
+            if (sInstance == null) {
+                sInstance = new WallpaperColorInfo(context.getApplicationContext());
+            }
+            return sInstance;
+        }
+    }
+
+    private final ArrayList<OnChangeListener> mListeners = new ArrayList<>();
+    private final WallpaperManagerCompat mWallpaperManager;
+    private final ColorExtractionAlgorithm mExtractionType;
+    private int mMainColor;
+    private int mSecondaryColor;
+    private boolean mIsDark;
+    private boolean mSupportsDarkText;
+    private OnThemeChangeListener mOnThemeChangeListener;
+
+    private WallpaperColorInfo(Context context) {
+        mWallpaperManager = WallpaperManagerCompat.getInstance(context);
+        mWallpaperManager.addOnColorsChangedListener(this);
+        mExtractionType = ColorExtractionAlgorithm.newInstance(context);
+        update(mWallpaperManager.getWallpaperColors(FLAG_SYSTEM));
+    }
+
+    public int getMainColor() {
+        return mMainColor;
+    }
+
+    public int getSecondaryColor() {
+        return mSecondaryColor;
+    }
+
+    public boolean isDark() {
+        return mIsDark;
+    }
+
+    public boolean supportsDarkText() {
+        return mSupportsDarkText;
+    }
+
+    @Override
+    public void onColorsChanged(WallpaperColorsCompat colors, int which) {
+        if (which == FLAG_SYSTEM) {
+            boolean wasDarkTheme = mIsDark;
+            boolean didSupportDarkText = mSupportsDarkText;
+            update(colors);
+            notifyChange(wasDarkTheme != mIsDark || didSupportDarkText != mSupportsDarkText);
+        }
+    }
+
+    private void update(WallpaperColorsCompat wallpaperColors) {
+        Pair<Integer, Integer> colors = mExtractionType.extractInto(wallpaperColors);
+        if (colors != null) {
+            mMainColor = colors.first;
+            mSecondaryColor = colors.second;
+        } else {
+            mMainColor = FALLBACK_COLOR;
+            mSecondaryColor = FALLBACK_COLOR;
+        }
+        mSupportsDarkText = wallpaperColors != null ? wallpaperColors.supportsDarkText() : false;
+        float[] hsl = new float[3];
+        ColorUtils.colorToHSL(mMainColor, hsl);
+        mIsDark = hsl[2] < 0.2f;
+    }
+
+    public void setOnThemeChangeListener(OnThemeChangeListener onThemeChangeListener) {
+        this.mOnThemeChangeListener = onThemeChangeListener;
+    }
+
+    public void addOnChangeListener(OnChangeListener listener) {
+        mListeners.add(listener);
+    }
+
+    public void removeOnChangeListener(OnChangeListener listener) {
+        mListeners.remove(listener);
+    }
+
+    public void notifyChange(boolean themeChanged) {
+        if (themeChanged) {
+            if (mOnThemeChangeListener != null) {
+                mOnThemeChangeListener.onThemeChanged();
+            }
+        } else {
+            for (OnChangeListener listener : mListeners) {
+                listener.onExtractedColorsChanged(this);
+            }
+        }
+    }
+
+    public interface OnChangeListener {
+        void onExtractedColorsChanged(WallpaperColorInfo wallpaperColorInfo);
+    }
+
+    public interface OnThemeChangeListener {
+        void onThemeChanged();
+    }
+}
diff --git a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
index 840fcf5..0df787a 100644
--- a/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
+++ b/src/com/android/launcher3/folder/ClippedFolderIconLayoutRule.java
@@ -1,12 +1,5 @@
 package com.android.launcher3.folder;
 
-import android.view.View;
-
-import com.android.launcher3.config.FeatureFlags;
-
-import java.util.ArrayList;
-import java.util.List;
-
 public class ClippedFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
 
     static final int MAX_NUM_ITEMS_IN_PREVIEW = 4;
@@ -121,6 +114,11 @@
     }
 
     @Override
+    public float getIconSize() {
+        return mIconSize;
+    }
+
+    @Override
     public int maxNumItems() {
         return MAX_NUM_ITEMS_IN_PREVIEW;
     }
@@ -129,24 +127,4 @@
     public boolean clipToBackground() {
         return true;
     }
-
-    @Override
-    public List<View> getItemsToDisplay(Folder folder) {
-        List<View> items = new ArrayList<>(folder.getItemsInReadingOrder());
-        int numItems = items.size();
-        if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION && numItems > MAX_NUM_ITEMS_IN_PREVIEW) {
-            // We match the icons in the preview with the layout of the opened folder (b/27944225),
-            // but we still need to figure out how we want to handle updating the preview when the
-            // upper left quadrant changes.
-            int appsPerRow = folder.mContent.getPageAt(0).getCountX();
-            int appsToDelete = appsPerRow - MAX_NUM_ITEMS_PER_ROW;
-
-            // We only display the upper left quadrant.
-            while (appsToDelete > 0) {
-                items.remove(MAX_NUM_ITEMS_PER_ROW);
-                appsToDelete--;
-            }
-        }
-        return items.subList(0, Math.min(numItems, MAX_NUM_ITEMS_IN_PREVIEW));
-    }
 }
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 93c9ea8..80338ca 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -34,7 +34,6 @@
 import android.view.KeyEvent;
 import android.view.Menu;
 import android.view.MenuItem;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewDebug;
 import android.view.accessibility.AccessibilityEvent;
@@ -46,6 +45,7 @@
 import com.android.launcher3.AbstractFloatingView;
 import com.android.launcher3.Alarm;
 import com.android.launcher3.AppInfo;
+import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.DragSource;
@@ -60,14 +60,16 @@
 import com.android.launcher3.LogDecelerateInterpolator;
 import com.android.launcher3.OnAlarmListener;
 import com.android.launcher3.PagedView;
+import com.android.launcher3.PendingAddItemInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.UninstallDropTarget.DropTargetSource;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace.ItemOperator;
 import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
+import com.android.launcher3.anim.AnimationLayerSet;
+import com.android.launcher3.anim.CircleRevealOutlineProvider;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragController.DragListener;
 import com.android.launcher3.dragndrop.DragLayer;
@@ -75,12 +77,13 @@
 import com.android.launcher3.pageindicators.PageIndicatorDots;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import com.android.launcher3.util.CircleRevealOutlineProvider;
 import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.PendingAddShortcutInfo;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
+import java.util.List;
 
 /**
  * Represents a set of icons chosen by the user or generated by the system.
@@ -133,8 +136,10 @@
 
     @Thunk final ArrayList<View> mItemsInReadingOrder = new ArrayList<View>();
 
+    private AnimatorSet mCurrentAnimator;
+
     private final int mExpandDuration;
-    private final int mMaterialExpandDuration;
+    public final int mMaterialExpandDuration;
     private final int mMaterialExpandStagger;
 
     protected final Launcher mLauncher;
@@ -501,51 +506,31 @@
         mState = STATE_SMALL;
     }
 
-    /**
-     * Opens the user folder described by the specified tag. The opening of the folder
-     * is animated relative to the specified View. If the View is null, no animation
-     * is played.
-     */
-    public void animateOpen() {
-        Folder openFolder = getOpen(mLauncher);
-        if (openFolder != null && openFolder != this) {
-            // Close any open folder before opening a folder.
-            openFolder.close(true);
+    private void startAnimation(final AnimatorSet a) {
+        if (mCurrentAnimator != null && mCurrentAnimator.isRunning()) {
+            mCurrentAnimator.cancel();
         }
-
-        DragLayer dragLayer = mLauncher.getDragLayer();
-        // Just verify that the folder hasn't already been added to the DragLayer.
-        // There was a one-off crash where the folder had a parent already.
-        if (getParent() == null) {
-            dragLayer.addView(this);
-            mDragController.addDropTarget(this);
-        } else {
-            if (ProviderConfig.IS_DOGFOOD_BUILD) {
-                Log.e(TAG, "Opening folder (" + this + ") which already has a parent:"
-                        + getParent());
+        a.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationStart(Animator animation) {
+                mState = STATE_ANIMATING;
+                mCurrentAnimator = a;
             }
-        }
 
-        mIsOpen = true;
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                mCurrentAnimator = null;
+            }
+        });
+        a.start();
+    }
 
-        mContent.completePendingPageChanges();
-        if (!mDragInProgress) {
-            // Open on the first page.
-            mContent.snapToPageImmediately(0);
-        }
-
-        // This is set to true in close(), but isn't reset to false until onDropCompleted(). This
-        // leads to an inconsistent state if you drag out of the folder and drag back in without
-        // dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice.
-        mDeleteFolderOnDropCompleted = false;
-
-        final Runnable onCompleteRunnable;
+    private AnimatorSet getOpeningAnimator() {
         prepareReveal();
-        centerAboutIcon();
-
         mFolderIcon.growAndFadeOut();
 
         AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
+
         int width = getFolderWidth();
         int height = getFolderHeight();
 
@@ -587,24 +572,76 @@
         anim.play(textAlpha);
         anim.play(reveal);
 
-        mContent.setLayerType(LAYER_TYPE_HARDWARE, null);
-        mFooter.setLayerType(LAYER_TYPE_HARDWARE, null);
+        AnimationLayerSet layerSet = new AnimationLayerSet();
+        layerSet.addView(mContent);
+        layerSet.addView(mFooter);
+        anim.addListener(layerSet);
+
+        return anim;
+    }
+
+    /**
+     * Opens the user folder described by the specified tag. The opening of the folder
+     * is animated relative to the specified View. If the View is null, no animation
+     * is played.
+     */
+    public void animateOpen() {
+        Folder openFolder = getOpen(mLauncher);
+        if (openFolder != null && openFolder != this) {
+            // Close any open folder before opening a folder.
+            openFolder.close(true);
+        }
+
+        DragLayer dragLayer = mLauncher.getDragLayer();
+        // Just verify that the folder hasn't already been added to the DragLayer.
+        // There was a one-off crash where the folder had a parent already.
+        if (getParent() == null) {
+            dragLayer.addView(this);
+            mDragController.addDropTarget(this);
+        } else {
+            if (FeatureFlags.IS_DOGFOOD_BUILD) {
+                Log.e(TAG, "Opening folder (" + this + ") which already has a parent:"
+                        + getParent());
+            }
+        }
+
+        mIsOpen = true;
+
+        mContent.completePendingPageChanges();
+        if (!mDragInProgress) {
+            // Open on the first page.
+            mContent.snapToPageImmediately(0);
+        }
+
+        // This is set to true in close(), but isn't reset to false until onDropCompleted(). This
+        // leads to an inconsistent state if you drag out of the folder and drag back in without
+        // dropping. One resulting issue is that replaceFolderWithFinalItem() can be called twice.
+        mDeleteFolderOnDropCompleted = false;
+
+        final Runnable onCompleteRunnable;
+        centerAboutIcon();
+
+        AnimatorSet anim = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION
+                ? new FolderAnimationManager(this, true /* isOpening */).getAnimator()
+                : getOpeningAnimator();
         onCompleteRunnable = new Runnable() {
             @Override
             public void run() {
-                mContent.setLayerType(LAYER_TYPE_NONE, null);
-                mFooter.setLayerType(LAYER_TYPE_NONE, null);
                 mLauncher.getUserEventDispatcher().resetElapsedContainerMillis();
             }
         };
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationStart(Animator animation) {
+                if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+                    mFolderIcon.drawLeaveBehindIfExists();
+                    mFolderIcon.setVisibility(INVISIBLE);
+                }
+
                 Utilities.sendCustomAccessibilityEvent(
                         Folder.this,
                         AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
                         mContent.getAccessibilityDescription());
-                mState = STATE_ANIMATING;
             }
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -650,7 +687,7 @@
         }
 
         mPageIndicator.stopAllAnimations();
-        anim.start();
+        startAnimation(anim);
 
         // Make sure the folder picks up the last drag move even if the finger doesn't move.
         if (mDragController.isDragging()) {
@@ -689,7 +726,11 @@
         }
 
         if (mFolderIcon != null) {
-            mFolderIcon.shrinkAndFadeIn(animate);
+            if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+                mFolderIcon.clearLeaveBehindIfExists();
+            } else {
+                mFolderIcon.shrinkAndFadeIn(animate);
+            }
         }
 
         if (!(getParent() instanceof DragLayer)) return;
@@ -706,12 +747,24 @@
         parent.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
     }
 
+    private AnimatorSet getClosingAnimator() {
+        AnimatorSet animatorSet = LauncherAnimUtils.createAnimatorSet();
+        animatorSet.play(LauncherAnimUtils.ofViewAlphaAndScale(this, 0, 0.9f, 0.9f));
+
+        AnimationLayerSet layerSet = new AnimationLayerSet();
+        layerSet.addView(this);
+        animatorSet.addListener(layerSet);
+        animatorSet.setDuration(mExpandDuration);
+        return animatorSet;
+    }
+
     private void animateClosed() {
-        final ObjectAnimator oa = LauncherAnimUtils.ofViewAlphaAndScale(this, 0, 0.9f, 0.9f);
-        oa.addListener(new AnimatorListenerAdapter() {
+        AnimatorSet a = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION
+                ? new FolderAnimationManager(this, false /* isOpening */).getAnimator()
+                : getClosingAnimator();
+        a.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                setLayerType(LAYER_TYPE_NONE, null);
                 closeComplete(true);
             }
             @Override
@@ -720,12 +773,9 @@
                         Folder.this,
                         AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
                         getContext().getString(R.string.folder_closed));
-                mState = STATE_ANIMATING;
             }
         });
-        oa.setDuration(mExpandDuration);
-        setLayerType(LAYER_TYPE_HARDWARE, null);
-        oa.start();
+        startAnimation(a);
     }
 
     private void closeComplete(boolean wasAnimated) {
@@ -736,8 +786,12 @@
         }
         mDragController.removeDropTarget(this);
         clearFocus();
-        if (wasAnimated) {
-            mFolderIcon.requestFocus();
+        if (mFolderIcon != null) {
+            mFolderIcon.setVisibility(View.VISIBLE);
+            if (wasAnimated) {
+                mFolderIcon.mBackground.animateBackgroundStroke();
+                mFolderIcon.requestFocus();
+            }
         }
 
         if (mRearrangeOnClose) {
@@ -1027,6 +1081,9 @@
     }
 
     public boolean isDropEnabled() {
+        if (FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION) {
+            return mState != STATE_ANIMATING;
+        }
         return true;
     }
 
@@ -1288,53 +1345,68 @@
         }
         mContent.completePendingPageChanges();
 
-        View currentDragView;
-        final ShortcutInfo si;
-        if (d.dragInfo instanceof AppInfo) {
-            // Came from all apps -- make a copy.
-            si = ((AppInfo) d.dragInfo).makeShortcut();
-        } else {
-            // ShortcutInfo
-            si = (ShortcutInfo) d.dragInfo;
-        }
-        if (mIsExternalDrag) {
-            currentDragView = mContent.createAndAddViewForRank(si, mEmptyCellRank);
-            // Actually move the item in the database if it was an external drag. Call this
-            // before creating the view, so that ShortcutInfo is updated appropriately.
-            mLauncher.getModelWriter().addOrMoveItemInDatabase(
-                    si, mInfo.id, 0, si.cellX, si.cellY);
+        if (d.dragInfo instanceof PendingAddShortcutInfo) {
+            PendingAddShortcutInfo pasi = (PendingAddShortcutInfo) d.dragInfo;
+            pasi.container = mInfo.id;
+            pasi.rank = mEmptyCellRank;
 
-            // We only need to update the locations if it doesn't get handled in #onDropCompleted.
-            if (d.dragSource != this) {
-                updateItemLocationsInDatabaseBatch();
-            }
-            mIsExternalDrag = false;
-        } else {
-            currentDragView = mCurrentDragView;
-            mContent.addViewForRank(currentDragView, si, mEmptyCellRank);
-        }
-
-        if (d.dragView.hasDrawn()) {
-
-            // Temporarily reset the scale such that the animation target gets calculated correctly.
-            float scaleX = getScaleX();
-            float scaleY = getScaleY();
-            setScaleX(1.0f);
-            setScaleY(1.0f);
-            mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, currentDragView,
-                    cleanUpRunnable, null);
-            setScaleX(scaleX);
-            setScaleY(scaleY);
-        } else {
+            mLauncher.addPendingItem(pasi, pasi.container, pasi.screenId, null, pasi.spanX,
+                    pasi.spanY);
             d.deferDragViewCleanupPostAnimation = false;
-            currentDragView.setVisibility(VISIBLE);
-        }
-        mItemsInvalidated = true;
-        rearrangeChildren();
+            mRearrangeOnClose = true;
+        } else {
+            final ShortcutInfo si;
+            if (d.dragInfo instanceof AppInfo) {
+                // Came from all apps -- make a copy.
+                si = ((AppInfo) d.dragInfo).makeShortcut();
+            } else {
+                // ShortcutInfo
+                si = (ShortcutInfo) d.dragInfo;
+            }
 
-        // Temporarily suppress the listener, as we did all the work already here.
-        try (SuppressInfoChanges s = new SuppressInfoChanges()) {
-            mInfo.add(si, false);
+            View currentDragView;
+            if (mIsExternalDrag) {
+                currentDragView = mContent.createAndAddViewForRank(si, mEmptyCellRank);
+
+                // Actually move the item in the database if it was an external drag. Call this
+                // before creating the view, so that ShortcutInfo is updated appropriately.
+                mLauncher.getModelWriter().addOrMoveItemInDatabase(
+                        si, mInfo.id, 0, si.cellX, si.cellY);
+
+                // We only need to update the locations if it doesn't get handled in
+                // #onDropCompleted.
+                if (d.dragSource != this) {
+                    updateItemLocationsInDatabaseBatch();
+                }
+                mIsExternalDrag = false;
+            } else {
+                currentDragView = mCurrentDragView;
+                mContent.addViewForRank(currentDragView, si, mEmptyCellRank);
+            }
+
+            if (d.dragView.hasDrawn()) {
+                // Temporarily reset the scale such that the animation target gets calculated
+                // correctly.
+                float scaleX = getScaleX();
+                float scaleY = getScaleY();
+                setScaleX(1.0f);
+                setScaleY(1.0f);
+                mLauncher.getDragLayer().animateViewIntoPosition(d.dragView, currentDragView,
+                        cleanUpRunnable, null);
+                setScaleX(scaleX);
+                setScaleY(scaleY);
+            } else {
+                d.deferDragViewCleanupPostAnimation = false;
+                currentDragView.setVisibility(VISIBLE);
+            }
+
+            mItemsInvalidated = true;
+            rearrangeChildren();
+
+            // Temporarily suppress the listener, as we did all the work already here.
+            try (SuppressInfoChanges s = new SuppressInfoChanges()) {
+                mInfo.add(si, false);
+            }
         }
 
         // Clear the drag info, as it is no longer being dragged.
@@ -1363,11 +1435,15 @@
     }
 
     @Override
-    public void onAdd(ShortcutInfo item) {
-        mContent.createAndAddViewForRank(item, mContent.allocateRankForNewItem());
+    public void onAdd(ShortcutInfo item, int rank) {
+        View view = mContent.createAndAddViewForRank(item, rank);
+        mLauncher.getModelWriter().addOrMoveItemInDatabase(item, mInfo.id, 0, item.cellX,
+                item.cellY);
+
+        ArrayList<View> items = new ArrayList<>(getItemsInReadingOrder());
+        items.add(rank, view);
+        mContent.arrangeChildren(items, items.size());
         mItemsInvalidated = true;
-        mLauncher.getModelWriter().addOrMoveItemInDatabase(
-                item, mInfo.id, 0, item.cellX, item.cellY);
     }
 
     public void onRemove(ShortcutInfo item) {
@@ -1427,6 +1503,26 @@
         return mItemsInReadingOrder;
     }
 
+    public List<BubbleTextView> getItemsOnCurrentPage() {
+        ArrayList<View> allItems = getItemsInReadingOrder();
+        int currentPage = mContent.getCurrentPage();
+        int lastPage = mContent.getPageCount() - 1;
+        int totalItemsInFolder = allItems.size();
+        int itemsPerPage = mContent.itemsPerPage();
+        int numItemsOnCurrentPage = currentPage == lastPage
+                ? totalItemsInFolder - (itemsPerPage * currentPage)
+                : itemsPerPage;
+
+        int startIndex = currentPage * itemsPerPage;
+        int endIndex = startIndex + numItemsOnCurrentPage;
+
+        List<BubbleTextView> itemsOnCurrentPage = new ArrayList<>(numItemsOnCurrentPage);
+        for (int i = startIndex; i < endIndex; ++i) {
+            itemsOnCurrentPage.add((BubbleTextView) allItems.get(i));
+        }
+        return itemsOnCurrentPage;
+    }
+
     public void onFocusChange(View v, boolean hasFocus) {
         if (v == mFolderName) {
             if (hasFocus) {
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
new file mode 100644
index 0000000..bee0bd4
--- /dev/null
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -0,0 +1,362 @@
+/*
+ * 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.folder;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.animation.TimeInterpolator;
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.Rect;
+import android.graphics.drawable.GradientDrawable;
+import android.support.v4.graphics.ColorUtils;
+import android.util.Property;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+
+import com.android.launcher3.BubbleTextView;
+import com.android.launcher3.CellLayout;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAnimUtils;
+import com.android.launcher3.R;
+import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
+import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.util.Themes;
+
+import java.util.List;
+
+/**
+ * Manages the opening and closing animations for a {@link Folder}.
+ *
+ * All of the animations are done in the Folder.
+ * ie. When the user taps on the FolderIcon, we immediately hide the FolderIcon and show the Folder
+ * in its place before starting the animation.
+ */
+public class FolderAnimationManager {
+
+    private Folder mFolder;
+    private FolderPagedView mContent;
+    private GradientDrawable mFolderBackground;
+
+    private FolderIcon mFolderIcon;
+    private FolderIcon.PreviewBackground mPreviewBackground;
+
+    private Context mContext;
+    private Launcher mLauncher;
+
+    private final boolean mIsOpening;
+
+    private final int mDuration;
+    private final int mDelay;
+
+    private final TimeInterpolator mFolderInterpolator;
+    private final TimeInterpolator mLargeFolderPreviewItemInterpolator;
+
+    private final FolderIcon.PreviewItemDrawingParams mTmpParams =
+            new FolderIcon.PreviewItemDrawingParams(0, 0, 0, 0);
+
+    private static final Property<View, Float> SCALE_PROPERTY =
+            new Property<View, Float>(Float.class, "scale") {
+                @Override
+                public Float get(View view) {
+                    return view.getScaleX();
+                }
+
+                @Override
+                public void set(View view, Float scale) {
+                    view.setScaleX(scale);
+                    view.setScaleY(scale);
+                }
+            };
+
+    private static final Property<List<BubbleTextView>, Integer> ITEMS_TEXT_COLOR_PROPERTY =
+            new Property<List<BubbleTextView>, Integer>(Integer.class, "textColor") {
+                @Override
+                public Integer get(List<BubbleTextView> items) {
+                    return items.get(0).getCurrentTextColor();
+                }
+
+                @Override
+                public void set(List<BubbleTextView> items, Integer color) {
+                    int size = items.size();
+
+                    for (int i = 0; i < size; ++i) {
+                        items.get(i).setTextColor(color);
+                    }
+                }
+            };
+
+    public FolderAnimationManager(Folder folder, boolean isOpening) {
+        mFolder = folder;
+        mContent = folder.mContent;
+        mFolderBackground = (GradientDrawable) mFolder.getBackground();
+
+        mFolderIcon = folder.mFolderIcon;
+        mPreviewBackground = mFolderIcon.mBackground;
+
+        mContext = folder.getContext();
+        mLauncher = folder.mLauncher;
+
+        mIsOpening = isOpening;
+
+        mDuration = mFolder.mMaterialExpandDuration;
+        mDelay = mContext.getResources().getInteger(R.integer.config_folderDelay);
+
+        mFolderInterpolator = AnimationUtils.loadInterpolator(mContext,
+                R.interpolator.folder_interpolator);
+        mLargeFolderPreviewItemInterpolator = AnimationUtils.loadInterpolator(mContext,
+                R.interpolator.large_folder_preview_item_interpolator);
+    }
+
+
+    /**
+     * Prepares the Folder for animating between open / closed states.
+     */
+    public AnimatorSet getAnimator() {
+        final DragLayer.LayoutParams lp = (DragLayer.LayoutParams) mFolder.getLayoutParams();
+        FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule();
+        final List<BubbleTextView> itemsInPreview = mFolderIcon.getItemsToDisplay();
+
+        // Match position of the FolderIcon
+        final Rect folderIconPos = new Rect();
+        float scaleRelativeToDragLayer = mLauncher.getDragLayer()
+                .getDescendantRectRelativeToSelf(mFolderIcon, folderIconPos);
+        float initialSize = (mFolderIcon.mBackground.getRadius() * 2) * scaleRelativeToDragLayer;
+
+        // Match size/scale of icons in the preview
+        float previewScale = rule.scaleForItem(0, itemsInPreview.size());
+        float previewSize = rule.getIconSize() * previewScale;
+        float initialScale = previewSize / itemsInPreview.get(0).getIconSize()
+                * scaleRelativeToDragLayer;
+        final float finalScale = 1f;
+        float scale = mIsOpening ? initialScale : finalScale;
+        mFolder.setScaleX(scale);
+        mFolder.setScaleY(scale);
+        mFolder.setPivotX(0);
+        mFolder.setPivotY(0);
+
+        // We want to create a small X offset for the preview items, so that they follow their
+        // expected path to their final locations. ie. an icon should not move right, if it's final
+        // location is to its left. This value is arbitrarily defined.
+        int previewItemOffsetX = (int) (previewSize / 2);
+        if (Utilities.isRtl(mContext.getResources())) {
+            previewItemOffsetX = (int) (lp.width * initialScale - initialSize - previewItemOffsetX);
+        }
+
+        final int paddingOffsetX = (int) ((mFolder.getPaddingLeft() + mContent.getPaddingLeft())
+                * initialScale);
+        final int paddingOffsetY = (int) ((mFolder.getPaddingTop() + mContent.getPaddingTop())
+                * initialScale);
+
+        // Background can have a scaled radius in drag and drop mode.
+        int radiusDiff = mFolderIcon.mBackground.getScaledRadius()
+                - mFolderIcon.mBackground.getRadius();
+
+        int initialX = folderIconPos.left + mFolderIcon.mBackground.getOffsetX() - paddingOffsetX
+                - previewItemOffsetX + radiusDiff;
+        int initialY = folderIconPos.top + mFolderIcon.mBackground.getOffsetY() - paddingOffsetY
+                + radiusDiff;
+        final float xDistance = initialX - lp.x;
+        final float yDistance = initialY - lp.y;
+
+        // Set up the Folder background.
+        final int finalColor = Themes.getAttrColor(mContext, android.R.attr.colorPrimary);
+        final int initialColor =
+                ColorUtils.setAlphaComponent(finalColor, mPreviewBackground.getBackgroundAlpha());
+        mFolderBackground.setColor(mIsOpening ? initialColor : finalColor);
+
+        // Initialize the Folder items' text.
+        final List<BubbleTextView> items = mFolder.getItemsOnCurrentPage();
+        final int finalTextColor = Themes.getAttrColor(mContext, android.R.attr.textColorSecondary);
+        ITEMS_TEXT_COLOR_PROPERTY.set(items, mIsOpening ? Color.TRANSPARENT
+                : finalTextColor);
+
+        // Set up the reveal animation that clips the Folder.
+        int totalOffsetX = paddingOffsetX + previewItemOffsetX;
+        Rect startRect = new Rect(
+                Math.round(totalOffsetX / initialScale),
+                Math.round(paddingOffsetY / initialScale),
+                Math.round((totalOffsetX + initialSize) / initialScale),
+                Math.round((paddingOffsetY + initialSize) / initialScale));
+        Rect endRect = new Rect(0, 0, lp.width, lp.height);
+        float initialRadius = initialSize / initialScale / 2f;
+        float finalRadius = Utilities.pxFromDp(2, mContext.getResources().getDisplayMetrics());
+
+        // Create the animators.
+        AnimatorSet a = LauncherAnimUtils.createAnimatorSet();
+
+        play(a, getAnimator(mFolder, View.TRANSLATION_X, xDistance, 0f));
+        play(a, getAnimator(mFolder, View.TRANSLATION_Y, yDistance, 0f));
+        play(a, getAnimator(mFolder, SCALE_PROPERTY, initialScale, finalScale));
+        play(a, getAnimator(items, ITEMS_TEXT_COLOR_PROPERTY, Color.TRANSPARENT, finalTextColor));
+        play(a, getAnimator(mFolderBackground, "color", initialColor, finalColor));
+        play(a, new RoundedRectRevealOutlineProvider(initialRadius, finalRadius, startRect,
+                endRect).createRevealAnimator(mFolder, !mIsOpening));
+
+        a.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator animation) {
+                super.onAnimationEnd(animation);
+                ITEMS_TEXT_COLOR_PROPERTY.set(items, finalTextColor);
+                mFolder.setTranslationX(0.0f);
+                mFolder.setTranslationY(0.0f);
+                mFolder.setScaleX(1f);
+                mFolder.setScaleY(1f);
+            }
+        });
+
+        // We set the interpolator on all current child animators here, because the preview item
+        // animators may use a different interpolator.
+        for (Animator animator : a.getChildAnimations()) {
+            animator.setInterpolator(mFolderInterpolator);
+        }
+
+        addPreviewItemAnimators(a, initialScale / scaleRelativeToDragLayer, previewItemOffsetX);
+        return a;
+    }
+
+    /**
+     * Animate the items that are displayed in the preview.
+     */
+    private void addPreviewItemAnimators(AnimatorSet animatorSet, final float folderScale,
+            int previewItemOffsetX) {
+        FolderIcon.PreviewLayoutRule rule = mFolderIcon.getLayoutRule();
+        final List<BubbleTextView> itemsInPreview = mFolderIcon.getItemsToDisplay();
+        final int numItemsInPreview = itemsInPreview.size();
+
+        TimeInterpolator previewItemInterpolator = getPreviewItemInterpolator();
+
+        ShortcutAndWidgetContainer cwc = mContent.getPageAt(0).getShortcutsAndWidgets();
+        for (int i = 0; i < numItemsInPreview; ++i) {
+            final BubbleTextView btv = itemsInPreview.get(i);
+            CellLayout.LayoutParams btvLp = (CellLayout.LayoutParams) btv.getLayoutParams();
+
+            // Calculate the final values in the LayoutParams.
+            btvLp.isLockedToGrid = true;
+            cwc.setupLp(btv);
+
+            // Match scale of icons in the preview.
+            float previewScale = rule.scaleForItem(i, numItemsInPreview);
+            float previewSize = rule.getIconSize() * previewScale;
+            float iconScale = previewSize / itemsInPreview.get(i).getIconSize();
+
+            final float initialScale = iconScale / folderScale;
+            final float finalScale = 1f;
+            float scale = mIsOpening ? initialScale : finalScale;
+            btv.setScaleX(scale);
+            btv.setScaleY(scale);
+
+            // Match positions of the icons in the folder with their positions in the preview
+            rule.computePreviewItemDrawingParams(i, numItemsInPreview, mTmpParams);
+            // The PreviewLayoutRule assumes that the icon size takes up the entire width so we
+            // offset by the actual size.
+            int iconOffsetX = (int) ((btvLp.width - btv.getIconSize()) * iconScale) / 2;
+
+            final int previewPosX =
+                    (int) ((mTmpParams.transX - iconOffsetX + previewItemOffsetX) / folderScale);
+            final int previewPosY = (int) (mTmpParams.transY / folderScale);
+
+            final float xDistance = previewPosX - btvLp.x;
+            final float yDistance = previewPosY - btvLp.y;
+
+            Animator translationX = getAnimator(btv, View.TRANSLATION_X, xDistance, 0f);
+            translationX.setInterpolator(previewItemInterpolator);
+            play(animatorSet, translationX);
+
+            Animator translationY = getAnimator(btv, View.TRANSLATION_Y, yDistance, 0f);
+            translationY.setInterpolator(previewItemInterpolator);
+            play(animatorSet, translationY);
+
+            Animator scaleAnimator = getAnimator(btv, SCALE_PROPERTY, initialScale, finalScale);
+            scaleAnimator.setInterpolator(previewItemInterpolator);
+            play(animatorSet, scaleAnimator);
+
+            if (mFolder.getItemCount() > FolderIcon.NUM_ITEMS_IN_PREVIEW) {
+                // These delays allows the preview items to move as part of the Folder's motion,
+                // and its only necessary for large folders because of differing interpolators.
+                if (mIsOpening) {
+                    translationX.setStartDelay(mDelay);
+                    translationY.setStartDelay(mDelay);
+                    scaleAnimator.setStartDelay(mDelay);
+                }
+                translationX.setDuration(translationX.getDuration() - mDelay);
+                translationY.setDuration(translationY.getDuration() - mDelay);
+                scaleAnimator.setDuration(scaleAnimator.getDuration() - mDelay);
+            }
+
+            animatorSet.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationStart(Animator animation) {
+                    super.onAnimationStart(animation);
+                    // Necessary to initialize values here because of the start delay.
+                    if (mIsOpening) {
+                        btv.setTranslationX(xDistance);
+                        btv.setTranslationY(yDistance);
+                        btv.setScaleX(initialScale);
+                        btv.setScaleY(initialScale);
+                    }
+                }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    super.onAnimationEnd(animation);
+                    btv.setTranslationX(0.0f);
+                    btv.setTranslationY(0.0f);
+                    btv.setScaleX(1f);
+                    btv.setScaleY(1f);
+                }
+            });
+        }
+    }
+
+    private void play(AnimatorSet as, Animator a) {
+        a.setDuration(mDuration);
+        as.play(a);
+    }
+
+    private TimeInterpolator getPreviewItemInterpolator() {
+        if (mFolder.getItemCount() > FolderIcon.NUM_ITEMS_IN_PREVIEW) {
+            // With larger folders, we want the preview items to reach their final positions faster
+            // (when opening) and later (when closing) so that they appear aligned with the rest of
+            // the folder items when they are both visible.
+            return mLargeFolderPreviewItemInterpolator;
+        }
+        return mFolderInterpolator;
+    }
+
+    private Animator getAnimator(View view, Property property, float v1, float v2) {
+        return mIsOpening
+                ? ObjectAnimator.ofFloat(view, property, v1, v2)
+                : ObjectAnimator.ofFloat(view, property, v2, v1);
+    }
+
+    private Animator getAnimator(List<BubbleTextView> items, Property property, int v1, int v2) {
+        return mIsOpening
+                ? ObjectAnimator.ofArgb(items, property, v1, v2)
+                : ObjectAnimator.ofArgb(items, property, v2, v1);
+    }
+
+    private Animator getAnimator(GradientDrawable drawable, String property, int v1, int v2) {
+        return mIsOpening
+                ? ObjectAnimator.ofArgb(drawable, property, v1, v2)
+                : ObjectAnimator.ofArgb(drawable, property, v2, v1);
+    }
+}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 8d58fef..b793f49 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -36,8 +36,10 @@
 import android.graphics.Shader;
 import android.graphics.drawable.Drawable;
 import android.os.Parcelable;
+import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
 import android.util.DisplayMetrics;
+import android.util.Log;
 import android.util.Property;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -75,8 +77,10 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.dragndrop.DragView;
+import com.android.launcher3.util.Themes;
 import com.android.launcher3.graphics.IconPalette;
 import com.android.launcher3.util.Thunk;
+import com.android.launcher3.widget.PendingAddShortcutInfo;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -126,6 +130,7 @@
 
     private float mSlop;
 
+    FolderIconPreviewVerifier mPreviewVerifier;
     private PreviewItemDrawingParams mTmpParams = new PreviewItemDrawingParams(0, 0, 0, 0);
     private ArrayList<PreviewItemDrawingParams> mDrawingParams = new ArrayList<PreviewItemDrawingParams>();
     private Drawable mReferenceDrawable = null;
@@ -181,7 +186,8 @@
         }
 
         DeviceProfile grid = launcher.getDeviceProfile();
-        FolderIcon icon = (FolderIcon) LayoutInflater.from(launcher).inflate(resId, group, false);
+        FolderIcon icon = (FolderIcon) LayoutInflater.from(group.getContext())
+                .inflate(resId, group, false);
 
         icon.setClipToPadding(false);
         icon.mFolderName = (BubbleTextView) icon.findViewById(R.id.folder_icon_name);
@@ -221,6 +227,7 @@
 
     private void setFolder(Folder folder) {
         mFolder = folder;
+        mPreviewVerifier = new FolderIconPreviewVerifier(mLauncher.getDeviceProfile().inv);
         updateItemDrawingParams(false);
     }
 
@@ -249,11 +256,9 @@
         mBackground.animateToAccept(cl, lp.cellX, lp.cellY);
         mOpenAlarm.setOnAlarmListener(mOnOpenListener);
         if (SPRING_LOADING_ENABLED &&
-                ((dragInfo instanceof AppInfo) || (dragInfo instanceof ShortcutInfo))) {
-            // TODO: we currently don't support spring-loading for PendingAddShortcutInfos even
-            // though widget-style shortcuts can be added to folders. The issue is that we need
-            // to deal with configuration activities which are currently handled in
-            // Workspace#onDropExternal.
+                ((dragInfo instanceof AppInfo)
+                        || (dragInfo instanceof ShortcutInfo)
+                        || (dragInfo instanceof PendingAddShortcutInfo))) {
             mOpenAlarm.setAlarm(ON_OPEN_DELAY);
         }
     }
@@ -383,14 +388,11 @@
     private void computePreviewDrawingParams(int drawableSize, int totalSize) {
         if (mIntrinsicIconSize != drawableSize || mTotalWidth != totalSize ||
                 mPrevTopPadding != getPaddingTop()) {
-            DeviceProfile grid = mLauncher.getDeviceProfile();
-
             mIntrinsicIconSize = drawableSize;
             mTotalWidth = totalSize;
             mPrevTopPadding = getPaddingTop();
 
-            mBackground.setup(getResources().getDisplayMetrics(), grid, this, mTotalWidth,
-                    getPaddingTop());
+            mBackground.setup(mLauncher, this, mTotalWidth, getPaddingTop());
             mPreviewLayoutRule.init(mBackground.previewSize, mIntrinsicIconSize,
                     Utilities.isRtl(getResources()));
 
@@ -407,6 +409,10 @@
         mBadgeInfo = badgeInfo;
     }
 
+    public PreviewLayoutRule getLayoutRule() {
+        return mPreviewLayoutRule;
+    }
+
     /**
      * Sets mBadgeScale to 1 or 0, animating if wasBadged or isBadged is false
      * (the badge is being added or removed).
@@ -539,7 +545,9 @@
 
         private float mScale = 1f;
         private float mColorMultiplier = 1f;
+        private int mBgColor;
         private float mStrokeWidth;
+        private int mStrokeAlpha = MAX_BG_OPACITY;
         private View mInvalidateDelegate;
 
         public int previewSize;
@@ -561,15 +569,31 @@
         // Expressed on a scale from 0 to 255.
         private static final int BG_OPACITY = 160;
         private static final int MAX_BG_OPACITY = 225;
-        private static final int BG_INTENSITY = 245;
         private static final int SHADOW_OPACITY = 40;
 
         ValueAnimator mScaleAnimator;
+        ObjectAnimator mStrokeAlphaAnimator;
 
-        public void setup(DisplayMetrics dm, DeviceProfile grid, View invalidateDelegate,
+        private static final Property<PreviewBackground, Integer> STROKE_ALPHA =
+                new Property<PreviewBackground, Integer>(Integer.class, "strokeAlpha") {
+                    @Override
+                    public Integer get(PreviewBackground previewBackground) {
+                        return previewBackground.mStrokeAlpha;
+                    }
+
+                    @Override
+                    public void set(PreviewBackground previewBackground, Integer alpha) {
+                        previewBackground.mStrokeAlpha = alpha;
+                        previewBackground.invalidate();
+                    }
+                };
+
+        public void setup(Launcher launcher, View invalidateDelegate,
                    int availableSpace, int topPadding) {
             mInvalidateDelegate = invalidateDelegate;
+            mBgColor = Themes.getAttrColor(launcher, android.R.attr.colorPrimary);
 
+            DeviceProfile grid = launcher.getDeviceProfile();
             final int previewSize = grid.folderIconSizePx;
             final int previewPadding = grid.folderIconPreviewPadding;
 
@@ -579,7 +603,7 @@
             basePreviewOffsetY = previewPadding + grid.folderBackgroundOffset + topPadding;
 
             // Stroke width is 1dp
-            mStrokeWidth = dm.density;
+            mStrokeWidth = launcher.getResources().getDisplayMetrics().density;
 
             float radius = getScaledRadius();
             float shadowRadius = radius + mStrokeWidth;
@@ -634,7 +658,7 @@
         public void drawBackground(Canvas canvas) {
             mPaint.setStyle(Paint.Style.FILL);
             int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
-            mPaint.setColor(Color.argb(alpha, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
+            mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, alpha));
 
             drawCircle(canvas, 0 /* deltaRadius */);
 
@@ -674,8 +698,24 @@
             canvas.restoreToCount(saveCount);
         }
 
+        public void animateBackgroundStroke() {
+            if (mStrokeAlphaAnimator != null) {
+                mStrokeAlphaAnimator.cancel();
+            }
+            mStrokeAlphaAnimator = ObjectAnimator
+                    .ofInt(this, STROKE_ALPHA, MAX_BG_OPACITY / 2, MAX_BG_OPACITY)
+                    .setDuration(100);
+            mStrokeAlphaAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mStrokeAlphaAnimator = null;
+                }
+            });
+            mStrokeAlphaAnimator.start();
+        }
+
         public void drawBackgroundStroke(Canvas canvas) {
-            mPaint.setColor(Color.argb(255, BG_INTENSITY, BG_INTENSITY, BG_INTENSITY));
+            mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, mStrokeAlpha));
             mPaint.setStyle(Paint.Style.STROKE);
             mPaint.setStrokeWidth(mStrokeWidth);
             drawCircle(canvas, 1 /* deltaRadius */);
@@ -822,6 +862,14 @@
             };
             animateScale(1f, 1f, onStart, onEnd);
         }
+
+        public int getBackgroundAlpha() {
+            return (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
+        }
+
+        public float getStrokeWidth() {
+            return mStrokeWidth;
+        }
     }
 
     public void setFolderBackground(PreviewBackground bg) {
@@ -992,8 +1040,26 @@
         return mFolderName.getVisibility() == VISIBLE;
     }
 
+    public List<BubbleTextView> getItemsToDisplay() {
+        mPreviewVerifier.setFolderInfo(mFolder.getInfo());
+
+        List<BubbleTextView> itemsToDisplay = new ArrayList<>();
+        List<View> allItems = mFolder.getItemsInReadingOrder();
+        int numItems = allItems.size();
+        for (int rank = 0; rank < numItems; ++rank) {
+            if (mPreviewVerifier.isItemInPreview(rank)) {
+                itemsToDisplay.add((BubbleTextView) allItems.get(rank));
+            }
+
+            if (itemsToDisplay.size() == FolderIcon.NUM_ITEMS_IN_PREVIEW) {
+                break;
+            }
+        }
+        return itemsToDisplay;
+    }
+
     private void updateItemDrawingParams(boolean animate) {
-        List<View> items = mPreviewLayoutRule.getItemsToDisplay(mFolder);
+        List<BubbleTextView> items = getItemsToDisplay();
         int nItemsInPreview = items.size();
 
         int prevNumItems = mDrawingParams.size();
@@ -1008,7 +1074,7 @@
 
         for (int i = 0; i < mDrawingParams.size(); i++) {
             PreviewItemDrawingParams p = mDrawingParams.get(i);
-            p.drawable = ((TextView) items.get(i)).getCompoundDrawables()[1];
+            p.drawable = items.get(i).getCompoundDrawables()[1];
 
             if (!animate || FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON) {
                 computePreviewItemDrawingParams(i, nItemsInPreview, p);
@@ -1044,7 +1110,7 @@
     }
 
     @Override
-    public void onAdd(ShortcutInfo item) {
+    public void onAdd(ShortcutInfo item, int rank) {
         boolean wasBadged = mBadgeInfo.hasBadge();
         mBadgeInfo.addBadgeInfo(mLauncher.getPopupDataProvider().getBadgeInfoForItem(item));
         boolean isBadged = mBadgeInfo.hasBadge();
@@ -1110,28 +1176,21 @@
     }
 
     public void shrinkAndFadeIn(boolean animate) {
-        final CellLayout cl = (CellLayout) getParent().getParent();
-        ((CellLayout.LayoutParams) getLayoutParams()).canReorder = true;
-
         // We remove and re-draw the FolderIcon in-case it has changed
         final PreviewImageView previewImage = PreviewImageView.get(getContext());
         previewImage.removeFromParent();
         copyToPreview(previewImage);
 
-        if (cl != null) {
-            cl.clearFolderLeaveBehind();
-        }
+        clearLeaveBehindIfExists();
 
         ObjectAnimator oa = LauncherAnimUtils.ofViewAlphaAndScale(previewImage, 1, 1, 1);
         oa.setDuration(getResources().getInteger(R.integer.config_folderExpandDuration));
         oa.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                if (cl != null) {
-                    // Remove the ImageView copy of the FolderIcon and make the original visible.
-                    previewImage.removeFromParent();
-                    setVisibility(View.VISIBLE);
-                }
+                // Remove the ImageView copy of the FolderIcon and make the original visible.
+                previewImage.removeFromParent();
+                setVisibility(View.VISIBLE);
             }
         });
         oa.start();
@@ -1140,7 +1199,15 @@
         }
     }
 
-    public void growAndFadeOut() {
+    public void clearLeaveBehindIfExists() {
+        ((CellLayout.LayoutParams) getLayoutParams()).canReorder = true;
+        if (mInfo.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
+            CellLayout cl = (CellLayout) getParent().getParent();
+            cl.clearFolderLeaveBehind();
+        }
+    }
+
+    public void drawLeaveBehindIfExists() {
         CellLayout.LayoutParams lp = (CellLayout.LayoutParams) getLayoutParams();
         // While the folder is open, the position of the icon cannot change.
         lp.canReorder = false;
@@ -1148,6 +1215,10 @@
             CellLayout cl = (CellLayout) getParent().getParent();
             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);
         }
+    }
+
+    public void growAndFadeOut() {
+        drawLeaveBehindIfExists();
 
         // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original
         PreviewImageView previewImage = PreviewImageView.get(getContext());
@@ -1177,8 +1248,8 @@
             PreviewItemDrawingParams params);
         void init(int availableSpace, int intrinsicIconSize, boolean rtl);
         float scaleForItem(int index, int totalNumItems);
+        float getIconSize();
         int maxNumItems();
         boolean clipToBackground();
-        List<View> getItemsToDisplay(Folder folder);
     }
 }
diff --git a/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java
new file mode 100644
index 0000000..de962b0
--- /dev/null
+++ b/src/com/android/launcher3/folder/FolderIconPreviewVerifier.java
@@ -0,0 +1,64 @@
+/*
+ * 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.folder;
+
+import com.android.launcher3.FolderInfo;
+import com.android.launcher3.InvariantDeviceProfile;
+import com.android.launcher3.config.FeatureFlags;
+
+/**
+ * Verifies whether an item in a Folder is displayed in the FolderIcon preview.
+ */
+public class FolderIconPreviewVerifier {
+
+    private final int mMaxGridCountX;
+    private final int mMaxGridCountY;
+    private final int mMaxItemsPerPage;
+    private final int[] mGridSize = new int[2];
+
+    private int mGridCountX;
+    private boolean mDisplayingUpperLeftQuadrant = false;
+
+    public FolderIconPreviewVerifier(InvariantDeviceProfile profile) {
+        mMaxGridCountX = profile.numFolderColumns;
+        mMaxGridCountY = profile.numFolderRows;
+        mMaxItemsPerPage = mMaxGridCountX * mMaxGridCountY;
+    }
+
+    public void setFolderInfo(FolderInfo info) {
+        int numItemsInFolder = info.contents.size();
+        mDisplayingUpperLeftQuadrant = FeatureFlags.LAUNCHER3_NEW_FOLDER_ANIMATION
+                && !FeatureFlags.LAUNCHER3_LEGACY_FOLDER_ICON
+                && numItemsInFolder > FolderIcon.NUM_ITEMS_IN_PREVIEW;
+
+        if (mDisplayingUpperLeftQuadrant) {
+            FolderPagedView.calculateGridSize(info.contents.size(), 0, 0, mMaxGridCountX,
+                    mMaxGridCountY, mMaxItemsPerPage, mGridSize);
+            mGridCountX = mGridSize[0];
+        }
+    }
+
+    public boolean isItemInPreview(int rank) {
+        if (mDisplayingUpperLeftQuadrant) {
+            // Returns true iff the icon is in the 2x2 upper left quadrant of the Folder.
+            int col = rank % mGridCountX;
+            int row = rank / mGridCountX;
+            return col < 2 && row < 2;
+        }
+        return rank < FolderIcon.NUM_ITEMS_IN_PREVIEW;
+    }
+}
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index eecce18..19a16b1 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -35,17 +35,14 @@
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
 import com.android.launcher3.PagedView;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutAndWidgetContainer;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace.ItemOperator;
-import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.keyboard.ViewGroupFocusHelper;
 import com.android.launcher3.pageindicators.PageIndicator;
-import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 
 import java.util.ArrayList;
@@ -68,7 +65,7 @@
      */
     private static final float SCROLL_HINT_FRACTION = 0.07f;
 
-    private static final int[] sTempPosArray = new int[2];
+    private static final int[] sTmpArray = new int[2];
 
     public final boolean mIsRtl;
 
@@ -108,7 +105,6 @@
         mIsRtl = Utilities.isRtl(getResources());
         setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
 
-        setEdgeGlowColor(Themes.getAttrColor(context, android.R.attr.colorEdgeEffect));
         mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
     }
 
@@ -120,40 +116,58 @@
     }
 
     /**
-     * Sets up the grid size such that {@param count} items can fit in the grid.
+     * Calculates the grid size such that {@param count} items can fit in the grid.
      * The grid size is calculated such that countY <= countX and countX = ceil(sqrt(count)) while
      * maintaining the restrictions of {@link #mMaxCountX} &amp; {@link #mMaxCountY}.
      */
-    private void setupContentDimensions(int count) {
-        mAllocatedContentSize = count;
+    public static void calculateGridSize(int count, int countX, int countY, int maxCountX,
+            int maxCountY, int maxItemsPerPage, int[] out) {
         boolean done;
-        if (count >= mMaxItemsPerPage) {
-            mGridCountX = mMaxCountX;
-            mGridCountY = mMaxCountY;
+        int gridCountX = countX;
+        int gridCountY = countY;
+
+        if (count >= maxItemsPerPage) {
+            gridCountX = maxCountX;
+            gridCountY = maxCountY;
             done = true;
         } else {
             done = false;
         }
 
         while (!done) {
-            int oldCountX = mGridCountX;
-            int oldCountY = mGridCountY;
-            if (mGridCountX * mGridCountY < count) {
+            int oldCountX = gridCountX;
+            int oldCountY = gridCountY;
+            if (gridCountX * gridCountY < count) {
                 // Current grid is too small, expand it
-                if ((mGridCountX <= mGridCountY || mGridCountY == mMaxCountY) && mGridCountX < mMaxCountX) {
-                    mGridCountX++;
-                } else if (mGridCountY < mMaxCountY) {
-                    mGridCountY++;
+                if ((gridCountX <= gridCountY || gridCountY == maxCountY)
+                        && gridCountX < maxCountX) {
+                    gridCountX++;
+                } else if (gridCountY < maxCountY) {
+                    gridCountY++;
                 }
-                if (mGridCountY == 0) mGridCountY++;
-            } else if ((mGridCountY - 1) * mGridCountX >= count && mGridCountY >= mGridCountX) {
-                mGridCountY = Math.max(0, mGridCountY - 1);
-            } else if ((mGridCountX - 1) * mGridCountY >= count) {
-                mGridCountX = Math.max(0, mGridCountX - 1);
+                if (gridCountY == 0) gridCountY++;
+            } else if ((gridCountY - 1) * gridCountX >= count && gridCountY >= gridCountX) {
+                gridCountY = Math.max(0, gridCountY - 1);
+            } else if ((gridCountX - 1) * gridCountY >= count) {
+                gridCountX = Math.max(0, gridCountX - 1);
             }
-            done = mGridCountX == oldCountX && mGridCountY == oldCountY;
+            done = gridCountX == oldCountX && gridCountY == oldCountY;
         }
 
+        out[0] = gridCountX;
+        out[1] = gridCountY;
+    }
+
+    /**
+     * Sets up the grid size such that {@param count} items can fit in the grid.
+     */
+    public void setupContentDimensions(int count) {
+        mAllocatedContentSize = count;
+        calculateGridSize(count, mGridCountX, mGridCountY, mMaxCountX, mMaxCountY, mMaxItemsPerPage,
+                sTmpArray);
+        mGridCountX = sTmpArray[0];
+        mGridCountY = sTmpArray[1];
+
         // Update grid size
         for (int i = getPageCount() - 1; i >= 0; i--) {
             getPageAt(i).setGridSize(mGridCountX, mGridCountY);
@@ -185,21 +199,26 @@
         return extra;
     }
 
+    public void allocateSpaceForRank(int rank) {
+        ArrayList<View> views = new ArrayList<>(mFolder.getItemsInReadingOrder());
+        views.add(rank, null);
+        arrangeChildren(views, views.size(), false);
+    }
+
     /**
      * Create space for a new item at the end, and returns the rank for that item.
      * Also sets the current page to the last page.
      */
     public int allocateRankForNewItem() {
         int rank = getItemCount();
-        ArrayList<View> views = new ArrayList<>(mFolder.getItemsInReadingOrder());
-        views.add(rank, null);
-        arrangeChildren(views, views.size(), false);
+        allocateSpaceForRank(rank);
         setCurrentPage(rank / mMaxItemsPerPage);
         return rank;
     }
 
     public View createAndAddViewForRank(ShortcutInfo item, int rank) {
         View icon = createNewView(item);
+        allocateSpaceForRank(rank);
         addViewForRank(icon, item, rank);
         return icon;
     }
@@ -314,6 +333,8 @@
         int position = 0;
         int newX, newY, rank;
 
+        FolderIconPreviewVerifier verifier = new FolderIconPreviewVerifier(
+                Launcher.getLauncher(getContext()).getDeviceProfile().inv);
         rank = 0;
         for (int i = 0; i < itemCount; i++) {
             View v = list.size() > i ? list.get(i) : null;
@@ -346,7 +367,7 @@
                 currentPage.addViewToCellLayout(
                         v, -1, mFolder.mLauncher.getViewIdForItem(info), lp, true);
 
-                if (rank < FolderIcon.NUM_ITEMS_IN_PREVIEW && v instanceof BubbleTextView) {
+                if (verifier.isItemInPreview(rank) && v instanceof BubbleTextView) {
                     ((BubbleTextView) v).verifyHighRes();
                 }
             }
@@ -400,12 +421,12 @@
     public int findNearestArea(int pixelX, int pixelY) {
         int pageIndex = getNextPage();
         CellLayout page = getPageAt(pageIndex);
-        page.findNearestArea(pixelX, pixelY, 1, 1, sTempPosArray);
+        page.findNearestArea(pixelX, pixelY, 1, 1, sTmpArray);
         if (mFolder.isLayoutRtl()) {
-            sTempPosArray[0] = page.getCountX() - sTempPosArray[0] - 1;
+            sTmpArray[0] = page.getCountX() - sTmpArray[0] - 1;
         }
         return Math.min(mAllocatedContentSize - 1,
-                pageIndex * mMaxItemsPerPage + sTempPosArray[1] * mGridCountX + sTempPosArray[0]);
+                pageIndex * mMaxItemsPerPage + sTmpArray[1] * mGridCountX + sTmpArray[0]);
     }
 
     public boolean isFull() {
diff --git a/src/com/android/launcher3/folder/PreviewImageView.java b/src/com/android/launcher3/folder/PreviewImageView.java
index c4f3ee1..65d9db1 100644
--- a/src/com/android/launcher3/folder/PreviewImageView.java
+++ b/src/com/android/launcher3/folder/PreviewImageView.java
@@ -22,7 +22,6 @@
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.view.View;
-import android.view.ViewGroup;
 import android.widget.ImageView;
 
 import com.android.launcher3.Launcher;
diff --git a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
index 297203a..12bca5f 100644
--- a/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
+++ b/src/com/android/launcher3/folder/StackFolderIconLayoutRule.java
@@ -16,12 +16,8 @@
 
 package com.android.launcher3.folder;
 
-import android.view.View;
-
 import com.android.launcher3.folder.FolderIcon.PreviewItemDrawingParams;
 
-import java.util.List;
-
 public class StackFolderIconLayoutRule implements FolderIcon.PreviewLayoutRule {
 
     static final int MAX_NUM_ITEMS_IN_PREVIEW = 3;
@@ -87,6 +83,11 @@
     }
 
     @Override
+    public float getIconSize() {
+        return mBaselineIconSize;
+    }
+
+    @Override
     public float scaleForItem(int index, int numItems) {
         // Scale is determined by the position of the icon in the preview.
         index = MAX_NUM_ITEMS_IN_PREVIEW - index - 1;
@@ -98,10 +99,4 @@
     public boolean clipToBackground() {
         return false;
     }
-
-    @Override
-    public List<View> getItemsToDisplay(Folder folder) {
-        List<View> items = folder.getItemsInReadingOrder();
-        return items.subList(0, Math.min(items.size(), MAX_NUM_ITEMS_IN_PREVIEW));
-    }
 }
diff --git a/src/com/android/launcher3/graphics/DragPreviewProvider.java b/src/com/android/launcher3/graphics/DragPreviewProvider.java
index bb136f7..492d853 100644
--- a/src/com/android/launcher3/graphics/DragPreviewProvider.java
+++ b/src/com/android/launcher3/graphics/DragPreviewProvider.java
@@ -29,7 +29,7 @@
 import com.android.launcher3.LauncherAppWidgetHostView;
 import com.android.launcher3.R;
 import com.android.launcher3.Workspace;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.folder.FolderIcon;
 
 /**
@@ -138,7 +138,7 @@
     }
 
     public final void generateDragOutline(Canvas canvas) {
-        if (ProviderConfig.IS_DOGFOOD_BUILD && generatedDragOutline != null) {
+        if (FeatureFlags.IS_DOGFOOD_BUILD && generatedDragOutline != null) {
             throw new RuntimeException("Drag outline generated twice");
         }
 
diff --git a/src/com/android/launcher3/graphics/GradientView.java b/src/com/android/launcher3/graphics/GradientView.java
new file mode 100644
index 0000000..9dd9504
--- /dev/null
+++ b/src/com/android/launcher3/graphics/GradientView.java
@@ -0,0 +1,160 @@
+/*
+ * 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 android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RadialGradient;
+import android.graphics.RectF;
+import android.graphics.Shader;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.dynamicui.WallpaperColorInfo;
+
+/**
+ * Draws a translucent radial gradient background from an initial state with progress 0.0 to a
+ * final state with progress 1.0;
+ */
+public class GradientView extends View implements WallpaperColorInfo.OnChangeListener {
+
+    private static final int DEFAULT_COLOR = Color.WHITE;
+    private static final float GRADIENT_ALPHA_MASK_LENGTH_DP = 300;
+    private static final boolean DEBUG = false;
+
+    private final Bitmap mFinalGradientMask;
+    private final Bitmap mAlphaGradientMask;
+
+    private int mColor1 = DEFAULT_COLOR;
+    private int mColor2 = DEFAULT_COLOR;
+    private int mWidth;
+    private int mHeight;
+    private final RectF mAlphaMaskRect = new RectF();
+    private final RectF mFinalMaskRect = new RectF();
+    private final Paint mPaint = new Paint();
+    private float mProgress;
+    private final int mMaskHeight;
+    private final Context mAppContext;
+    private final Paint mDebugPaint = DEBUG ? new Paint() : null;
+    private final Interpolator mAccelerator = new AccelerateInterpolator();
+    private final float mAlphaStart;
+    private final WallpaperColorInfo mWallpaperColorInfo;
+
+    public GradientView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        this.mAppContext = context.getApplicationContext();
+        this.mMaskHeight = Utilities.pxFromDp(GRADIENT_ALPHA_MASK_LENGTH_DP,
+                mAppContext.getResources().getDisplayMetrics());
+        Launcher launcher = Launcher.getLauncher(context);
+        this.mAlphaStart = launcher.getDeviceProfile().isVerticalBarLayout() ? 0 : 100;
+        this.mWallpaperColorInfo = WallpaperColorInfo.getInstance(launcher);
+        updateColors();
+
+        int finalAlpha = 0xBF;
+        mFinalGradientMask = Utilities.convertToAlphaMask(
+                Utilities.createOnePixBitmap(), finalAlpha);
+        Bitmap alphaMaskFromResource = BitmapFactory.decodeResource(context.getResources(),
+                R.drawable.all_apps_alpha_mask);
+        mAlphaGradientMask = Utilities.convertToAlphaMask(
+                alphaMaskFromResource, finalAlpha);
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        mWallpaperColorInfo.addOnChangeListener(this);
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+        mWallpaperColorInfo.removeOnChangeListener(this);
+    }
+
+    @Override
+    public void onExtractedColorsChanged(WallpaperColorInfo info) {
+        updateColors();
+        invalidate();
+    }
+
+    private void updateColors() {
+        this.mColor1 = mWallpaperColorInfo.getMainColor();
+        this.mColor2 = mWallpaperColorInfo.getSecondaryColor();
+        if (mWidth + mHeight > 0) {
+            createRadialShader();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        this.mWidth = getMeasuredWidth();
+        this.mHeight = getMeasuredHeight();
+        if (mWidth + mHeight > 0) {
+            createRadialShader();
+        }
+    }
+
+    // only being called when colors change
+    private void createRadialShader() {
+        final float gradientCenterY = 1.05f;
+        float radius = Math.max(mHeight, mWidth) * gradientCenterY;
+
+        float posScreenBottom = (radius - mHeight) / radius; // center lives below screen
+        RadialGradient shader = new RadialGradient(
+                mWidth * 0.5f,
+                mHeight * gradientCenterY,
+                radius,
+                new int[] {mColor1, mColor1, mColor2},
+                new float[] {0f, posScreenBottom, 1f},
+                Shader.TileMode.CLAMP);
+        mPaint.setShader(shader);
+    }
+
+    public void setProgress(float progress) {
+        this.mProgress = progress;
+        invalidate();
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        float head = 0.29f;
+        float linearProgress = head + (mProgress * (1f - head));
+        float startMaskY = (1f - linearProgress) * mHeight - mMaskHeight * linearProgress;
+        float interpolatedAlpha = (255 - mAlphaStart) * mAccelerator.getInterpolation(mProgress);
+        mPaint.setAlpha((int) (mAlphaStart + interpolatedAlpha));
+        mAlphaMaskRect.set(0, startMaskY, mWidth, startMaskY + mMaskHeight);
+        mFinalMaskRect.set(0, startMaskY + mMaskHeight, mWidth, mHeight);
+        canvas.drawBitmap(mAlphaGradientMask, null, mAlphaMaskRect, mPaint);
+        canvas.drawBitmap(mFinalGradientMask, null, mFinalMaskRect, mPaint);
+
+        if (DEBUG) {
+            mDebugPaint.setColor(0xFF00FF00);
+            canvas.drawLine(0, startMaskY, mWidth, startMaskY, mDebugPaint);
+            canvas.drawLine(0, startMaskY + mMaskHeight, mWidth, startMaskY + mMaskHeight, mDebugPaint);
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/graphics/HolographicOutlineHelper.java b/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
index c9873d9..b221828 100644
--- a/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
+++ b/src/com/android/launcher3/graphics/HolographicOutlineHelper.java
@@ -31,7 +31,7 @@
 
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.R;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 
 import java.nio.ByteBuffer;
 
@@ -86,7 +86,7 @@
      * bitmap.
      */
     public void applyExpensiveOutlineWithBlur(Bitmap srcDst, Canvas srcDstCanvas) {
-        if (ProviderConfig.IS_DOGFOOD_BUILD && srcDst.getConfig() != Bitmap.Config.ALPHA_8) {
+        if (FeatureFlags.IS_DOGFOOD_BUILD && srcDst.getConfig() != Bitmap.Config.ALPHA_8) {
             throw new RuntimeException("Outline blue is only supported on alpha bitmaps");
         }
 
diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java
index a17ceeb..6e01ed5 100644
--- a/src/com/android/launcher3/graphics/IconPalette.java
+++ b/src/com/android/launcher3/graphics/IconPalette.java
@@ -169,43 +169,40 @@
      * This was copied from com.android.internal.util.NotificationColorUtil.
      */
     private static int ensureTextContrast(int color, int bg) {
-        return findContrastColor(color, bg, true, 4.5);
+        return findContrastColor(color, bg, 4.5);
     }
     /**
      * Finds a suitable color such that there's enough contrast.
      *
-     * @param color the color to start searching from.
-     * @param other the color to ensure contrast against. Assumed to be lighter than {@param color}
-     * @param findFg if true, we assume {@param color} is a foreground, otherwise a background.
+     * @param fg the color to start searching from.
+     * @param bg the color to ensure contrast against.
      * @param minRatio the minimum contrast ratio required.
      * @return a color with the same hue as {@param color}, potentially darkened to meet the
      *          contrast ratio.
      *
      * This was copied from com.android.internal.util.NotificationColorUtil.
      */
-    private static int findContrastColor(int color, int other, boolean findFg, double minRatio) {
-        int fg = findFg ? color : other;
-        int bg = findFg ? other : color;
+    private static int findContrastColor(int fg, int bg, double minRatio) {
         if (ColorUtils.calculateContrast(fg, bg) >= minRatio) {
-            return color;
+            return fg;
         }
 
         double[] lab = new double[3];
-        ColorUtils.colorToLAB(findFg ? fg : bg, lab);
+        ColorUtils.colorToLAB(bg, lab);
+        double bgL = lab[0];
+        ColorUtils.colorToLAB(fg, lab);
+        double fgL = lab[0];
+        boolean isBgDark = bgL < 50;
 
-        double low = 0, high = lab[0];
+        double low = isBgDark ? fgL : 0, high = isBgDark ? 100 : fgL;
         final double a = lab[1], b = lab[2];
         for (int i = 0; i < 15 && high - low > 0.00001; i++) {
             final double l = (low + high) / 2;
-            if (findFg) {
-                fg = ColorUtils.LABToColor(l, a, b);
-            } else {
-                bg = ColorUtils.LABToColor(l, a, b);
-            }
+            fg = ColorUtils.LABToColor(l, a, b);
             if (ColorUtils.calculateContrast(fg, bg) > minRatio) {
-                low = l;
+                if (isBgDark) high = l; else low = l;
             } else {
-                high = l;
+                if (isBgDark) low = l; else high = l;
             }
         }
         return ColorUtils.LABToColor(low, a, b);
diff --git a/src/com/android/launcher3/graphics/IconShapeOverride.java b/src/com/android/launcher3/graphics/IconShapeOverride.java
index 6e4d366..e2d1d50 100644
--- a/src/com/android/launcher3/graphics/IconShapeOverride.java
+++ b/src/com/android/launcher3/graphics/IconShapeOverride.java
@@ -15,13 +15,14 @@
  */
 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.SharedPreferences;
 import android.content.res.Resources;
 import android.os.Build;
 import android.os.SystemClock;
@@ -34,11 +35,10 @@
 import android.util.Log;
 
 import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherFiles;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.util.LooperExecuter;
+import com.android.launcher3.util.LooperExecutor;
 
 import java.lang.reflect.Field;
 
@@ -101,7 +101,7 @@
         } catch (Exception e) {
             Log.e(TAG, "Unable to override icon shape", e);
             // revert value.
-            prefs(context).edit().remove(KEY_PREFERENCE).apply();
+            getDevicePrefs(context).edit().remove(KEY_PREFERENCE).apply();
         }
     }
 
@@ -116,11 +116,7 @@
     }
 
     private static String getAppliedValue(Context context) {
-        return prefs(context).getString(KEY_PREFERENCE, "");
-    }
-
-    private static SharedPreferences prefs(Context context) {
-        return context.getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, 0);
+        return getDevicePrefs(context).getString(KEY_PREFERENCE, "");
     }
 
     public static void handlePreferenceUi(ListPreference preference) {
@@ -169,7 +165,7 @@
                         mContext.getString(R.string.icon_shape_override_progress),
                         true /* indeterminate */,
                         false /* cancelable */);
-                new LooperExecuter(LauncherModel.getWorkerLooper()).execute(
+                new LooperExecutor(LauncherModel.getWorkerLooper()).execute(
                         new OverrideApplyHandler(mContext, newValue));
             }
             return false;
@@ -189,7 +185,7 @@
         @Override
         public void run() {
             // Synchronously write the preference.
-            prefs(mContext).edit().putString(KEY_PREFERENCE, mValue).commit();
+            getDevicePrefs(mContext).edit().putString(KEY_PREFERENCE, mValue).commit();
             // Clear the icon cache.
             LauncherAppState.getInstance(mContext).getIconCache().clear();
 
diff --git a/src/com/android/launcher3/graphics/ScrimView.java b/src/com/android/launcher3/graphics/ScrimView.java
new file mode 100644
index 0000000..6d1f30a
--- /dev/null
+++ b/src/com/android/launcher3/graphics/ScrimView.java
@@ -0,0 +1,115 @@
+/*
+ * 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 android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.support.v4.graphics.ColorUtils;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.Interpolator;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.util.Themes;
+
+public class ScrimView extends View {
+
+    private static final boolean DEBUG = false;
+
+    private static final int MASK_HEIGHT_DP = 300;
+    private static final float MASK_START_LENGTH_FACTOR = 1f;
+    private static final boolean APPLY_ALPHA = true;
+
+    private final Bitmap mFinalScrimMask;
+    private final Bitmap mAlphaScrimMask;
+
+    private final int mMaskHeight;
+    private int mVisibleHeight;
+    private final int mHeadStart;
+
+    private final RectF mAlphaMaskRect = new RectF();
+    private final RectF mFinalMaskRect = new RectF();
+    private final Paint mPaint = new Paint();
+    private float mProgress;
+    private final Interpolator mAccelerator = new AccelerateInterpolator();
+    private final Paint mDebugPaint = DEBUG ? new Paint() : null;
+    private final int mAlphaStart;
+
+    public ScrimView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        mMaskHeight = Utilities.pxFromDp(MASK_HEIGHT_DP, getResources().getDisplayMetrics());
+        mHeadStart = (int) (mMaskHeight * MASK_START_LENGTH_FACTOR);
+        mAlphaStart = Launcher.getLauncher(context)
+                .getDeviceProfile().isVerticalBarLayout() ? 0 : 55;
+
+        int scrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
+        int scrimAlpha = Color.alpha(scrimColor);
+        mPaint.setColor(scrimColor);
+        mFinalScrimMask = Utilities.convertToAlphaMask(
+                Utilities.createOnePixBitmap(), scrimAlpha);
+        Bitmap alphaMaskFromResource = BitmapFactory.decodeResource(getResources(),
+                R.drawable.all_apps_alpha_mask);
+        mAlphaScrimMask = Utilities.convertToAlphaMask(alphaMaskFromResource, scrimAlpha);
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        int width = MeasureSpec.getSize(widthMeasureSpec);
+        mVisibleHeight = MeasureSpec.getSize(heightMeasureSpec);
+        setMeasuredDimension(width, mVisibleHeight * 2);
+        setProgress(mProgress);
+    }
+
+    public void setProgress(float progress) {
+        mProgress = progress;
+        float initialY = mVisibleHeight - mHeadStart;
+        float fullTranslationY = mVisibleHeight;
+        float linTranslationY = initialY - progress * fullTranslationY;
+        setTranslationY(linTranslationY);
+
+        if (APPLY_ALPHA) {
+            int alpha = mAlphaStart + (int) ((255f - mAlphaStart)
+                    * mAccelerator.getInterpolation(progress));
+            mPaint.setAlpha(alpha);
+            invalidate();
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        mAlphaMaskRect.set(0, 0, getWidth(), mMaskHeight);
+        mFinalMaskRect.set(0, mMaskHeight, getWidth(), getHeight());
+        canvas.drawBitmap(mAlphaScrimMask, null, mAlphaMaskRect, mPaint);
+        canvas.drawBitmap(mFinalScrimMask, null, mFinalMaskRect, mPaint);
+
+        if (DEBUG) {
+            mDebugPaint.setColor(0xFF0000FF);
+            canvas.drawLine(0, mAlphaMaskRect.top, getWidth(), mAlphaMaskRect.top, mDebugPaint);
+            canvas.drawLine(0, mAlphaMaskRect.bottom, getWidth(), mAlphaMaskRect.bottom, mDebugPaint);
+        }
+    }
+
+}
diff --git a/src/com/android/launcher3/graphics/ShadowDrawable.java b/src/com/android/launcher3/graphics/ShadowDrawable.java
new file mode 100644
index 0000000..45c1b6a
--- /dev/null
+++ b/src/com/android/launcher3/graphics/ShadowDrawable.java
@@ -0,0 +1,215 @@
+/*
+ * 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 android.annotation.TargetApi;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.Bitmap;
+import android.graphics.BlurMaskFilter;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.ColorFilter;
+import android.graphics.Paint;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.util.AttributeSet;
+
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+/**
+ * A drawable which adds shadow around a child drawable.
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public class ShadowDrawable extends Drawable {
+
+    private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+
+    private final ShadowDrawableState mState;
+
+    @SuppressWarnings("unused")
+    public ShadowDrawable() {
+        this(new ShadowDrawableState());
+    }
+
+    private ShadowDrawable(ShadowDrawableState state) {
+        mState = state;
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        Rect bounds = getBounds();
+        if (bounds.isEmpty()) {
+            return;
+        }
+        if (mState.mLastDrawnBitmap == null) {
+            regenerateBitmapCache();
+        }
+        canvas.drawBitmap(mState.mLastDrawnBitmap, null, bounds, mPaint);
+    }
+
+    @Override
+    public void setAlpha(int alpha) {
+        mPaint.setAlpha(alpha);
+        invalidateSelf();
+    }
+
+    @Override
+    public void setColorFilter(ColorFilter colorFilter) {
+        mPaint.setColorFilter(colorFilter);
+        invalidateSelf();
+    }
+
+    @Override
+    public ConstantState getConstantState() {
+        return mState;
+    }
+
+    @Override
+    public int getOpacity() {
+        return PixelFormat.TRANSLUCENT;
+    }
+
+    @Override
+    public int getIntrinsicHeight() {
+        return mState.mIntrinsicHeight;
+    }
+
+    @Override
+    public int getIntrinsicWidth() {
+        return mState.mIntrinsicWidth;
+    }
+
+    @Override
+    public boolean canApplyTheme() {
+        return mState.canApplyTheme();
+    }
+
+    @Override
+    public void applyTheme(Resources.Theme t) {
+        if (mState.canApplyTheme()) {
+            // Workaround since ColorStateList does not expose applyTheme method
+            ColorDrawable cd = new ColorDrawable();
+            cd.setTintList(mState.mTintColor);
+            cd.applyTheme(t);
+
+            mState.mLastDrawnBitmap = null;
+            invalidateSelf();
+        }
+    }
+
+    private void regenerateBitmapCache() {
+        Bitmap bitmap = Bitmap.createBitmap(mState.mIntrinsicWidth, mState.mIntrinsicHeight,
+                Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(bitmap);
+
+        // Call mutate, so that the pixel allocation by the underlying vector drawable is cleared.
+        Drawable d = mState.mChildState.newDrawable().mutate();
+        d.setBounds(mState.mShadowSize, mState.mShadowSize,
+                mState.mIntrinsicWidth - mState.mShadowSize,
+                mState.mIntrinsicHeight - mState.mShadowSize);
+        if (mState.mTintColor != null) {
+            d.setTint(mState.mTintColor.getDefaultColor());
+        }
+        d.draw(canvas);
+
+        Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+        paint.setMaskFilter(new BlurMaskFilter(mState.mShadowSize, BlurMaskFilter.Blur.NORMAL));
+        int[] offset = new int[2];
+        Bitmap shadow = bitmap.extractAlpha(paint, offset);
+
+        paint.setMaskFilter(null);
+        paint.setColor(mState.mShadowColor);
+        bitmap.eraseColor(Color.TRANSPARENT);
+        canvas.drawBitmap(shadow, offset[0], offset[1], paint);
+        d.draw(canvas);
+
+        if (Utilities.isAtLeastO()) {
+            bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
+        }
+        mState.mLastDrawnBitmap = bitmap;
+    }
+
+    @Override
+    public void inflate(Resources r, XmlPullParser parser, AttributeSet attrs,
+            Resources.Theme theme) throws XmlPullParserException, IOException {
+        super.inflate(r, parser, attrs, theme);
+
+        final TypedArray a = theme == null
+                ? r.obtainAttributes(attrs, R.styleable.ShadowDrawable)
+                : theme.obtainStyledAttributes(attrs, R.styleable.ShadowDrawable, 0, 0);
+
+        try {
+            Drawable d = a.getDrawable(R.styleable.ShadowDrawable_android_src);
+            if (d == null) {
+                throw new XmlPullParserException("missing src attribute");
+            }
+            mState.mShadowColor = a.getColor(
+                    R.styleable.ShadowDrawable_android_shadowColor, Color.BLACK);
+            mState.mShadowSize = a.getDimensionPixelSize(
+                    R.styleable.ShadowDrawable_android_elevation, 0);
+            mState.mTintColor = a.getColorStateList(R.styleable.ShadowDrawable_android_tint);
+
+            mState.mIntrinsicHeight = d.getIntrinsicHeight() + 2 * mState.mShadowSize;
+            mState.mIntrinsicWidth = d.getIntrinsicWidth() + 2 * mState.mShadowSize;
+            mState.mChangingConfigurations = d.getChangingConfigurations();
+
+            mState.mChildState = d.getConstantState();
+        } finally {
+            a.recycle();
+        }
+    }
+
+    private static class ShadowDrawableState extends ConstantState {
+
+        int mChangingConfigurations;
+        int mIntrinsicWidth;
+        int mIntrinsicHeight;
+
+        int mShadowColor;
+        int mShadowSize;
+        ColorStateList mTintColor;
+
+        Bitmap mLastDrawnBitmap;
+        ConstantState mChildState;
+
+        @Override
+        public Drawable newDrawable() {
+            return new ShadowDrawable(this);
+        }
+
+        @Override
+        public int getChangingConfigurations() {
+            return mChangingConfigurations;
+        }
+
+        @Override
+        public boolean canApplyTheme() {
+            return mTintColor != null;
+        }
+    }
+}
diff --git a/src/com/android/launcher3/graphics/ShadowGenerator.java b/src/com/android/launcher3/graphics/ShadowGenerator.java
index 5d8cca8..9ea11a7 100644
--- a/src/com/android/launcher3/graphics/ShadowGenerator.java
+++ b/src/com/android/launcher3/graphics/ShadowGenerator.java
@@ -22,8 +22,10 @@
 import android.graphics.BlurMaskFilter;
 import android.graphics.BlurMaskFilter.Blur;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.RectF;
+import android.support.v4.graphics.ColorUtils;
 
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.util.Preconditions;
@@ -38,10 +40,10 @@
     public static final float BLUR_FACTOR = 0.5f/48;
 
     // Percent of actual icon size
-    private static final float KEY_SHADOW_DISTANCE = 1f/48;
-    public static final int KEY_SHADOW_ALPHA = 61;
+    public static final float KEY_SHADOW_DISTANCE = 1f/48;
+    private static final int KEY_SHADOW_ALPHA = 61;
 
-    public static final int AMBIENT_SHADOW_ALPHA = 30;
+    private static final int AMBIENT_SHADOW_ALPHA = 30;
 
     private static final Object LOCK = new Object();
     // Singleton object guarded by {@link #LOCK}
@@ -84,45 +86,45 @@
     }
 
     public static Bitmap createPillWithShadow(int rectColor, int width, int height) {
-
         float shadowRadius = height * 1f / 32;
         float shadowYOffset = height * 1f / 16;
+        return createPillWithShadow(rectColor, width, height, shadowRadius, shadowYOffset,
+                new RectF());
+    }
 
+    public static Bitmap createPillWithShadow(int rectColor, int width, int height,
+            float shadowRadius, float shadowYOffset, RectF outRect) {
         int radius = height / 2;
 
-        Canvas canvas = new Canvas();
-        Paint blurPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-        blurPaint.setMaskFilter(new BlurMaskFilter(shadowRadius, Blur.NORMAL));
-
         int centerX = Math.round(width / 2 + shadowRadius);
         int centerY = Math.round(radius + shadowRadius + shadowYOffset);
         int center = Math.max(centerX, centerY);
         int size = center * 2;
         Bitmap result = Bitmap.createBitmap(size, size, Config.ARGB_8888);
-        canvas.setBitmap(result);
 
-        int left = center - width / 2;
-        int top = center - height / 2;
-        int right = center + width / 2;
-        int bottom = center + height / 2;
+        outRect.set(0, 0, width, height);
+        outRect.offsetTo(center - width / 2, center - height / 2);
 
-        // Draw ambient shadow, center aligned within size
-        blurPaint.setAlpha(AMBIENT_SHADOW_ALPHA);
-        canvas.drawRoundRect(left, top, right, bottom, radius, radius, blurPaint);
-
-        // Draw key shadow, bottom aligned within size
-        blurPaint.setAlpha(KEY_SHADOW_ALPHA);
-        canvas.drawRoundRect(left, top + shadowYOffset, right, bottom + shadowYOffset,
-                radius, radius, blurPaint);
-
-        // Draw the circle
-        Paint drawPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
-        drawPaint.setColor(rectColor);
-        canvas.drawRoundRect(left, top, right, bottom, radius, radius, drawPaint);
-
+        drawShadow(new Canvas(result), outRect, rectColor, shadowRadius, shadowYOffset, radius);
         return result;
     }
 
+    public static void drawShadow(Canvas c, RectF bounds, int color,
+            float shadowBlur, float keyShadowDistance, float radius) {
+        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
+        p.setColor(color);
+
+        // Key shadow
+        p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
+                ColorUtils.setAlphaComponent(Color.BLACK, KEY_SHADOW_ALPHA));
+        c.drawRoundRect(bounds, radius, radius, p);
+
+        // Ambient shadow
+        p.setShadowLayer(shadowBlur, 0, 0,
+                ColorUtils.setAlphaComponent(Color.BLACK, AMBIENT_SHADOW_ALPHA));
+        c.drawRoundRect(bounds, radius, radius, p);
+    }
+
     public static ShadowGenerator getInstance(Context context) {
         Preconditions.assertNonUiThread();
         synchronized (LOCK) {
diff --git a/src/com/android/launcher3/graphics/TintedDrawableSpan.java b/src/com/android/launcher3/graphics/TintedDrawableSpan.java
index f72ce03..d719575 100644
--- a/src/com/android/launcher3/graphics/TintedDrawableSpan.java
+++ b/src/com/android/launcher3/graphics/TintedDrawableSpan.java
@@ -34,6 +34,7 @@
         super(ALIGN_BOTTOM);
         mDrawable = context.getDrawable(resourceId);
         mOldTint = 0;
+        mDrawable.setTint(0);
     }
 
     @Override
diff --git a/src/com/android/launcher3/keyboard/CustomActionsPopup.java b/src/com/android/launcher3/keyboard/CustomActionsPopup.java
index bb0b58a..938955c 100644
--- a/src/com/android/launcher3/keyboard/CustomActionsPopup.java
+++ b/src/com/android/launcher3/keyboard/CustomActionsPopup.java
@@ -24,10 +24,10 @@
 import android.widget.PopupMenu;
 import android.widget.PopupMenu.OnMenuItemClickListener;
 
-import com.android.launcher3.popup.PopupContainerWithArrow;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
+import com.android.launcher3.popup.PopupContainerWithArrow;
 
 import java.util.ArrayList;
 import java.util.Collections;
diff --git a/src/com/android/launcher3/logging/FileLog.java b/src/com/android/launcher3/logging/FileLog.java
index ffb41b7..4c83e9a 100644
--- a/src/com/android/launcher3/logging/FileLog.java
+++ b/src/com/android/launcher3/logging/FileLog.java
@@ -6,9 +6,8 @@
 import android.util.Log;
 import android.util.Pair;
 
-import com.android.launcher3.LauncherModel;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 
 import java.io.BufferedReader;
 import java.io.File;
@@ -40,7 +39,7 @@
     private static File sLogsDirectory = null;
 
     public static void setDir(File logsDir) {
-        if (ProviderConfig.IS_DOGFOOD_BUILD || Utilities.IS_DEBUG_DEVICE) {
+        if (FeatureFlags.IS_DOGFOOD_BUILD || Utilities.IS_DEBUG_DEVICE) {
             synchronized (DATE_FORMAT) {
                 // If the target directory changes, stop any active thread.
                 if (sHandler != null && !logsDir.equals(sLogsDirectory)) {
@@ -77,7 +76,7 @@
     }
 
     public static void print(String tag, String msg, Exception e) {
-        if (!ProviderConfig.IS_DOGFOOD_BUILD) {
+        if (!FeatureFlags.IS_DOGFOOD_BUILD) {
             return;
         }
         String out = String.format("%s %s %s", DATE_FORMAT.format(new Date()), tag, msg);
@@ -103,7 +102,7 @@
      * @param out if not null, all the persisted logs are copied to the writer.
      */
     public static void flushAll(PrintWriter out) throws InterruptedException {
-        if (!ProviderConfig.IS_DOGFOOD_BUILD) {
+        if (!FeatureFlags.IS_DOGFOOD_BUILD) {
             return;
         }
         CountDownLatch latch = new CountDownLatch(1);
@@ -136,7 +135,7 @@
 
         @Override
         public boolean handleMessage(Message msg) {
-            if (sLogsDirectory == null || !ProviderConfig.IS_DOGFOOD_BUILD) {
+            if (sLogsDirectory == null || !FeatureFlags.IS_DOGFOOD_BUILD) {
                 return true;
             }
             switch (msg.what) {
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 499fdc7..329b7d5 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -15,7 +15,6 @@
  */
 package com.android.launcher3.logging;
 
-import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.SparseArray;
 import android.view.View;
diff --git a/src/com/android/launcher3/logging/UserEventDispatcher.java b/src/com/android/launcher3/logging/UserEventDispatcher.java
index 258af16..edbb88c 100644
--- a/src/com/android/launcher3/logging/UserEventDispatcher.java
+++ b/src/com/android/launcher3/logging/UserEventDispatcher.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.SystemClock;
+import android.support.annotation.Nullable;
 import android.util.Log;
 import android.view.View;
 import android.view.ViewParent;
@@ -29,7 +30,7 @@
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
@@ -60,7 +61,7 @@
 
     private static final String TAG = "UserEvent";
     private static final boolean IS_VERBOSE =
-            ProviderConfig.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT);
+            FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isPropertyEnabled(LogConfig.USEREVENT);
 
     public static UserEventDispatcher newInstance(Context context, boolean isInLandscapeMode,
             boolean isInMultiWindowMode) {
@@ -90,7 +91,7 @@
     /**
      * Recursively finds the parent of the given child which implements IconLogInfoProvider
      */
-    public static LogContainerProvider getLaunchProviderRecursive(View v) {
+    public static LogContainerProvider getLaunchProviderRecursive(@Nullable View v) {
         ViewParent parent;
         if (v != null) {
             parent = v.getParent();
@@ -147,7 +148,11 @@
         return event;
     }
 
-    public boolean fillInLogContainerData(LauncherEvent event, View v) {
+    /**
+     * Fills in the container data on the given event if the given view is not null.
+     * @return whether container data was added.
+     */
+    private boolean fillInLogContainerData(LauncherEvent event, @Nullable View v) {
         // Fill in grid(x,y), pageIndex of the child and container type of the parent
         LogContainerProvider provider = getLaunchProviderRecursive(v);
         if (v == null || !(v.getTag() instanceof ItemInfo) || provider == null) {
@@ -203,9 +208,16 @@
     }
 
     public void logActionOnControl(int action, int controlType) {
-        LauncherEvent event = newLauncherEvent(
-                newTouchAction(action), newTarget(Target.Type.CONTROL));
+        logActionOnControl(action, controlType, null);
+    }
+
+    public void logActionOnControl(int action, int controlType, @Nullable View controlInContainer) {
+        final LauncherEvent event = controlInContainer == null
+                ? newLauncherEvent(newTouchAction(action), newTarget(Target.Type.CONTROL))
+                : newLauncherEvent(newTouchAction(action), newTarget(Target.Type.CONTROL),
+                        newTarget(Target.Type.CONTAINER));
         event.srcTarget[0].controlType = controlType;
+        fillInLogContainerData(event, controlInContainer);
         dispatchUserEvent(event, null);
     }
 
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index 9696054..2e8e15b 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -17,6 +17,8 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.LauncherActivityInfo;
+import android.os.Process;
 import android.os.UserHandle;
 import android.util.LongSparseArray;
 import android.util.Pair;
@@ -33,10 +35,13 @@
 import com.android.launcher3.LauncherModel.Callbacks;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.util.GridOccupancy;
+import com.android.launcher3.util.ManagedProfileHeuristic.UserFolderInfo;
 import com.android.launcher3.util.Provider;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -44,18 +49,18 @@
  */
 public class AddWorkspaceItemsTask extends ExtendedModelTask {
 
-    private final Provider<List<ItemInfo>> mAppsProvider;
+    private final Provider<List<Pair<ItemInfo, Object>>> mAppsProvider;
 
     /**
      * @param appsProvider items to add on the workspace
      */
-    public AddWorkspaceItemsTask(Provider<List<ItemInfo>> appsProvider) {
+    public AddWorkspaceItemsTask(Provider<List<Pair<ItemInfo, Object>>> appsProvider) {
         mAppsProvider = appsProvider;
     }
 
     @Override
     public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
-        List<ItemInfo> workspaceApps = mAppsProvider.get();
+        List<Pair<ItemInfo, Object>> workspaceApps = mAppsProvider.get();
         if (workspaceApps.isEmpty()) {
             return;
         }
@@ -63,13 +68,17 @@
 
         final ArrayList<ItemInfo> addedItemsFinal = new ArrayList<>();
         final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<>();
+        HashMap<UserHandle, UserFolderInfo> userFolderMap = new HashMap<>();
 
         // 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.
         ArrayList<Long> workspaceScreens = LauncherModel.loadWorkspaceScreensDb(context);
         synchronized(dataModel) {
-            for (ItemInfo item : workspaceApps) {
+
+            List<ItemInfo> filteredItems = new ArrayList<>();
+            for (Pair<ItemInfo, Object> entry : workspaceApps) {
+                ItemInfo item = entry.first;
                 if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION ||
                         item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
                     // Short-circuit this logic if the icon exists somewhere on the workspace
@@ -78,6 +87,32 @@
                     }
                 }
 
+                if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+                    if (item instanceof AppInfo) {
+                        item = ((AppInfo) item).makeShortcut();
+                    }
+
+                    if (!Process.myUserHandle().equals(item.user)) {
+                        // Check if this belongs to a work folder.
+                        if (!(entry.second instanceof LauncherActivityInfo)) {
+                            continue;
+                        }
+
+                        UserFolderInfo userFolderInfo = userFolderMap.get(item.user);
+                        if (userFolderInfo == null) {
+                            userFolderInfo = new UserFolderInfo(context, item.user, dataModel);
+                            userFolderMap.put(item.user, userFolderInfo);
+                        }
+                        item = userFolderInfo.convertToWorkspaceItem(
+                                (ShortcutInfo) item, (LauncherActivityInfo) entry.second);
+                    }
+                }
+                if (item != null) {
+                    filteredItems.add(item);
+                }
+            }
+
+            for (ItemInfo item : filteredItems) {
                 // Find appropriate space for the item.
                 Pair<Long, int[]> coords = findSpaceForItem(app, dataModel, workspaceScreens,
                         addedWorkspaceScreensFinal, item.spanX, item.spanY);
@@ -129,6 +164,10 @@
                 }
             });
         }
+
+        for (UserFolderInfo userFolderInfo : userFolderMap.values()) {
+            userFolderInfo.applyPendingState(getModelWriter());
+        }
     }
 
     protected void updateScreens(Context context, ArrayList<Long> workspaceScreens) {
@@ -140,7 +179,7 @@
      * the workspace has been loaded. We identify a shortcut by its intent.
      */
     protected boolean shortcutExists(BgDataModel dataModel, Intent intent, UserHandle user) {
-        final String intentWithPkg, intentWithoutPkg;
+        final String compPkgName, intentWithPkg, intentWithoutPkg;
         if (intent == null) {
             // Skip items with null intents
             return true;
@@ -148,19 +187,21 @@
         if (intent.getComponent() != null) {
             // If component is not null, an intent with null package will produce
             // the same result and should also be a match.
-            String packageName = intent.getComponent().getPackageName();
+            compPkgName = intent.getComponent().getPackageName();
             if (intent.getPackage() != null) {
                 intentWithPkg = intent.toUri(0);
                 intentWithoutPkg = new Intent(intent).setPackage(null).toUri(0);
             } else {
-                intentWithPkg = new Intent(intent).setPackage(packageName).toUri(0);
+                intentWithPkg = new Intent(intent).setPackage(compPkgName).toUri(0);
                 intentWithoutPkg = intent.toUri(0);
             }
         } else {
+            compPkgName = null;
             intentWithPkg = intent.toUri(0);
             intentWithoutPkg = intent.toUri(0);
         }
 
+        boolean isLauncherAppTarget = Utilities.isLauncherAppTarget(intent);
         synchronized (dataModel) {
             for (ItemInfo item : dataModel.itemsIdMap) {
                 if (item instanceof ShortcutInfo) {
@@ -172,6 +213,16 @@
                         if (intentWithPkg.equals(s) || intentWithoutPkg.equals(s)) {
                             return true;
                         }
+
+                        // checking for existing promise icon with same package name
+                        if (isLauncherAppTarget
+                                && info.isPromise()
+                                && info.hasStatusFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)
+                                && info.getTargetComponent() != null
+                                && compPkgName != null
+                                && compPkgName.equals(info.getTargetComponent().getPackageName())) {
+                            return true;
+                        }
                     }
                 }
             }
@@ -263,4 +314,5 @@
         }
         return occupied.findVacantCell(xy, spanX, spanY);
     }
+
 }
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index 0e73ca6..d9c5143 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -27,16 +27,14 @@
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.config.ProviderConfig;
-import com.android.launcher3.logging.LoggerUtils;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.logging.DumpTargetWrapper;
-import com.android.launcher3.shortcuts.DeepShortcutManager;
-import com.android.launcher3.shortcuts.ShortcutInfoCompat;
-import com.android.launcher3.shortcuts.ShortcutKey;
 import com.android.launcher3.model.nano.LauncherDumpProto;
 import com.android.launcher3.model.nano.LauncherDumpProto.ContainerType;
 import com.android.launcher3.model.nano.LauncherDumpProto.DumpTarget;
-import com.android.launcher3.model.nano.LauncherDumpProto.ItemType;
+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.LongArrayMap;
 import com.android.launcher3.util.MultiHashMap;
@@ -93,11 +91,21 @@
     public final Map<ShortcutKey, MutableInt> pinnedShortcutCounts = new HashMap<>();
 
     /**
+     * True if the launcher has permission to access deep shortcuts.
+     */
+    public boolean hasShortcutHostPermission;
+
+    /**
      * Maps all launcher activities to the id's of their shortcuts (if they have any).
      */
     public final MultiHashMap<ComponentKey, String> deepShortcutMap = new MultiHashMap<>();
 
     /**
+     * Entire list of widgets.
+     */
+    public final WidgetsModel widgetsModel = new WidgetsModel();
+
+    /**
      * Clears all the data
      */
     public synchronized void clear() {
@@ -242,7 +250,7 @@
             switch (item.itemType) {
                 case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
                     folders.remove(item.id);
-                    if (ProviderConfig.IS_DOGFOOD_BUILD) {
+                    if (FeatureFlags.IS_DOGFOOD_BUILD) {
                         for (ItemInfo info : itemsIdMap) {
                             if (info.container == item.id) {
                                 // We are deleting a folder which still contains items that
diff --git a/src/com/android/launcher3/model/CacheDataUpdatedTask.java b/src/com/android/launcher3/model/CacheDataUpdatedTask.java
index 46130fc..d7cece4 100644
--- a/src/com/android/launcher3/model/CacheDataUpdatedTask.java
+++ b/src/com/android/launcher3/model/CacheDataUpdatedTask.java
@@ -26,7 +26,6 @@
 import com.android.launcher3.LauncherModel.CallbackTask;
 import com.android.launcher3.LauncherModel.Callbacks;
 import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.ShortcutInfo;
 
 import java.util.ArrayList;
diff --git a/src/com/android/launcher3/model/DbDowngradeHelper.java b/src/com/android/launcher3/model/DbDowngradeHelper.java
new file mode 100644
index 0000000..cd86b72
--- /dev/null
+++ b/src/com/android/launcher3/model/DbDowngradeHelper.java
@@ -0,0 +1,108 @@
+/*
+ * 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 android.content.Context;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
+import com.android.launcher3.util.IOUtils;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * Utility class to handle DB downgrade
+ */
+public class DbDowngradeHelper {
+
+    private static final String TAG = "DbDowngradeHelper";
+
+    private static final String KEY_VERSION = "version";
+    private static final String KEY_DOWNGRADE_TO = "downgrade_to_";
+
+    private final SparseArray<String[]> mStatements = new SparseArray<>();
+    public final int version;
+
+    private DbDowngradeHelper(int version) {
+        this.version = version;
+    }
+
+    public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+        ArrayList<String> allCommands = new ArrayList<>();
+
+        for (int i = oldVersion - 1; i >= newVersion; i--) {
+            String[] commands = mStatements.get(i);
+            if (commands == null) {
+                throw new SQLiteException("Downgrade path not supported to version " + i);
+            }
+            Collections.addAll(allCommands, commands);
+        }
+
+        try (SQLiteTransaction t = new SQLiteTransaction(db)) {
+            for (String sql : allCommands) {
+                db.execSQL(sql);
+            }
+            t.commit();
+        }
+    }
+
+    public static DbDowngradeHelper parse(File file) throws JSONException, IOException {
+        JSONObject obj = new JSONObject(new String(IOUtils.toByteArray(file)));
+        DbDowngradeHelper helper = new DbDowngradeHelper(obj.getInt(KEY_VERSION));
+        for (int version = helper.version - 1; version > 0; version--) {
+            if (obj.has(KEY_DOWNGRADE_TO + version)) {
+                JSONArray statements = obj.getJSONArray(KEY_DOWNGRADE_TO + version);
+                String[] parsed = new String[statements.length()];
+                for (int i = 0; i < parsed.length; i++) {
+                    parsed[i] = statements.getString(i);
+                }
+                helper.mStatements.put(version, parsed);
+            }
+        }
+        return helper;
+    }
+
+    public static void updateSchemaFile(File schemaFile, int expectedVersion,
+            Context context, int schemaResId) {
+        try {
+            if (DbDowngradeHelper.parse(schemaFile).version >= expectedVersion) {
+                return;
+            }
+        } catch (Exception e) {
+            // Schema error
+        }
+
+        // Write the updated schema
+        try (FileOutputStream fos = new FileOutputStream(schemaFile);
+            InputStream in = context.getResources().openRawResource(schemaResId)) {
+            IOUtils.copy(in, fos);
+        } catch (IOException e) {
+            Log.e(TAG, "Error writing schema file", e);
+        }
+    }
+}
diff --git a/src/com/android/launcher3/model/ExtendedModelTask.java b/src/com/android/launcher3/model/ExtendedModelTask.java
index 0541966..080aaf5 100644
--- a/src/com/android/launcher3/model/ExtendedModelTask.java
+++ b/src/com/android/launcher3/model/ExtendedModelTask.java
@@ -59,4 +59,15 @@
             }
         });
     }
+
+    public void bindUpdatedWidgets(BgDataModel dataModel) {
+        final MultiHashMap<PackageItemInfo, WidgetItem> widgets
+                = dataModel.widgetsModel.getWidgetsMap();
+        scheduleCallbackTask(new CallbackTask() {
+            @Override
+            public void execute(Callbacks callbacks) {
+                callbacks.bindAllWidgets(widgets);
+            }
+        });
+    }
 }
diff --git a/src/com/android/launcher3/model/LoaderCursor.java b/src/com/android/launcher3/model/LoaderCursor.java
index 36f60b9..1a2c04d 100644
--- a/src/com/android/launcher3/model/LoaderCursor.java
+++ b/src/com/android/launcher3/model/LoaderCursor.java
@@ -219,7 +219,7 @@
             if (!TextUtils.isEmpty(title)) {
                 info.title = Utilities.trim(title);
             }
-        } else if  (hasRestoreFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
+        } else if  (hasRestoreFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)) {
             if (TextUtils.isEmpty(info.title)) {
                 info.title = getTitle();
             }
diff --git a/src/com/android/launcher3/model/LoaderResults.java b/src/com/android/launcher3/model/LoaderResults.java
new file mode 100644
index 0000000..28df64d
--- /dev/null
+++ b/src/com/android/launcher3/model/LoaderResults.java
@@ -0,0 +1,392 @@
+/*
+ * 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 android.util.Log;
+
+import com.android.launcher3.AllAppsList;
+import com.android.launcher3.AppInfo;
+import com.android.launcher3.InvariantDeviceProfile;
+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.Callbacks;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.PagedView;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.ComponentKey;
+import com.android.launcher3.util.MultiHashMap;
+import com.android.launcher3.util.ViewOnDrawExecutor;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.Executor;
+
+/**
+ * Helper class to handle results of {@link com.android.launcher3.LauncherModel.LoaderTask}.
+ */
+public class LoaderResults {
+
+    private static final String TAG = "LoaderResults";
+    private static final long INVALID_SCREEN_ID = -1L;
+    private static final int ITEMS_CHUNK = 6; // batch size for the workspace icons
+
+    private final Executor mUiExecutor;
+
+    private final LauncherAppState mApp;
+    private final BgDataModel mBgDataModel;
+    private final AllAppsList mBgAllAppsList;
+    private final int mPageToBindFirst;
+
+    private final WeakReference<Callbacks> mCallbacks;
+
+    public LoaderResults(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;
+    }
+
+    /**
+     * 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.
+        if (callbacks == null) {
+            // This launcher has exited and nobody bothered to tell us.  Just bail.
+            Log.w(TAG, "LoaderTask running with no launcher");
+            return;
+        }
+
+        // Save a copy of all the bg-thread collections
+        ArrayList<ItemInfo> workspaceItems = new ArrayList<>();
+        ArrayList<LauncherAppWidgetInfo> appWidgets = new ArrayList<>();
+        final ArrayList<Long> orderedScreenIds = new ArrayList<>();
+
+        synchronized (mBgDataModel) {
+            workspaceItems.addAll(mBgDataModel.workspaceItems);
+            appWidgets.addAll(mBgDataModel.appWidgets);
+            orderedScreenIds.addAll(mBgDataModel.workspaceScreens);
+        }
+
+        final int currentScreen;
+        {
+            int currScreen = mPageToBindFirst != PagedView.INVALID_RESTORE_PAGE
+                    ? mPageToBindFirst : callbacks.getCurrentWorkspaceScreen();
+            if (currScreen >= orderedScreenIds.size()) {
+                // There may be no workspace screens (just hotseat items and an empty page).
+                currScreen = PagedView.INVALID_RESTORE_PAGE;
+            }
+            currentScreen = currScreen;
+        }
+        final boolean validFirstPage = currentScreen >= 0;
+        final long currentScreenId =
+                validFirstPage ? orderedScreenIds.get(currentScreen) : INVALID_SCREEN_ID;
+
+        // Separate the items that are on the current screen, and all the other remaining items
+        ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>();
+        ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>();
+        ArrayList<LauncherAppWidgetInfo> currentAppWidgets = new ArrayList<>();
+        ArrayList<LauncherAppWidgetInfo> otherAppWidgets = new ArrayList<>();
+
+        filterCurrentWorkspaceItems(currentScreenId, workspaceItems, currentWorkspaceItems,
+                otherWorkspaceItems);
+        filterCurrentAppWidgets(currentScreenId, appWidgets, currentAppWidgets,
+                otherAppWidgets);
+        sortWorkspaceItemsSpatially(currentWorkspaceItems);
+        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);
+
+        // Bind workspace screens
+        mUiExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                Callbacks callbacks = mCallbacks.get();
+                if (callbacks != null) {
+                    callbacks.bindScreens(orderedScreenIds);
+                }
+            }
+        });
+
+        Executor mainExecutor = mUiExecutor;
+        // Load items on the current page.
+        bindWorkspaceItems(currentWorkspaceItems, 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).
+        // This ensures that the first screen is immediately visible (eg. during rotation)
+        // In case of !validFirstPage, bind all pages one after other.
+        final Executor deferredExecutor =
+                validFirstPage ? new ViewOnDrawExecutor(mUiExecutor) : mainExecutor;
+
+        mainExecutor.execute(new Runnable() {
+            @Override
+            public void run() {
+                Callbacks callbacks = mCallbacks.get();
+                if (callbacks != null) {
+                    callbacks.finishFirstPageBind(
+                            validFirstPage ? (ViewOnDrawExecutor) deferredExecutor : null);
+                }
+            }
+        });
+
+        bindWorkspaceItems(otherWorkspaceItems, 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();
+                }
+            }
+        };
+        deferredExecutor.execute(r);
+
+        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);
+                    }
+                }
+            };
+            mUiExecutor.execute(r);
+        }
+    }
+
+
+    /** Filters the set of items who are directly or indirectly (via another container) on the
+     * specified screen. */
+    private void filterCurrentWorkspaceItems(long currentScreenId,
+            ArrayList<ItemInfo> allWorkspaceItems,
+            ArrayList<ItemInfo> currentScreenItems,
+            ArrayList<ItemInfo> otherScreenItems) {
+        // Purge any null ItemInfos
+        Iterator<ItemInfo> iter = allWorkspaceItems.iterator();
+        while (iter.hasNext()) {
+            ItemInfo i = iter.next();
+            if (i == null) {
+                iter.remove();
+            }
+        }
+
+        // Order the set of items by their containers first, this allows use to walk through the
+        // list sequentially, build up a list of containers that are in the specified screen,
+        // as well as all items in those containers.
+        Set<Long> itemsOnScreen = new HashSet<Long>();
+        Collections.sort(allWorkspaceItems, new Comparator<ItemInfo>() {
+            @Override
+            public int compare(ItemInfo lhs, ItemInfo rhs) {
+                return Utilities.longCompare(lhs.container, rhs.container);
+            }
+        });
+        for (ItemInfo info : allWorkspaceItems) {
+            if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
+                if (info.screenId == currentScreenId) {
+                    currentScreenItems.add(info);
+                    itemsOnScreen.add(info.id);
+                } else {
+                    otherScreenItems.add(info);
+                }
+            } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
+                currentScreenItems.add(info);
+                itemsOnScreen.add(info.id);
+            } else {
+                if (itemsOnScreen.contains(info.container)) {
+                    currentScreenItems.add(info);
+                    itemsOnScreen.add(info.id);
+                } else {
+                    otherScreenItems.add(info);
+                }
+            }
+        }
+    }
+
+    /** Filters the set of widgets which are on the specified screen. */
+    private void filterCurrentAppWidgets(long currentScreenId,
+            ArrayList<LauncherAppWidgetInfo> appWidgets,
+            ArrayList<LauncherAppWidgetInfo> currentScreenWidgets,
+            ArrayList<LauncherAppWidgetInfo> otherScreenWidgets) {
+
+        for (LauncherAppWidgetInfo widget : appWidgets) {
+            if (widget == null) continue;
+            if (widget.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
+                    widget.screenId == currentScreenId) {
+                currentScreenWidgets.add(widget);
+            } else {
+                otherScreenWidgets.add(widget);
+            }
+        }
+    }
+
+    /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to
+     * right) */
+    private void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) {
+        final InvariantDeviceProfile profile = mApp.getInvariantDeviceProfile();
+        final int screenCols = profile.numColumns;
+        final int screenCellCount = profile.numColumns * profile.numRows;
+        Collections.sort(workspaceItems, new Comparator<ItemInfo>() {
+            @Override
+            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) {
+                        case LauncherSettings.Favorites.CONTAINER_DESKTOP: {
+                            long lr = (lhs.screenId * screenCellCount +
+                                    lhs.cellY * screenCols + lhs.cellX);
+                            long rr = (rhs.screenId * screenCellCount +
+                                    rhs.cellY * screenCols + rhs.cellX);
+                            return Utilities.longCompare(lr, rr);
+                        }
+                        case LauncherSettings.Favorites.CONTAINER_HOTSEAT: {
+                            // We currently use the screen id as the rank
+                            return Utilities.longCompare(lhs.screenId, rhs.screenId);
+                        }
+                        default:
+                            if (FeatureFlags.IS_DOGFOOD_BUILD) {
+                                throw new RuntimeException("Unexpected container type when " +
+                                        "sorting workspace items.");
+                            }
+                            return 0;
+                    }
+                } else {
+                    // Between containers, order by hotseat, desktop
+                    return Utilities.longCompare(lhs.container, rhs.container);
+                }
+            }
+        });
+    }
+
+    private void bindWorkspaceItems(final ArrayList<ItemInfo> workspaceItems,
+            final ArrayList<LauncherAppWidgetInfo> appWidgets,
+            final Executor executor) {
+
+        // 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, start, start+chunkSize, false);
+                    }
+                }
+            };
+            executor.execute(r);
+        }
+
+        // Bind the widgets, one at a time
+        N = appWidgets.size();
+        for (int i = 0; i < N; i++) {
+            final LauncherAppWidgetInfo widget = appWidgets.get(i);
+            final Runnable r = new Runnable() {
+                public void run() {
+                    Callbacks callbacks = mCallbacks.get();
+                    if (callbacks != null) {
+                        callbacks.bindAppWidget(widget);
+                    }
+                }
+            };
+            executor.execute(r);
+        }
+    }
+
+    public void bindDeepShortcuts() {
+        final MultiHashMap<ComponentKey, String> shortcutMapCopy;
+        synchronized (mBgDataModel) {
+            shortcutMapCopy = mBgDataModel.deepShortcutMap.clone();
+        }
+        Runnable r = new Runnable() {
+            @Override
+            public void run() {
+                Callbacks callbacks = mCallbacks.get();
+                if (callbacks != null) {
+                    callbacks.bindDeepShortcutMap(shortcutMapCopy);
+                }
+            }
+        };
+        mUiExecutor.execute(r);
+    }
+
+    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);
+    }
+
+    public void bindWidgets() {
+        final MultiHashMap<PackageItemInfo, WidgetItem> widgets
+                = mBgDataModel.widgetsModel.getWidgetsMap();
+        Runnable r = new Runnable() {
+            public void run() {
+                Callbacks callbacks = mCallbacks.get();
+                if (callbacks != null) {
+                    callbacks.bindAllWidgets(widgets);
+                }
+            }
+        };
+        mUiExecutor.execute(r);
+    }
+}
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
new file mode 100644
index 0000000..bcf516e
--- /dev/null
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -0,0 +1,839 @@
+/*
+ * 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 android.appwidget.AppWidgetProviderInfo;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.LauncherActivityInfo;
+import android.content.pm.PackageInstaller;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Process;
+import android.os.SystemClock;
+import android.os.Trace;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.MutableInt;
+
+import com.android.launcher3.AllAppsList;
+import com.android.launcher3.AppInfo;
+import com.android.launcher3.FolderInfo;
+import com.android.launcher3.IconCache;
+import com.android.launcher3.InstallShortcutReceiver;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetInfo;
+import com.android.launcher3.LauncherModel;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.compat.AppWidgetManagerCompat;
+import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.PackageInstallerCompat;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.folder.Folder;
+import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.folder.FolderIconPreviewVerifier;
+import com.android.launcher3.graphics.LauncherIcons;
+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.LooperIdleLock;
+import com.android.launcher3.util.ManagedProfileHeuristic;
+import com.android.launcher3.util.MultiHashMap;
+import com.android.launcher3.util.PackageManagerHelper;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CancellationException;
+
+/**
+ * Runnable for the thread that loads the contents of the launcher:
+ *   - workspace icons
+ *   - widgets
+ *   - all apps icons
+ *   - deep shortcuts within apps
+ */
+public class LoaderTask implements Runnable {
+    private static final boolean DEBUG_LOADERS = false;
+    private static final String TAG = "LoaderTask";
+
+    private final LauncherAppState mApp;
+    private final AllAppsList mBgAllAppsList;
+    private final BgDataModel mBgDataModel;
+
+    private final LoaderResults mResults;
+
+    private final LauncherAppsCompat mLauncherApps;
+    private final UserManagerCompat mUserManager;
+    private final DeepShortcutManager mShortcutManager;
+    private final PackageInstallerCompat mPackageInstaller;
+    private final AppWidgetManagerCompat mAppWidgetManager;
+    private final IconCache mIconCache;
+
+    private boolean mStopped;
+
+    public LoaderTask(LauncherAppState app, AllAppsList bgAllAppsList, BgDataModel dataModel,
+            LoaderResults results) {
+        mApp = app;
+        mBgAllAppsList = bgAllAppsList;
+        mBgDataModel = dataModel;
+        mResults = results;
+
+        mLauncherApps = LauncherAppsCompat.getInstance(mApp.getContext());
+        mUserManager = UserManagerCompat.getInstance(mApp.getContext());
+        mShortcutManager = DeepShortcutManager.getInstance(mApp.getContext());
+        mPackageInstaller = PackageInstallerCompat.getInstance(mApp.getContext());
+        mAppWidgetManager = AppWidgetManagerCompat.getInstance(mApp.getContext());
+        mIconCache = mApp.getIconCache();
+    }
+
+    private synchronized void waitForIdle() {
+        // Wait until the either we're stopped or the other threads are done.
+        // This way we don't start loading all apps until the workspace has settled
+        // down.
+        LooperIdleLock idleLock = new LooperIdleLock(this, Looper.getMainLooper());
+        // Just in case mFlushingWorkerThread changes but we aren't woken up,
+        // wait no longer than 1sec at a time
+        while (!mStopped && idleLock.awaitLocked(1000));
+    }
+
+    private synchronized void verifyNotStopped() throws CancellationException {
+        if (mStopped) {
+            throw new CancellationException("Loader stopped");
+        }
+    }
+
+    public void run() {
+        synchronized (this) {
+            // Skip fast if we are already stopped.
+            if (mStopped) {
+                return;
+            }
+        }
+
+        try (LauncherModel.LoaderTransaction transaction = mApp.getModel().beginLoader(this)) {
+            long now = 0;
+            if (DEBUG_LOADERS) Log.d(TAG, "step 1.1: loading workspace");
+            loadWorkspace();
+
+            verifyNotStopped();
+            if (DEBUG_LOADERS) Log.d(TAG, "step 1.2: bind workspace workspace");
+            mResults.bindWorkspace();
+
+            // Take a break
+            if (DEBUG_LOADERS) {
+                Log.d(TAG, "step 1 completed, wait for idle");
+                now = SystemClock.uptimeMillis();
+            }
+            waitForIdle();
+            if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms");
+            verifyNotStopped();
+
+            // second step
+            if (DEBUG_LOADERS) Log.d(TAG, "step 2.1: loading all apps");
+            loadAllApps();
+
+            if (DEBUG_LOADERS) Log.d(TAG, "step 2.2: Binding all apps");
+            verifyNotStopped();
+            mResults.bindAllApps();
+
+            verifyNotStopped();
+            if (DEBUG_LOADERS) Log.d(TAG, "step 2.3: Update icon cache");
+            updateIconCache();
+
+            // Take a break
+            if (DEBUG_LOADERS) {
+                Log.d(TAG, "step 2 completed, wait for idle");
+                now = SystemClock.uptimeMillis();
+            }
+            waitForIdle();
+            if (DEBUG_LOADERS) Log.d(TAG, "Waited " + (SystemClock.uptimeMillis() - now) + "ms");
+            verifyNotStopped();
+
+            // third step
+            if (DEBUG_LOADERS) Log.d(TAG, "step 3.1: loading deep shortcuts");
+            loadDeepShortcuts();
+
+            verifyNotStopped();
+            if (DEBUG_LOADERS) Log.d(TAG, "step 3.2: bind deep shortcuts");
+            mResults.bindDeepShortcuts();
+
+            // Take a break
+            if (DEBUG_LOADERS) Log.d(TAG, "step 3 completed, wait for idle");
+            waitForIdle();
+            verifyNotStopped();
+
+            // fourth step
+            if (DEBUG_LOADERS) Log.d(TAG, "step 4.1: loading widgets");
+            mBgDataModel.widgetsModel.update(mApp, null);
+
+            verifyNotStopped();
+            if (DEBUG_LOADERS) Log.d(TAG, "step 4.2: Binding widgets");
+            mResults.bindWidgets();
+
+            transaction.commit();
+        } catch (CancellationException e) {
+          // Loader stopped, ignore
+        }
+    }
+
+    public synchronized void stopLocked() {
+        mStopped = true;
+        this.notify();
+    }
+
+    private void loadWorkspace() {
+        if (LauncherAppState.PROFILE_STARTUP) {
+            Trace.beginSection("Loading Workspace");
+        }
+
+        final Context context = mApp.getContext();
+        final ContentResolver contentResolver = context.getContentResolver();
+        final PackageManagerHelper pmHelper = new PackageManagerHelper(context);
+        final boolean isSafeMode = pmHelper.isSafeMode();
+        final boolean isSdCardReady = Utilities.isBootCompleted();
+        final MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>();
+
+        boolean clearDb = false;
+        try {
+            ImportDataTask.performImportIfPossible(context);
+        } catch (Exception e) {
+            // Migration failed. Clear workspace.
+            clearDb = true;
+        }
+
+        if (!clearDb && GridSizeMigrationTask.ENABLED &&
+                !GridSizeMigrationTask.migrateGridIfNeeded(context)) {
+            // Migration failed. Clear workspace.
+            clearDb = true;
+        }
+
+        if (clearDb) {
+            Log.d(TAG, "loadWorkspace: resetting launcher database");
+            LauncherSettings.Settings.call(contentResolver,
+                    LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
+        }
+
+        Log.d(TAG, "loadWorkspace: loading default favorites");
+        LauncherSettings.Settings.call(contentResolver,
+                LauncherSettings.Settings.METHOD_LOAD_DEFAULT_FAVORITES);
+
+        synchronized (mBgDataModel) {
+            mBgDataModel.clear();
+
+            final HashMap<String, Integer> installingPkgs =
+                    mPackageInstaller.updateAndGetActiveSessionCache();
+            mBgDataModel.workspaceScreens.addAll(LauncherModel.loadWorkspaceScreensDb(context));
+
+            Map<ShortcutKey, ShortcutInfoCompat> shortcutKeyToPinnedShortcuts = new HashMap<>();
+            final LoaderCursor c = new LoaderCursor(contentResolver.query(
+                    LauncherSettings.Favorites.CONTENT_URI, null, null, null, null), mApp);
+
+            HashMap<ComponentKey, AppWidgetProviderInfo> widgetProvidersMap = null;
+
+            try {
+                final int appWidgetIdIndex = c.getColumnIndexOrThrow(
+                        LauncherSettings.Favorites.APPWIDGET_ID);
+                final int appWidgetProviderIndex = c.getColumnIndexOrThrow(
+                        LauncherSettings.Favorites.APPWIDGET_PROVIDER);
+                final int spanXIndex = c.getColumnIndexOrThrow
+                        (LauncherSettings.Favorites.SPANX);
+                final int spanYIndex = c.getColumnIndexOrThrow(
+                        LauncherSettings.Favorites.SPANY);
+                final int rankIndex = c.getColumnIndexOrThrow(
+                        LauncherSettings.Favorites.RANK);
+                final int optionsIndex = c.getColumnIndexOrThrow(
+                        LauncherSettings.Favorites.OPTIONS);
+
+                final LongSparseArray<UserHandle> allUsers = c.allUsers;
+                final LongSparseArray<Boolean> quietMode = new LongSparseArray<>();
+                final LongSparseArray<Boolean> unlockedUsers = new LongSparseArray<>();
+                for (UserHandle user : mUserManager.getUserProfiles()) {
+                    long serialNo = mUserManager.getSerialNumberForUser(user);
+                    allUsers.put(serialNo, user);
+                    quietMode.put(serialNo, mUserManager.isQuietModeEnabled(user));
+
+                    boolean userUnlocked = mUserManager.isUserUnlocked(user);
+
+                    // We can only query for shortcuts when the user is unlocked.
+                    if (userUnlocked) {
+                        List<ShortcutInfoCompat> pinnedShortcuts =
+                                mShortcutManager.queryForPinnedShortcuts(null, user);
+                        if (mShortcutManager.wasLastCallSuccess()) {
+                            for (ShortcutInfoCompat shortcut : pinnedShortcuts) {
+                                shortcutKeyToPinnedShortcuts.put(ShortcutKey.fromInfo(shortcut),
+                                        shortcut);
+                            }
+                        } else {
+                            // Shortcut manager can fail due to some race condition when the
+                            // lock state changes too frequently. For the purpose of the loading
+                            // shortcuts, consider the user is still locked.
+                            userUnlocked = false;
+                        }
+                    }
+                    unlockedUsers.put(serialNo, userUnlocked);
+                }
+
+                ShortcutInfo info;
+                LauncherAppWidgetInfo appWidgetInfo;
+                Intent intent;
+                String targetPkg;
+
+                FolderIconPreviewVerifier verifier =
+                        new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile());
+                while (!mStopped && c.moveToNext()) {
+                    try {
+                        if (c.user == null) {
+                            // User has been deleted, remove the item.
+                            c.markDeleted("User has been deleted");
+                            continue;
+                        }
+
+                        boolean allowMissingTarget = false;
+                        switch (c.itemType) {
+                        case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
+                        case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
+                        case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+                            intent = c.parseIntent();
+                            if (intent == null) {
+                                c.markDeleted("Invalid or null intent");
+                                continue;
+                            }
+
+                            int disabledState = quietMode.get(c.serialNumber) ?
+                                    ShortcutInfo.FLAG_DISABLED_QUIET_USER : 0;
+                            ComponentName cn = intent.getComponent();
+                            targetPkg = cn == null ? intent.getPackage() : cn.getPackageName();
+
+                            if (!Process.myUserHandle().equals(c.user)) {
+                                if (c.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
+                                    c.markDeleted("Legacy shortcuts are only allowed for default user");
+                                    continue;
+                                } else if (c.restoreFlag != 0) {
+                                    // Don't restore items for other profiles.
+                                    c.markDeleted("Restore from managed profile not supported");
+                                    continue;
+                                }
+                            }
+                            if (TextUtils.isEmpty(targetPkg) &&
+                                    c.itemType != LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
+                                c.markDeleted("Only legacy shortcuts can have null package");
+                                continue;
+                            }
+
+                            // If there is no target package, its an implicit intent
+                            // (legacy shortcut) which is always valid
+                            boolean validTarget = TextUtils.isEmpty(targetPkg) ||
+                                    mLauncherApps.isPackageEnabledForProfile(targetPkg, c.user);
+
+                            if (cn != null && validTarget) {
+                                // If the apk is present and the shortcut points to a specific
+                                // component.
+
+                                // If the component is already present
+                                if (mLauncherApps.isActivityEnabledForProfile(cn, c.user)) {
+                                    // no special handling necessary for this item
+                                    c.markRestored();
+                                } else {
+                                    if (c.hasRestoreFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)) {
+                                        // We allow auto install apps to have their intent
+                                        // updated after an install.
+                                        intent = pmHelper.getAppLaunchIntent(targetPkg, c.user);
+                                        if (intent != null) {
+                                            c.restoreFlag = 0;
+                                            c.updater().put(
+                                                    LauncherSettings.Favorites.INTENT,
+                                                    intent.toUri(0)).commit();
+                                            cn = intent.getComponent();
+                                        } else {
+                                            c.markDeleted("Unable to find a launch target");
+                                            continue;
+                                        }
+                                    } else {
+                                        // The app is installed but the component is no
+                                        // longer available.
+                                        c.markDeleted("Invalid component removed: " + cn);
+                                        continue;
+                                    }
+                                }
+                            }
+                            // else if cn == null => can't infer much, leave it
+                            // else if !validPkg => could be restored icon or missing sd-card
+
+                            if (!TextUtils.isEmpty(targetPkg) && !validTarget) {
+                                // Points to a valid app (superset of cn != null) but the apk
+                                // is not available.
+
+                                if (c.restoreFlag != 0) {
+                                    // Package is not yet available but might be
+                                    // installed later.
+                                    FileLog.d(TAG, "package not yet restored: " + targetPkg);
+
+                                    if (c.hasRestoreFlag(ShortcutInfo.FLAG_RESTORE_STARTED)) {
+                                        // Restore has started once.
+                                    } else if (installingPkgs.containsKey(targetPkg)) {
+                                        // App restore has started. Update the flag
+                                        c.restoreFlag |= ShortcutInfo.FLAG_RESTORE_STARTED;
+                                        c.updater().commit();
+                                    } else {
+                                        c.markDeleted("Unrestored app removed: " + targetPkg);
+                                        continue;
+                                    }
+                                } else if (pmHelper.isAppOnSdcard(targetPkg, c.user)) {
+                                    // Package is present but not available.
+                                    disabledState |= ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
+                                    // Add the icon on the workspace anyway.
+                                    allowMissingTarget = true;
+                                } else if (!isSdCardReady) {
+                                    // SdCard is not ready yet. Package might get available,
+                                    // once it is ready.
+                                    Log.d(TAG, "Missing pkg, will check later: " + targetPkg);
+                                    pendingPackages.addToList(c.user, targetPkg);
+                                    // Add the icon on the workspace anyway.
+                                    allowMissingTarget = true;
+                                } else {
+                                    // Do not wait for external media load anymore.
+                                    c.markDeleted("Invalid package removed: " + targetPkg);
+                                    continue;
+                                }
+                            }
+
+                            if (validTarget) {
+                                // The shortcut points to a valid target (either no target
+                                // or something which is ready to be used)
+                                c.markRestored();
+                            }
+
+                            boolean useLowResIcon = !c.isOnWorkspaceOrHotseat() &&
+                                    !verifier.isItemInPreview(c.getInt(rankIndex));
+
+                            if (c.restoreFlag != 0) {
+                                // Already verified above that user is same as default user
+                                info = c.getRestoredItemInfo(intent);
+                            } else if (c.itemType ==
+                                    LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+                                info = c.getAppShortcutInfo(
+                                        intent, allowMissingTarget, useLowResIcon);
+                            } else if (c.itemType ==
+                                    LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+
+                                ShortcutKey key = ShortcutKey.fromIntent(intent, c.user);
+                                if (unlockedUsers.get(c.serialNumber)) {
+                                    ShortcutInfoCompat pinnedShortcut =
+                                            shortcutKeyToPinnedShortcuts.get(key);
+                                    if (pinnedShortcut == null) {
+                                        // The shortcut is no longer valid.
+                                        c.markDeleted("Pinned shortcut not found");
+                                        continue;
+                                    }
+                                    info = new ShortcutInfo(pinnedShortcut, context);
+                                    info.iconBitmap = LauncherIcons
+                                            .createShortcutIcon(pinnedShortcut, context);
+                                    if (pmHelper.isAppSuspended(
+                                            pinnedShortcut.getPackage(), info.user)) {
+                                        info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
+                                    }
+                                    intent = info.intent;
+                                } else {
+                                    // Create a shortcut info in disabled mode for now.
+                                    info = c.loadSimpleShortcut();
+                                    info.isDisabled |= ShortcutInfo.FLAG_DISABLED_LOCKED_USER;
+                                }
+                            } else { // item type == ITEM_TYPE_SHORTCUT
+                                info = c.loadSimpleShortcut();
+
+                                // Shortcuts are only available on the primary profile
+                                if (!TextUtils.isEmpty(targetPkg)
+                                        && pmHelper.isAppSuspended(targetPkg, c.user)) {
+                                    disabledState |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
+                                }
+
+                                // App shortcuts that used to be automatically added to Launcher
+                                // didn't always have the correct intent flags set, so do that
+                                // here
+                                if (intent.getAction() != null &&
+                                    intent.getCategories() != null &&
+                                    intent.getAction().equals(Intent.ACTION_MAIN) &&
+                                    intent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
+                                    intent.addFlags(
+                                        Intent.FLAG_ACTIVITY_NEW_TASK |
+                                        Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+                                }
+                            }
+
+                            if (info != null) {
+                                c.applyCommonProperties(info);
+
+                                info.intent = intent;
+                                info.rank = c.getInt(rankIndex);
+                                info.spanX = 1;
+                                info.spanY = 1;
+                                info.isDisabled |= disabledState;
+                                if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
+                                    info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE;
+                                }
+
+                                if (c.restoreFlag != 0 && !TextUtils.isEmpty(targetPkg)) {
+                                    Integer progress = installingPkgs.get(targetPkg);
+                                    if (progress != null) {
+                                        info.setInstallProgress(progress);
+                                    } else {
+                                        info.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
+                                    }
+                                }
+
+                                c.checkAndAddItem(info, mBgDataModel);
+                            } else {
+                                throw new RuntimeException("Unexpected null ShortcutInfo");
+                            }
+                            break;
+
+                        case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
+                            FolderInfo folderInfo = mBgDataModel.findOrMakeFolder(c.id);
+                            c.applyCommonProperties(folderInfo);
+
+                            // Do not trim the folder label, as is was set by the user.
+                            folderInfo.title = c.getString(c.titleIndex);
+                            folderInfo.spanX = 1;
+                            folderInfo.spanY = 1;
+                            folderInfo.options = c.getInt(optionsIndex);
+
+                            // no special handling required for restored folders
+                            c.markRestored();
+
+                            c.checkAndAddItem(folderInfo, mBgDataModel);
+                            break;
+
+                        case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
+                        case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
+                            // Read all Launcher-specific widget details
+                            boolean customWidget = c.itemType ==
+                                LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET;
+
+                            int appWidgetId = c.getInt(appWidgetIdIndex);
+                            String savedProvider = c.getString(appWidgetProviderIndex);
+
+                            final ComponentName component =
+                                    ComponentName.unflattenFromString(savedProvider);
+
+                            final boolean isIdValid = !c.hasRestoreFlag(
+                                    LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
+                            final boolean wasProviderReady = !c.hasRestoreFlag(
+                                    LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY);
+
+                            if (widgetProvidersMap == null) {
+                                widgetProvidersMap = mAppWidgetManager.getAllProvidersMap();
+                            }
+                            final AppWidgetProviderInfo provider = widgetProvidersMap.get(
+                                    new ComponentKey(
+                                            ComponentName.unflattenFromString(savedProvider),
+                                            c.user));
+
+                            final boolean isProviderReady = isValidProvider(provider);
+                            if (!isSafeMode && !customWidget &&
+                                    wasProviderReady && !isProviderReady) {
+                                c.markDeleted(
+                                        "Deleting widget that isn't installed anymore: "
+                                        + provider);
+                            } else {
+                                if (isProviderReady) {
+                                    appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
+                                            provider.provider);
+
+                                    // The provider is available. So the widget is either
+                                    // available or not available. We do not need to track
+                                    // any future restore updates.
+                                    int status = c.restoreFlag &
+                                            ~LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
+                                    if (!wasProviderReady) {
+                                        // If provider was not previously ready, update the
+                                        // status and UI flag.
+
+                                        // Id would be valid only if the widget restore broadcast was received.
+                                        if (isIdValid) {
+                                            status |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
+                                        } else {
+                                            status &= ~LauncherAppWidgetInfo
+                                                    .FLAG_PROVIDER_NOT_READY;
+                                        }
+                                    }
+                                    appWidgetInfo.restoreStatus = status;
+                                } else {
+                                    Log.v(TAG, "Widget restore pending id=" + c.id
+                                            + " appWidgetId=" + appWidgetId
+                                            + " status =" + c.restoreFlag);
+                                    appWidgetInfo = new LauncherAppWidgetInfo(appWidgetId,
+                                            component);
+                                    appWidgetInfo.restoreStatus = c.restoreFlag;
+                                    Integer installProgress = installingPkgs.get(component.getPackageName());
+
+                                    if (c.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_RESTORE_STARTED)) {
+                                        // Restore has started once.
+                                    } else if (installProgress != null) {
+                                        // App restore has started. Update the flag
+                                        appWidgetInfo.restoreStatus |=
+                                                LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
+                                    } else if (!isSafeMode) {
+                                        c.markDeleted("Unrestored widget removed: " + component);
+                                        continue;
+                                    }
+
+                                    appWidgetInfo.installProgress =
+                                            installProgress == null ? 0 : installProgress;
+                                }
+                                if (appWidgetInfo.hasRestoreFlag(
+                                        LauncherAppWidgetInfo.FLAG_DIRECT_CONFIG)) {
+                                    appWidgetInfo.bindOptions = c.parseIntent();
+                                }
+
+                                c.applyCommonProperties(appWidgetInfo);
+                                appWidgetInfo.spanX = c.getInt(spanXIndex);
+                                appWidgetInfo.spanY = c.getInt(spanYIndex);
+                                appWidgetInfo.user = c.user;
+
+                                if (!c.isOnWorkspaceOrHotseat()) {
+                                    c.markDeleted("Widget found where container != " +
+                                            "CONTAINER_DESKTOP nor CONTAINER_HOTSEAT - ignoring!");
+                                    continue;
+                                }
+
+                                if (!customWidget) {
+                                    String providerName =
+                                            appWidgetInfo.providerName.flattenToString();
+                                    if (!providerName.equals(savedProvider) ||
+                                            (appWidgetInfo.restoreStatus != c.restoreFlag)) {
+                                        c.updater()
+                                                .put(LauncherSettings.Favorites.APPWIDGET_PROVIDER,
+                                                        providerName)
+                                                .put(LauncherSettings.Favorites.RESTORED,
+                                                        appWidgetInfo.restoreStatus)
+                                                .commit();
+                                    }
+                                }
+
+                                if (appWidgetInfo.restoreStatus !=
+                                        LauncherAppWidgetInfo.RESTORE_COMPLETED) {
+                                    String pkg = appWidgetInfo.providerName.getPackageName();
+                                    appWidgetInfo.pendingItemInfo = new PackageItemInfo(pkg);
+                                    appWidgetInfo.pendingItemInfo.user = appWidgetInfo.user;
+                                    mIconCache.getTitleAndIconForApp(
+                                            appWidgetInfo.pendingItemInfo, false);
+                                }
+
+                                c.checkAndAddItem(appWidgetInfo, mBgDataModel);
+                            }
+                            break;
+                        }
+                    } catch (Exception e) {
+                        Log.e(TAG, "Desktop items loading interrupted", e);
+                    }
+                }
+            } finally {
+                Utilities.closeSilently(c);
+            }
+
+            // Break early if we've stopped loading
+            if (mStopped) {
+                mBgDataModel.clear();
+                return;
+            }
+
+            // Remove dead items
+            if (c.commitDeleted()) {
+                // Remove any empty folder
+                ArrayList<Long> deletedFolderIds = (ArrayList<Long>) LauncherSettings.Settings
+                        .call(contentResolver,
+                                LauncherSettings.Settings.METHOD_DELETE_EMPTY_FOLDERS)
+                        .getSerializable(LauncherSettings.Settings.EXTRA_VALUE);
+                for (long folderId : deletedFolderIds) {
+                    mBgDataModel.workspaceItems.remove(mBgDataModel.folders.get(folderId));
+                    mBgDataModel.folders.remove(folderId);
+                    mBgDataModel.itemsIdMap.remove(folderId);
+                }
+
+                // Remove any ghost widgets
+                LauncherSettings.Settings.call(contentResolver,
+                        LauncherSettings.Settings.METHOD_REMOVE_GHOST_WIDGETS);
+            }
+
+            // Unpin shortcuts that don't exist on the workspace.
+            HashSet<ShortcutKey> pendingShortcuts =
+                    InstallShortcutReceiver.getPendingShortcuts(context);
+            for (ShortcutKey key : shortcutKeyToPinnedShortcuts.keySet()) {
+                MutableInt numTimesPinned = mBgDataModel.pinnedShortcutCounts.get(key);
+                if ((numTimesPinned == null || numTimesPinned.value == 0)
+                        && !pendingShortcuts.contains(key)) {
+                    // Shortcut is pinned but doesn't exist on the workspace; unpin it.
+                    mShortcutManager.unpinShortcut(key);
+                }
+            }
+
+            FolderIconPreviewVerifier verifier =
+                    new FolderIconPreviewVerifier(mApp.getInvariantDeviceProfile());
+            // Sort the folder items and make sure all items in the preview are high resolution.
+            for (FolderInfo folder : mBgDataModel.folders) {
+                Collections.sort(folder.contents, Folder.ITEM_POS_COMPARATOR);
+                verifier.setFolderInfo(folder);
+
+                int numItemsInPreview = 0;
+                for (ShortcutInfo info : folder.contents) {
+                    if (info.usingLowResIcon
+                            && info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
+                            && verifier.isItemInPreview(info.rank)) {
+                        mIconCache.getTitleAndIcon(info, false);
+                        numItemsInPreview++;
+                    }
+
+                    if (numItemsInPreview >= FolderIcon.NUM_ITEMS_IN_PREVIEW) {
+                        break;
+                    }
+                }
+            }
+
+            c.commitRestoredItems();
+            if (!isSdCardReady && !pendingPackages.isEmpty()) {
+                context.registerReceiver(
+                        new SdCardAvailableReceiver(mApp, pendingPackages),
+                        new IntentFilter(Intent.ACTION_BOOT_COMPLETED),
+                        null,
+                        new Handler(LauncherModel.getWorkerLooper()));
+            }
+
+            // Remove any empty screens
+            ArrayList<Long> unusedScreens = new ArrayList<>(mBgDataModel.workspaceScreens);
+            for (ItemInfo item: mBgDataModel.itemsIdMap) {
+                long screenId = item.screenId;
+                if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
+                        unusedScreens.contains(screenId)) {
+                    unusedScreens.remove(screenId);
+                }
+            }
+
+            // If there are any empty screens remove them, and update.
+            if (unusedScreens.size() != 0) {
+                mBgDataModel.workspaceScreens.removeAll(unusedScreens);
+                LauncherModel.updateWorkspaceScreenOrder(context, mBgDataModel.workspaceScreens);
+            }
+        }
+        if (LauncherAppState.PROFILE_STARTUP) {
+            Trace.endSection();
+        }
+    }
+
+    private void updateIconCache() {
+        // Ignore packages which have a promise icon.
+        HashSet<String> packagesToIgnore = new HashSet<>();
+        synchronized (mBgDataModel) {
+            for (ItemInfo info : mBgDataModel.itemsIdMap) {
+                if (info instanceof ShortcutInfo) {
+                    ShortcutInfo si = (ShortcutInfo) info;
+                    if (si.isPromise() && si.getTargetComponent() != null) {
+                        packagesToIgnore.add(si.getTargetComponent().getPackageName());
+                    }
+                } else if (info instanceof LauncherAppWidgetInfo) {
+                    LauncherAppWidgetInfo lawi = (LauncherAppWidgetInfo) info;
+                    if (lawi.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)) {
+                        packagesToIgnore.add(lawi.providerName.getPackageName());
+                    }
+                }
+            }
+        }
+        mIconCache.updateDbIcons(packagesToIgnore);
+    }
+
+    private void loadAllApps() {
+        final long loadTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
+
+        final List<UserHandle> profiles = mUserManager.getUserProfiles();
+
+        // Clear the list of apps
+        mBgAllAppsList.clear();
+        for (UserHandle user : profiles) {
+            // Query for the set of apps
+            final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
+            final List<LauncherActivityInfo> apps = mLauncherApps.getActivityList(null, user);
+            if (DEBUG_LOADERS) {
+                Log.d(TAG, "getActivityList took "
+                        + (SystemClock.uptimeMillis()-qiaTime) + "ms for user " + user);
+                Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user);
+            }
+            // Fail if we don't have any apps
+            // TODO: Fix this. Only fail for the current user.
+            if (apps == null || apps.isEmpty()) {
+                return;
+            }
+            boolean quietMode = mUserManager.isQuietModeEnabled(user);
+            // Create the ApplicationInfos
+            for (int i = 0; i < apps.size(); i++) {
+                LauncherActivityInfo app = apps.get(i);
+                // This builds the icon bitmaps.
+                mBgAllAppsList.add(new AppInfo(app, user, quietMode), app);
+            }
+
+            ManagedProfileHeuristic.onAllAppsLoaded(mApp.getContext(), apps, user);
+        }
+
+        if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) {
+            // get all active sessions and add them to the all apps list
+            for (PackageInstaller.SessionInfo info :
+                    mPackageInstaller.getAllVerifiedSessions()) {
+                mBgAllAppsList.addPromiseApp(mApp.getContext(),
+                        PackageInstallerCompat.PackageInstallInfo.fromInstallingState(info));
+            }
+        }
+
+        mBgAllAppsList.added = new ArrayList<>();
+        if (DEBUG_LOADERS) {
+            Log.d(TAG, "All apps loaded in in "
+                    + (SystemClock.uptimeMillis() - loadTime) + "ms");
+        }
+    }
+
+    private void loadDeepShortcuts() {
+        mBgDataModel.deepShortcutMap.clear();
+        mBgDataModel.hasShortcutHostPermission = mShortcutManager.hasHostPermission();
+        if (mBgDataModel.hasShortcutHostPermission) {
+            for (UserHandle user : mUserManager.getUserProfiles()) {
+                if (mUserManager.isUserUnlocked(user)) {
+                    List<ShortcutInfoCompat> shortcuts =
+                            mShortcutManager.queryForAllShortcuts(user);
+                    mBgDataModel.updateDeepShortcutMap(null, user, shortcuts);
+                }
+            }
+        }
+    }
+
+    public static boolean isValidProvider(AppWidgetProviderInfo provider) {
+        return (provider != null) && (provider.provider != null)
+                && (provider.provider.getPackageName() != null);
+    }
+}
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
index 4931dca..032ed78 100644
--- a/src/com/android/launcher3/model/ModelWriter.java
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -34,7 +34,7 @@
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.util.ContentWriter;
 import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.LooperExecuter;
+import com.android.launcher3.util.LooperExecutor;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -55,7 +55,7 @@
     public ModelWriter(Context context, BgDataModel dataModel, boolean hasVerticalHotseat) {
         mContext = context;
         mBgDataModel = dataModel;
-        mWorkerExecutor = new LooperExecuter(LauncherModel.getWorkerLooper());
+        mWorkerExecutor = new LooperExecutor(LauncherModel.getWorkerLooper());
         mHasVerticalHotseat = hasVerticalHotseat;
     }
 
diff --git a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
index 5d04325..76b90a8 100644
--- a/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
+++ b/src/com/android/launcher3/model/PackageInstallStateChangedTask.java
@@ -18,15 +18,18 @@
 import android.content.ComponentName;
 
 import com.android.launcher3.AllAppsList;
+import com.android.launcher3.AppInfo;
 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.PromiseAppInfo;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
 
+import java.util.ArrayList;
 import java.util.HashSet;
 
 /**
@@ -47,6 +50,44 @@
             return;
         }
 
+        synchronized (apps) {
+            PromiseAppInfo updated = null;
+            final ArrayList<AppInfo> removed = new ArrayList<>();
+            for (int i=0; i < apps.size(); i++) {
+                final AppInfo appInfo = apps.get(i);
+                final ComponentName tgtComp = appInfo.getTargetComponent();
+                if (tgtComp != null && tgtComp.getPackageName().equals(mInstallInfo.packageName)) {
+                    if (appInfo instanceof PromiseAppInfo) {
+                        final PromiseAppInfo promiseAppInfo = (PromiseAppInfo) appInfo;
+                        if (mInstallInfo.state == PackageInstallerCompat.STATUS_INSTALLING) {
+                            promiseAppInfo.level = mInstallInfo.progress;
+                            updated = promiseAppInfo;
+                        } else if (mInstallInfo.state == PackageInstallerCompat.STATUS_FAILED) {
+                            apps.removePromiseApp(appInfo);
+                            removed.add(appInfo);
+                        }
+                    }
+                }
+            }
+            if (updated != null) {
+                final PromiseAppInfo updatedPromiseApp = updated;
+                scheduleCallbackTask(new CallbackTask() {
+                    @Override
+                    public void execute(Callbacks callbacks) {
+                        callbacks.bindPromiseAppProgressUpdated(updatedPromiseApp);
+                    }
+                });
+            }
+            if (!removed.isEmpty()) {
+                scheduleCallbackTask(new CallbackTask() {
+                    @Override
+                    public void execute(Callbacks callbacks) {
+                        callbacks.bindAppInfosRemoved(removed);
+                    }
+                });
+            }
+        }
+
         synchronized (dataModel) {
             final HashSet<ItemInfo> updates = new HashSet<>();
             for (ItemInfo info : dataModel.itemsIdMap) {
@@ -56,7 +97,6 @@
                     if (si.isPromise() && (cn != null)
                             && mInstallInfo.packageName.equals(cn.getPackageName())) {
                         si.setInstallProgress(mInstallInfo.progress);
-
                         if (mInstallInfo.state == PackageInstallerCompat.STATUS_FAILED) {
                             // Mark this info as broken.
                             si.status &= ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index f03c9c7..46fea21 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -18,9 +18,8 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.graphics.Bitmap;
+import android.os.Process;
 import android.os.UserHandle;
 import android.util.Log;
 
@@ -36,14 +35,17 @@
 import com.android.launcher3.LauncherModel.Callbacks;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.SessionCommitReceiver;
 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.config.FeatureFlags;
 import com.android.launcher3.graphics.LauncherIcons;
 import com.android.launcher3.util.FlagOp;
 import com.android.launcher3.util.ItemInfoMatcher;
-import com.android.launcher3.util.ManagedProfileHeuristic;
+import com.android.launcher3.util.MultiHashMap;
+import com.android.launcher3.util.PackageManagerHelper;
 import com.android.launcher3.util.PackageUserKey;
 
 import java.util.ArrayList;
@@ -95,12 +97,15 @@
                 for (int i = 0; i < N; i++) {
                     if (DEBUG) Log.d(TAG, "mAllAppsList.addPackage " + packages[i]);
                     iconCache.updateIconsForPkg(packages[i], mUser);
+                    if (FeatureFlags.LAUNCHER3_PROMISE_APPS_IN_ALL_APPS) {
+                        appsList.removePackage(packages[i], Process.myUserHandle());
+                    }
                     appsList.addPackage(context, packages[i], mUser);
-                }
 
-                ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(context, mUser);
-                if (heuristic != null) {
-                    heuristic.processPackageAdd(mPackages);
+                    // Automatically add homescreen icon for work profile apps for below O device.
+                    if (!Utilities.isAtLeastO() && !Process.myUserHandle().equals(mUser)) {
+                        SessionCommitReceiver.queueAppIconAddition(context, packages[i], mUser);
+                    }
                 }
                 break;
             }
@@ -115,10 +120,6 @@
                 flagOp = FlagOp.removeFlag(ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE);
                 break;
             case OP_REMOVE: {
-                ManagedProfileHeuristic heuristic = ManagedProfileHeuristic.get(context, mUser);
-                if (heuristic != null) {
-                    heuristic.processPackageRemoved(mPackages);
-                }
                 for (int i = 0; i < N; i++) {
                     iconCache.removeIconsForPkg(packages[i], mUser);
                 }
@@ -222,18 +223,17 @@
                         if (cn != null && matcher.matches(si, cn)) {
                             AppInfo appInfo = addedOrUpdatedApps.get(cn);
 
-                            if (si.isPromise() && mOp == OP_ADD) {
-                                if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
+                            // For system apps, package manager send OP_UPDATE when an
+                            // app is enabled.
+                            if (si.isPromise() && (mOp == OP_ADD || mOp == OP_UPDATE)) {
+                                if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINSTALL_ICON)) {
                                     // Auto install icon
-                                    PackageManager pm = context.getPackageManager();
-                                    ResolveInfo matched = pm.resolveActivity(
-                                            new Intent(Intent.ACTION_MAIN)
-                                                    .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER),
-                                            PackageManager.MATCH_DEFAULT_ONLY);
-                                    if (matched == null) {
+                                    LauncherAppsCompat launcherApps
+                                            = LauncherAppsCompat.getInstance(context);
+                                    if (!launcherApps.isActivityEnabledForProfile(cn, mUser)) {
                                         // Try to find the best match activity.
-                                        Intent intent = pm.getLaunchIntentForPackage(
-                                                cn.getPackageName());
+                                        Intent intent = new PackageManagerHelper(context)
+                                                .getAppLaunchIntent(cn.getPackageName(), mUser);
                                         if (intent != null) {
                                             cn = intent.getComponent();
                                             appInfo = addedOrUpdatedApps.get(cn);
@@ -374,11 +374,9 @@
         } else if (Utilities.isAtLeastO() && mOp == OP_ADD) {
             // Load widgets for the new package.
             for (int i = 0; i < N; i++) {
-                LauncherModel model = app.getModel();
-                model.refreshAndBindWidgetsAndShortcuts(
-                        model.getCallback(), false /* bindFirst */,
-                        new PackageUserKey(packages[i], mUser) /* packageUser */);
+                dataModel.widgetsModel.update(app, new PackageUserKey(packages[i], mUser));
             }
+            bindUpdatedWidgets(dataModel);
         }
     }
 }
diff --git a/src/com/android/launcher3/model/SdCardAvailableReceiver.java b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
index 278669b..3aedae6 100644
--- a/src/com/android/launcher3/model/SdCardAvailableReceiver.java
+++ b/src/com/android/launcher3/model/SdCardAvailableReceiver.java
@@ -19,9 +19,9 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.os.UserHandle;
 
+import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.MultiHashMap;
@@ -44,10 +44,10 @@
     private final Context mContext;
     private final MultiHashMap<UserHandle, String> mPackages;
 
-    public SdCardAvailableReceiver(LauncherModel model, Context context,
+    public SdCardAvailableReceiver(LauncherAppState app,
             MultiHashMap<UserHandle, String> packages) {
-        mModel = model;
-        mContext = context;
+        mModel = app.getModel();
+        mContext = app.getContext();
         mPackages = packages;
     }
 
diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java
index d8a429c..47e83e5 100644
--- a/src/com/android/launcher3/model/ShortcutsChangedTask.java
+++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java
@@ -21,7 +21,6 @@
 import com.android.launcher3.AllAppsList;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.graphics.LauncherIcons;
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index 363f1ee..fefed75 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -21,7 +21,6 @@
 import com.android.launcher3.AllAppsList;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.compat.UserManagerCompat;
diff --git a/src/com/android/launcher3/model/WidgetsModel.java b/src/com/android/launcher3/model/WidgetsModel.java
index e5215c7..ed900bf 100644
--- a/src/com/android/launcher3/model/WidgetsModel.java
+++ b/src/com/android/launcher3/model/WidgetsModel.java
@@ -18,7 +18,7 @@
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.ShortcutConfigActivityInfo;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.MultiHashMap;
 import com.android.launcher3.util.PackageUserKey;
 import com.android.launcher3.util.Preconditions;
@@ -38,36 +38,26 @@
     private static final boolean DEBUG = false;
 
     /* Map of widgets and shortcuts that are tracked per package. */
-    private final MultiHashMap<PackageItemInfo, WidgetItem> mWidgetsList;
+    private final MultiHashMap<PackageItemInfo, WidgetItem> mWidgetsList = new MultiHashMap<>();
 
-    private final IconCache mIconCache;
-    private final AppFilter mAppFilter;
+    private AppFilter mAppFilter;
 
-    public WidgetsModel(IconCache iconCache, AppFilter appFilter) {
-        mIconCache = iconCache;
-        mAppFilter = appFilter;
-        mWidgetsList = new MultiHashMap<>();
-    }
-
-    public MultiHashMap<PackageItemInfo, WidgetItem> getWidgetsMap() {
-        return mWidgetsList;
-    }
-
-    public boolean isEmpty() {
-        return mWidgetsList.isEmpty();
+    public synchronized MultiHashMap<PackageItemInfo, WidgetItem> getWidgetsMap() {
+        return mWidgetsList.clone();
     }
 
     /**
      * @param packageUser If null, all widgets and shortcuts are updated and returned, otherwise
      *                    only widgets and shortcuts associated with the package/user are.
      */
-    public ArrayList<WidgetItem> update(Context context, @Nullable PackageUserKey packageUser) {
+    public void update(LauncherAppState app, @Nullable PackageUserKey packageUser) {
         Preconditions.assertWorkerThread();
 
+        Context context = app.getContext();
         final ArrayList<WidgetItem> widgetsAndShortcuts = new ArrayList<>();
         try {
             PackageManager pm = context.getPackageManager();
-            InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
+            InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
 
             // Widgets
             AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(context);
@@ -81,9 +71,9 @@
                     .getCustomShortcutActivityList(packageUser)) {
                 widgetsAndShortcuts.add(new WidgetItem(info));
             }
-            setWidgetsAndShortcuts(widgetsAndShortcuts, context, packageUser);
+            setWidgetsAndShortcuts(widgetsAndShortcuts, app, packageUser);
         } catch (Exception e) {
-            if (!ProviderConfig.IS_DOGFOOD_BUILD && Utilities.isBinderSizeError(e)) {
+            if (!FeatureFlags.IS_DOGFOOD_BUILD && Utilities.isBinderSizeError(e)) {
                 // the returned value may be incomplete and will not be refreshed until the next
                 // time Launcher starts.
                 // TODO: after figuring out a repro step, introduce a dirty bit to check when
@@ -92,11 +82,12 @@
                 throw e;
             }
         }
-        return widgetsAndShortcuts;
+
+        app.getWidgetCache().removeObsoletePreviews(widgetsAndShortcuts, packageUser);
     }
 
-    private void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts,
-            Context context, @Nullable PackageUserKey packageUser) {
+    private synchronized void setWidgetsAndShortcuts(ArrayList<WidgetItem> rawWidgetsShortcuts,
+            LauncherAppState app, @Nullable PackageUserKey packageUser) {
         if (DEBUG) {
             Log.d(TAG, "addWidgetsAndShortcuts, widgetsShortcuts#=" + rawWidgetsShortcuts.size());
         }
@@ -133,7 +124,7 @@
             }
         }
 
-        InvariantDeviceProfile idp = LauncherAppState.getIDP(context);
+        InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
         UserHandle myUser = Process.myUserHandle();
 
         // add and update.
@@ -152,6 +143,9 @@
                 }
             }
 
+            if (mAppFilter == null) {
+                mAppFilter = AppFilter.newInstance(app.getContext());
+            }
             if (!mAppFilter.shouldShowApp(item.componentName)) {
                 if (DEBUG) {
                     Log.d(TAG, String.format("%s is filtered and not added to the widget tray.",
@@ -174,8 +168,9 @@
         }
 
         // Update each package entry
+        IconCache iconCache = app.getIconCache();
         for (PackageItemInfo p : tmpPackageItemInfos.values()) {
-            mIconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
+            iconCache.getTitleAndIconForApp(p, true /* userLowResIcon */);
         }
     }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/notification/NotificationFooterLayout.java b/src/com/android/launcher3/notification/NotificationFooterLayout.java
index 051c033..b83c9b9 100644
--- a/src/com/android/launcher3/notification/NotificationFooterLayout.java
+++ b/src/com/android/launcher3/notification/NotificationFooterLayout.java
@@ -205,6 +205,7 @@
                 collapseFooter.addListener(new AnimatorListenerAdapter() {
                     @Override
                     public void onAnimationEnd(Animator animation) {
+                        ((ViewGroup) getParent()).findViewById(R.id.divider).setVisibility(GONE);
                         ((ViewGroup) getParent()).removeView(NotificationFooterLayout.this);
                     }
                 });
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
index 997def2..cc81b11 100644
--- a/src/com/android/launcher3/notification/NotificationItemView.java
+++ b/src/com/android/launcher3/notification/NotificationItemView.java
@@ -21,7 +21,6 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.support.annotation.Nullable;
-import android.support.v4.content.ContextCompat;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
@@ -30,11 +29,12 @@
 
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.R;
-import com.android.launcher3.anim.PillHeightRevealOutlineProvider;
+import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
 import com.android.launcher3.graphics.IconPalette;
 import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
 import com.android.launcher3.popup.PopupItemView;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
+import com.android.launcher3.util.Themes;
 
 import java.util.List;
 
@@ -87,9 +87,10 @@
     }
 
     public Animator animateHeightRemoval(int heightToRemove) {
-        final int newHeight = getHeight() - heightToRemove;
-        return new PillHeightRevealOutlineProvider(mPillRect,
-                getBackgroundRadius(), newHeight).createRevealAnimator(this, true /* isReversed */);
+        Rect endRect = new Rect(mPillRect);
+        endRect.bottom -= heightToRemove;
+        return new RoundedRectRevealOutlineProvider(getBackgroundRadius(), getBackgroundRadius(),
+                mPillRect, endRect, mRoundedCorners).createRevealAnimator(this, false);
     }
 
     public void updateHeader(int notificationCount, @Nullable IconPalette palette) {
@@ -98,7 +99,7 @@
             if (mNotificationHeaderTextColor == Notification.COLOR_DEFAULT) {
                 mNotificationHeaderTextColor =
                         IconPalette.resolveContrastColor(getContext(), palette.dominantColor,
-                            getResources().getColor(R.color.popup_header_background_color));
+                                Themes.getAttrColor(getContext(), R.attr.popupColorPrimary));
             }
             mHeaderCount.setTextColor(mNotificationHeaderTextColor);
         }
@@ -163,13 +164,6 @@
     }
 
     @Override
-    public int getArrowColor(boolean isArrowAttachedToBottom) {
-        return ContextCompat.getColor(getContext(), isArrowAttachedToBottom
-                ? R.color.popup_background_color
-                : R.color.popup_header_background_color);
-    }
-
-    @Override
     public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
             LauncherLogProto.Target targetParent) {
         target.itemType = LauncherLogProto.ItemType.NOTIFICATION;
diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java
index 0d6da77..9b8dd64 100644
--- a/src/com/android/launcher3/notification/NotificationMainView.java
+++ b/src/com/android/launcher3/notification/NotificationMainView.java
@@ -87,11 +87,11 @@
         CharSequence title = mNotificationInfo.title;
         CharSequence text = mNotificationInfo.text;
         if (!TextUtils.isEmpty(title) && !TextUtils.isEmpty(text)) {
-            mTitleView.setText(title);
-            mTextView.setText(text);
+            mTitleView.setText(title.toString());
+            mTextView.setText(text.toString());
         } else {
             mTitleView.setMaxLines(2);
-            mTitleView.setText(TextUtils.isEmpty(title) ? text : title);
+            mTitleView.setText(TextUtils.isEmpty(title) ? text.toString() : title.toString());
             mTextView.setVisibility(GONE);
         }
         iconView.setBackground(mNotificationInfo.getIconForBackground(getContext(),
diff --git a/src/com/android/launcher3/pageindicators/CaretDrawable.java b/src/com/android/launcher3/pageindicators/CaretDrawable.java
index 0a00e24..5ade497 100644
--- a/src/com/android/launcher3/pageindicators/CaretDrawable.java
+++ b/src/com/android/launcher3/pageindicators/CaretDrawable.java
@@ -22,12 +22,11 @@
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
 
 import com.android.launcher3.R;
 import com.android.launcher3.util.Themes;
 
-import android.graphics.drawable.Drawable;
-
 public class CaretDrawable extends Drawable {
     public static final float PROGRESS_CARET_POINTING_UP = -1f;
     public static final float PROGRESS_CARET_POINTING_DOWN = 1f;
@@ -39,6 +38,7 @@
     private Paint mCaretPaint = new Paint();
     private Path mPath = new Path();
     private final int mCaretSizePx;
+    private final boolean mUseShadow;
 
     public CaretDrawable(Context context) {
         final Resources res = context.getResources();
@@ -46,12 +46,12 @@
         final int strokeWidth = res.getDimensionPixelSize(R.dimen.all_apps_caret_stroke_width);
         final int shadowSpread = res.getDimensionPixelSize(R.dimen.all_apps_caret_shadow_spread);
 
-        mCaretPaint.setColor(res.getColor(R.color.workspace_icon_text_color));
+        mCaretPaint.setColor(Themes.getAttrColor(context, R.attr.workspaceTextColor));
         mCaretPaint.setAntiAlias(true);
         mCaretPaint.setStrokeWidth(strokeWidth);
         mCaretPaint.setStyle(Paint.Style.STROKE);
-        mCaretPaint.setStrokeCap(Paint.Cap.SQUARE);
-        mCaretPaint.setStrokeJoin(Paint.Join.MITER);
+        mCaretPaint.setStrokeCap(Paint.Cap.ROUND);
+        mCaretPaint.setStrokeJoin(Paint.Join.ROUND);
 
         mShadowPaint.setColor(res.getColor(R.color.default_shadow_color_no_alpha));
         mShadowPaint.setAlpha(Themes.getAlpha(context, android.R.attr.spotShadowAlpha));
@@ -61,6 +61,7 @@
         mShadowPaint.setStrokeCap(Paint.Cap.ROUND);
         mShadowPaint.setStrokeJoin(Paint.Join.ROUND);
 
+        mUseShadow = !Themes.getAttrBoolean(context, R.attr.isWorkspaceDarkText);
         mCaretSizePx = res.getDimensionPixelSize(R.dimen.all_apps_caret_size);
     }
 
@@ -95,8 +96,9 @@
         mPath.moveTo(left, top + caretHeight * (1 - getNormalizedCaretProgress()));
         mPath.lineTo(left + (width / 2), top + caretHeight * getNormalizedCaretProgress());
         mPath.lineTo(left + width, top + caretHeight * (1 - getNormalizedCaretProgress()));
-
-        canvas.drawPath(mPath, mShadowPaint);
+        if (mUseShadow) {
+            canvas.drawPath(mPath, mShadowPaint);
+        }
         canvas.drawPath(mPath, mCaretPaint);
     }
 
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
index aedf283..ae10aed 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorCaretLandscape.java
@@ -16,9 +16,7 @@
 package com.android.launcher3.pageindicators;
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.graphics.Canvas;
-import android.graphics.Paint;
 import android.graphics.Rect;
 import android.util.AttributeSet;
 
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
index 3ceba84..91fc1f0 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorLineCaret.java
@@ -221,7 +221,7 @@
      */
     public void updateColor(ExtractedColors extractedColors) {
         int originalLineAlpha = mLinePaint.getAlpha();
-        int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX, Color.TRANSPARENT);
+        int color = extractedColors.getColor(ExtractedColors.HOTSEAT_INDEX);
         if (color != Color.TRANSPARENT) {
             color = ColorUtils.setAlphaComponent(color, 255);
             if (color == Color.BLACK) {
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 4488f66..5463ef7 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -20,19 +20,21 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
-import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.CornerPathEffect;
+import android.graphics.Outline;
 import android.graphics.Paint;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.drawable.ShapeDrawable;
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
+import android.support.annotation.IntDef;
 import android.util.AttributeSet;
 import android.view.Gravity;
 import android.view.LayoutInflater;
@@ -40,7 +42,7 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.DecelerateInterpolator;
+import android.view.animation.AccelerateDecelerateInterpolator;
 import android.widget.FrameLayout;
 
 import com.android.launcher3.AbstractFloatingView;
@@ -52,13 +54,13 @@
 import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.LogAccelerateInterpolator;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.accessibility.LauncherAccessibilityDelegate;
 import com.android.launcher3.accessibility.ShortcutMenuAccessibilityDelegate;
 import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.anim.PropertyResetListener;
+import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
 import com.android.launcher3.badge.BadgeInfo;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragLayer;
@@ -71,7 +73,10 @@
 import com.android.launcher3.shortcuts.DeepShortcutView;
 import com.android.launcher3.shortcuts.ShortcutsItemView;
 import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.Themes;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -88,6 +93,16 @@
 public class PopupContainerWithArrow extends AbstractFloatingView implements DragSource,
         DragController.DragListener {
 
+    public static final int ROUNDED_TOP_CORNERS = 1 << 0;
+    public static final int ROUNDED_BOTTOM_CORNERS = 1 << 1;
+
+    @IntDef(flag = true, value = {
+            ROUNDED_TOP_CORNERS,
+            ROUNDED_BOTTOM_CORNERS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public  @interface RoundedCornerFlags {}
+
     protected final Launcher mLauncher;
     private final int mStartDragThreshold;
     private LauncherAccessibilityDelegate mAccessibilityDelegate;
@@ -106,6 +121,8 @@
     protected Animator mOpenCloseAnimator;
     private boolean mDeferContainerRemoval;
     private AnimatorSet mReduceHeightAnimatorSet;
+    private final Rect mStartRect = new Rect();
+    private final Rect mEndRect = new Rect();
 
     public PopupContainerWithArrow(Context context, AttributeSet attrs, int defStyleAttr) {
         super(context, attrs, defStyleAttr);
@@ -221,6 +238,7 @@
         mArrow.setPivotX(arrowWidth / 2);
         mArrow.setPivotY(mIsAboveIcon ? 0 : arrowHeight);
 
+        measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
         animateOpen();
 
         mLauncher.getDragController().addDragListener(this);
@@ -237,46 +255,67 @@
     private void addDummyViews(PopupPopulator.Item[] itemTypesToPopulate,
             boolean notificationFooterHasIcons) {
         final Resources res = getResources();
-        final int spacing = res.getDimensionPixelSize(R.dimen.popup_items_spacing);
         final LayoutInflater inflater = mLauncher.getLayoutInflater();
 
+        int shortcutsItemRoundedCorners = ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS;
         int numItems = itemTypesToPopulate.length;
         for (int i = 0; i < numItems; i++) {
             PopupPopulator.Item itemTypeToPopulate = itemTypesToPopulate[i];
+            PopupPopulator.Item prevItemTypeToPopulate =
+                    i > 0 ? itemTypesToPopulate[i - 1] : null;
             PopupPopulator.Item nextItemTypeToPopulate =
                     i < numItems - 1 ? itemTypesToPopulate[i + 1] : null;
             final View item = inflater.inflate(itemTypeToPopulate.layoutId, this, false);
 
+            boolean shouldUnroundTopCorners = prevItemTypeToPopulate != null
+                    && itemTypeToPopulate.isShortcut ^ prevItemTypeToPopulate.isShortcut;
+            boolean shouldUnroundBottomCorners = nextItemTypeToPopulate != null
+                    && itemTypeToPopulate.isShortcut ^ nextItemTypeToPopulate.isShortcut;
+
             if (itemTypeToPopulate == PopupPopulator.Item.NOTIFICATION) {
                 mNotificationItemView = (NotificationItemView) item;
                 int footerHeight = notificationFooterHasIcons ?
                         res.getDimensionPixelSize(R.dimen.notification_footer_height) : 0;
                 item.findViewById(R.id.footer).getLayoutParams().height = footerHeight;
+                if (notificationFooterHasIcons) {
+                    mNotificationItemView.findViewById(R.id.divider).setVisibility(VISIBLE);
+                }
+
+                int roundedCorners = ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS;
+                if (shouldUnroundTopCorners) {
+                    roundedCorners &= ~ROUNDED_TOP_CORNERS;
+                }
+                if (shouldUnroundBottomCorners) {
+                    roundedCorners &= ~ROUNDED_BOTTOM_CORNERS;
+                }
+                int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorTertiary);
+                mNotificationItemView.setBackgroundWithCorners(backgroundColor, roundedCorners);
+
                 mNotificationItemView.getMainView().setAccessibilityDelegate(mAccessibilityDelegate);
             } else if (itemTypeToPopulate == PopupPopulator.Item.SHORTCUT) {
                 item.setAccessibilityDelegate(mAccessibilityDelegate);
             }
 
-            boolean shouldAddBottomMargin = nextItemTypeToPopulate != null
-                    && itemTypeToPopulate.isShortcut ^ nextItemTypeToPopulate.isShortcut;
-
             if (itemTypeToPopulate.isShortcut) {
                 if (mShortcutsItemView == null) {
                     mShortcutsItemView = (ShortcutsItemView) inflater.inflate(
                             R.layout.shortcuts_item, this, false);
                     addView(mShortcutsItemView);
+                    if (shouldUnroundTopCorners) {
+                        shortcutsItemRoundedCorners &= ~ROUNDED_TOP_CORNERS;
+                    }
                 }
                 mShortcutsItemView.addShortcutView(item, itemTypeToPopulate);
-                if (shouldAddBottomMargin) {
-                    ((LayoutParams) mShortcutsItemView.getLayoutParams()).bottomMargin = spacing;
+                if (shouldUnroundBottomCorners) {
+                    shortcutsItemRoundedCorners &= ~ROUNDED_BOTTOM_CORNERS;
                 }
             } else {
                 addView(item);
-                if (shouldAddBottomMargin) {
-                    ((LayoutParams) item.getLayoutParams()).bottomMargin = spacing;
-                }
             }
         }
+        int backgroundColor = Themes.getAttrColor(mLauncher, mNotificationItemView == null
+                ? R.attr.popupColorPrimary : R.attr.popupColorSecondary);
+        mShortcutsItemView.setBackgroundWithCorners(backgroundColor, shortcutsItemRoundedCorners);
     }
 
     protected PopupItemView getItemViewAt(int index) {
@@ -296,45 +335,31 @@
         setVisibility(View.VISIBLE);
         mIsOpen = true;
 
-        final AnimatorSet shortcutAnims = LauncherAnimUtils.createAnimatorSet();
-        final int itemCount = getItemCount();
+        final AnimatorSet openAnim = LauncherAnimUtils.createAnimatorSet();
+        final Resources res = getResources();
 
-        final long duration = getResources().getInteger(
-                R.integer.config_deepShortcutOpenDuration);
-        final long arrowScaleDuration = getResources().getInteger(
-                R.integer.config_deepShortcutArrowOpenDuration);
-        final long arrowScaleDelay = duration - arrowScaleDuration;
-        final long stagger = getResources().getInteger(
-                R.integer.config_deepShortcutOpenStagger);
-        final TimeInterpolator fadeInterpolator = new LogAccelerateInterpolator(100, 0);
-
-        // Animate shortcuts
-        DecelerateInterpolator interpolator = new DecelerateInterpolator();
-        for (int i = 0; i < itemCount; i++) {
-            final PopupItemView popupItemView = getItemViewAt(i);
-            popupItemView.setVisibility(INVISIBLE);
-            popupItemView.setAlpha(0);
-
-            Animator anim = popupItemView.createOpenAnimation(mIsAboveIcon, mIsLeftAligned);
-            anim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationStart(Animator animation) {
-                    popupItemView.setVisibility(VISIBLE);
-                }
-            });
-            anim.setDuration(duration);
-            int animationIndex = mIsAboveIcon ? itemCount - i - 1 : i;
-            anim.setStartDelay(stagger * animationIndex);
-            anim.setInterpolator(interpolator);
-            shortcutAnims.play(anim);
-
-            Animator fadeAnim = ObjectAnimator.ofFloat(popupItemView, View.ALPHA, 1);
-            fadeAnim.setInterpolator(fadeInterpolator);
-            // We want the shortcut to be fully opaque before the arrow starts animating.
-            fadeAnim.setDuration(arrowScaleDelay);
-            shortcutAnims.play(fadeAnim);
+        // Rectangular reveal.
+        int itemsTotalHeight = 0;
+        for (int i = 0; i < getItemCount(); i++) {
+            itemsTotalHeight += getItemViewAt(i).getMeasuredHeight();
         }
-        shortcutAnims.addListener(new AnimatorListenerAdapter() {
+        Point startPoint = computeAnimStartPoint(itemsTotalHeight);
+        int top = mIsAboveIcon ? getPaddingTop() : startPoint.y;
+        float radius = getItemViewAt(0).getBackgroundRadius();
+        mStartRect.set(startPoint.x, startPoint.y, startPoint.x, startPoint.y);
+        mEndRect.set(0, top, getMeasuredWidth(), top + itemsTotalHeight);
+        final ValueAnimator revealAnim = new RoundedRectRevealOutlineProvider
+                (radius, radius, mStartRect, mEndRect).createRevealAnimator(this, false);
+        revealAnim.setDuration((long) res.getInteger(R.integer.config_popupOpenCloseDuration));
+        revealAnim.setInterpolator(new AccelerateDecelerateInterpolator());
+
+        // Animate the arrow.
+        mArrow.setScaleX(0);
+        mArrow.setScaleY(0);
+        Animator arrowScale = createArrowScaleAnim(1).setDuration(res.getInteger(
+                R.integer.config_popupArrowOpenDuration));
+
+        openAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
                 mOpenCloseAnimator = null;
@@ -345,15 +370,26 @@
             }
         });
 
-        // Animate the arrow
-        mArrow.setScaleX(0);
-        mArrow.setScaleY(0);
-        Animator arrowScale = createArrowScaleAnim(1).setDuration(arrowScaleDuration);
-        arrowScale.setStartDelay(arrowScaleDelay);
-        shortcutAnims.play(arrowScale);
+        mOpenCloseAnimator = openAnim;
+        openAnim.playSequentially(revealAnim, arrowScale);
+        openAnim.start();
+    }
 
-        mOpenCloseAnimator = shortcutAnims;
-        shortcutAnims.start();
+    /**
+     * Returns the point at which the center of the arrow merges with the first popup item.
+     */
+    private Point computeAnimStartPoint(int itemsTotalHeight) {
+        int arrowCenterX = getResources().getDimensionPixelSize(mIsLeftAligned ^ mIsRtl ?
+                R.dimen.popup_arrow_horizontal_center_start:
+                R.dimen.popup_arrow_horizontal_center_end);
+        if (!mIsLeftAligned) {
+            arrowCenterX = getMeasuredWidth() - arrowCenterX;
+        }
+        int arrowHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom()
+                - itemsTotalHeight;
+        // The y-coordinate of edge between the arrow and the first popup item.
+        int arrowEdge = getPaddingTop() + (mIsAboveIcon ? itemsTotalHeight : arrowHeight);
+        return new Point(arrowCenterX, arrowEdge);
     }
 
     /**
@@ -505,7 +541,7 @@
             // since the latter expects the arrow which hasn't been added yet.
             PopupItemView itemAttachedToArrow = (PopupItemView)
                     (getChildAt(mIsAboveIcon ? getChildCount() - 1 : 0));
-            arrowPaint.setColor(itemAttachedToArrow.getArrowColor(mIsAboveIcon));
+            arrowPaint.setColor(Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary));
             // The corner path effect won't be reflected in the shadow, but shouldn't be noticeable.
             int radius = getResources().getDimensionPixelSize(R.dimen.popup_arrow_corner_radius);
             arrowPaint.setPathEffect(new CornerPathEffect(radius));
@@ -529,6 +565,7 @@
      */
     public DragOptions.PreDragCondition createPreDragCondition() {
         return new DragOptions.PreDragCondition() {
+
             @Override
             public boolean shouldStartDrag(double distanceDragged) {
                 return distanceDragged > mStartDragThreshold;
@@ -536,15 +573,27 @@
 
             @Override
             public void onPreDragStart(DropTarget.DragObject dragObject) {
-                mOriginalIcon.setVisibility(INVISIBLE);
+                if (mIsAboveIcon) {
+                    // Hide only the icon, keep the text visible.
+                    mOriginalIcon.setIconVisible(false);
+                    mOriginalIcon.setVisibility(VISIBLE);
+                } else {
+                    // Hide both the icon and text.
+                    mOriginalIcon.setVisibility(INVISIBLE);
+                }
             }
 
             @Override
             public void onPreDragEnd(DropTarget.DragObject dragObject, boolean dragStarted) {
-                if (!dragStarted) {
-                    mOriginalIcon.setVisibility(VISIBLE);
+                mOriginalIcon.setIconVisible(true);
+                if (dragStarted) {
+                    // Make sure we keep the original icon hidden while it is being dragged.
+                    mOriginalIcon.setVisibility(INVISIBLE);
+                } else {
                     mLauncher.getUserEventDispatcher().logDeepShortcutsOpen(mOriginalIcon);
                     if (!mIsAboveIcon) {
+                        // Show the icon but keep the text hidden.
+                        mOriginalIcon.setVisibility(VISIBLE);
                         mOriginalIcon.setTextVisibility(false);
                     }
                 }
@@ -593,22 +642,8 @@
             AnimatorSet removeNotification = LauncherAnimUtils.createAnimatorSet();
             final int duration = getResources().getInteger(
                     R.integer.config_removeNotificationViewDuration);
-            final int spacing = getResources().getDimensionPixelSize(R.dimen.popup_items_spacing);
             removeNotification.play(reduceNotificationViewHeight(
-                    mNotificationItemView.getHeightMinusFooter() + spacing, duration));
-            final View removeMarginView = mIsAboveIcon ? getItemViewAt(getItemCount() - 2)
-                    : mNotificationItemView;
-            if (removeMarginView != null) {
-                ValueAnimator removeMargin = ValueAnimator.ofFloat(1, 0).setDuration(duration);
-                removeMargin.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-                    @Override
-                    public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                        ((MarginLayoutParams) removeMarginView.getLayoutParams()).bottomMargin
-                                = (int) (spacing * (float) valueAnimator.getAnimatedValue());
-                    }
-                });
-                removeNotification.play(removeMargin);
-            }
+                    mNotificationItemView.getHeightMinusFooter(), duration));
             Animator fade = ObjectAnimator.ofFloat(mNotificationItemView, ALPHA, 0)
                     .setDuration(duration);
             fade.addListener(new AnimatorListenerAdapter() {
@@ -618,19 +653,24 @@
                     mNotificationItemView = null;
                     if (getItemCount() == 0) {
                         close(false);
-                        return;
                     }
                 }
             });
             removeNotification.play(fade);
             final long arrowScaleDuration = getResources().getInteger(
-                    R.integer.config_deepShortcutArrowOpenDuration);
+                    R.integer.config_popupArrowOpenDuration);
             Animator hideArrow = createArrowScaleAnim(0).setDuration(arrowScaleDuration);
             hideArrow.setStartDelay(0);
             Animator showArrow = createArrowScaleAnim(1).setDuration(arrowScaleDuration);
             showArrow.setStartDelay((long) (duration - arrowScaleDuration * 1.5));
             removeNotification.playSequentially(hideArrow, showArrow);
             removeNotification.start();
+            if (mShortcutsItemView != null) {
+                int backgroundColor = Themes.getAttrColor(mLauncher, R.attr.popupColorPrimary);
+                // With notifications gone, all corners of shortcuts item should be rounded.
+                mShortcutsItemView.setBackgroundWithCorners(backgroundColor,
+                        ROUNDED_TOP_CORNERS | ROUNDED_BOTTOM_CORNERS);
+            }
             return;
         }
         mNotificationItemView.trimNotifications(NotificationKeyData.extractKeysOnly(
@@ -754,55 +794,40 @@
         if (!mIsOpen) {
             return;
         }
+        mEndRect.setEmpty();
         if (mOpenCloseAnimator != null) {
+            Outline outline = new Outline();
+            getOutlineProvider().getOutline(this, outline);
+            outline.getRect(mEndRect);
             mOpenCloseAnimator.cancel();
         }
         mIsOpen = false;
 
-        final AnimatorSet shortcutAnims = LauncherAnimUtils.createAnimatorSet();
-        final int itemCount = getItemCount();
-        int numOpenShortcuts = 0;
-        for (int i = 0; i < itemCount; i++) {
-            if (getItemViewAt(i).isOpenOrOpening()) {
-                numOpenShortcuts++;
-            }
+        final AnimatorSet closeAnim = LauncherAnimUtils.createAnimatorSet();
+        final Resources res = getResources();
+
+        // Animate the arrow.
+        Animator arrowScale = createArrowScaleAnim(0).setDuration(res.getInteger(
+                R.integer.config_popupArrowOpenDuration));
+
+        // Rectangular reveal (reversed).
+        int itemsTotalHeight = 0;
+        for (int i = 0; i < getItemCount(); i++) {
+            itemsTotalHeight += getItemViewAt(i).getMeasuredHeight();
         }
-        final long duration = getResources().getInteger(
-                R.integer.config_deepShortcutCloseDuration);
-        final long arrowScaleDuration = getResources().getInteger(
-                R.integer.config_deepShortcutArrowOpenDuration);
-        final long stagger = getResources().getInteger(
-                R.integer.config_deepShortcutCloseStagger);
-        final TimeInterpolator fadeInterpolator = new LogAccelerateInterpolator(100, 0);
-
-        int firstOpenItemIndex = mIsAboveIcon ? itemCount - numOpenShortcuts : 0;
-        for (int i = firstOpenItemIndex; i < firstOpenItemIndex + numOpenShortcuts; i++) {
-            final PopupItemView view = getItemViewAt(i);
-            Animator anim;
-            anim = view.createCloseAnimation(mIsAboveIcon, mIsLeftAligned, duration);
-            int animationIndex = mIsAboveIcon ? i - firstOpenItemIndex
-                    : numOpenShortcuts - i - 1;
-            anim.setStartDelay(stagger * animationIndex);
-
-            Animator fadeAnim = ObjectAnimator.ofFloat(view, View.ALPHA, 0);
-            // Don't start fading until the arrow is gone.
-            fadeAnim.setStartDelay(stagger * animationIndex + arrowScaleDuration);
-            fadeAnim.setDuration(duration - arrowScaleDuration);
-            fadeAnim.setInterpolator(fadeInterpolator);
-            shortcutAnims.play(fadeAnim);
-            anim.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation) {
-                    view.setVisibility(INVISIBLE);
-                }
-            });
-            shortcutAnims.play(anim);
+        Point startPoint = computeAnimStartPoint(itemsTotalHeight);
+        int top = mIsAboveIcon ? getPaddingTop() : startPoint.y;
+        float radius = getItemViewAt(0).getBackgroundRadius();
+        mStartRect.set(startPoint.x, startPoint.y, startPoint.x, startPoint.y);
+        if (mEndRect.isEmpty()) {
+            mEndRect.set(0, top, getMeasuredWidth(), top + itemsTotalHeight);
         }
-        Animator arrowAnim = createArrowScaleAnim(0).setDuration(arrowScaleDuration);
-        arrowAnim.setStartDelay(0);
-        shortcutAnims.play(arrowAnim);
+        final ValueAnimator revealAnim = new RoundedRectRevealOutlineProvider(
+                radius, radius, mStartRect, mEndRect).createRevealAnimator(this, true);
+        revealAnim.setDuration((long) res.getInteger(R.integer.config_popupOpenCloseDuration));
+        revealAnim.setInterpolator(new AccelerateDecelerateInterpolator());
 
-        shortcutAnims.addListener(new AnimatorListenerAdapter() {
+        closeAnim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
                 mOpenCloseAnimator = null;
@@ -813,8 +838,9 @@
                 }
             }
         });
-        mOpenCloseAnimator = shortcutAnims;
-        shortcutAnims.start();
+        mOpenCloseAnimator = closeAnim;
+        closeAnim.playSequentially(arrowScale, revealAnim);
+        closeAnim.start();
         mOriginalIcon.forceHideBadge(false);
     }
 
diff --git a/src/com/android/launcher3/popup/PopupItemView.java b/src/com/android/launcher3/popup/PopupItemView.java
index 384f554..05cadb6 100644
--- a/src/com/android/launcher3/popup/PopupItemView.java
+++ b/src/com/android/launcher3/popup/PopupItemView.java
@@ -16,38 +16,34 @@
 
 package com.android.launcher3.popup;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Paint;
-import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
 import android.graphics.Rect;
+import android.graphics.drawable.ShapeDrawable;
+import android.graphics.drawable.shapes.RoundRectShape;
 import android.util.AttributeSet;
 import android.view.View;
 import android.widget.FrameLayout;
 
-import com.android.launcher3.LogAccelerateInterpolator;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.util.PillRevealOutlineProvider;
+import com.android.launcher3.popup.PopupContainerWithArrow.RoundedCornerFlags;
+
+import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_BOTTOM_CORNERS;
+import static com.android.launcher3.popup.PopupContainerWithArrow.ROUNDED_TOP_CORNERS;
 
 /**
- * An abstract {@link FrameLayout} that supports animating an item's content
- * (e.g. icon and text) separate from the item's background.
+ * An abstract {@link FrameLayout} that contains content for {@link PopupContainerWithArrow}.
  */
-public abstract class PopupItemView extends FrameLayout
-        implements ValueAnimator.AnimatorUpdateListener {
-
-    protected static final Point sTempPoint = new Point();
+public abstract class PopupItemView extends FrameLayout {
 
     protected final Rect mPillRect;
-    private float mOpenAnimationProgress;
+    protected  @RoundedCornerFlags int mRoundedCorners;
     protected final boolean mIsRtl;
     protected View mIconView;
 
@@ -93,164 +89,55 @@
 
     @Override
     protected void dispatchDraw(Canvas canvas) {
+        if (mRoundedCorners == 0) {
+            super.dispatchDraw(canvas);
+            return;
+        }
+
         int saveCount = canvas.saveLayer(0, 0, getWidth(), getHeight(), null);
         super.dispatchDraw(canvas);
 
+        // Clip children to this item's rounded corners.
         int cornerWidth = mRoundedCornerBitmap.getWidth();
         int cornerHeight = mRoundedCornerBitmap.getHeight();
-        // Clip top left corner.
-        mMatrix.reset();
-        canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
-        // Clip top right corner.
-        mMatrix.setRotate(90, cornerWidth / 2, cornerHeight / 2);
-        mMatrix.postTranslate(canvas.getWidth() - cornerWidth, 0);
-        canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
-        // Clip bottom right corner.
-        mMatrix.setRotate(180, cornerWidth / 2, cornerHeight / 2);
-        mMatrix.postTranslate(canvas.getWidth() - cornerWidth, canvas.getHeight() - cornerHeight);
-        canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
-        // Clip bottom left corner.
-        mMatrix.setRotate(270, cornerWidth / 2, cornerHeight / 2);
-        mMatrix.postTranslate(0, canvas.getHeight() - cornerHeight);
-        canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
+        if ((mRoundedCorners & ROUNDED_TOP_CORNERS) != 0) {
+            // Clip top left corner.
+            mMatrix.reset();
+            canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
+            // Clip top right corner.
+            mMatrix.setRotate(90, cornerWidth / 2, cornerHeight / 2);
+            mMatrix.postTranslate(canvas.getWidth() - cornerWidth, 0);
+            canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
+        }
+        if ((mRoundedCorners & ROUNDED_BOTTOM_CORNERS) != 0) {
+            // Clip bottom right corner.
+            mMatrix.setRotate(180, cornerWidth / 2, cornerHeight / 2);
+            mMatrix.postTranslate(canvas.getWidth() - cornerWidth, canvas.getHeight() - cornerHeight);
+            canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
+            // Clip bottom left corner.
+            mMatrix.setRotate(270, cornerWidth / 2, cornerHeight / 2);
+            mMatrix.postTranslate(0, canvas.getHeight() - cornerHeight);
+            canvas.drawBitmap(mRoundedCornerBitmap, mMatrix, mBackgroundClipPaint);
+        }
 
         canvas.restoreToCount(saveCount);
     }
 
     /**
-     * Creates an animator to play when the shortcut container is being opened.
+     * Creates a round rect drawable (with the specified corners unrounded)
+     * and sets it as this View's background.
      */
-    public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) {
-        Point center = getIconCenter();
-        int arrowCenter = getResources().getDimensionPixelSize(pivotLeft ^ mIsRtl ?
-                R.dimen.popup_arrow_horizontal_center_start:
-                R.dimen.popup_arrow_horizontal_center_end);
-        ValueAnimator openAnimator =  new ZoomRevealOutlineProvider(center.x, center.y,
-                mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft, arrowCenter)
-                        .createRevealAnimator(this, false);
-        mOpenAnimationProgress = 0f;
-        openAnimator.addUpdateListener(this);
-        return openAnimator;
-    }
-
-    @Override
-    public void onAnimationUpdate(ValueAnimator valueAnimator) {
-        mOpenAnimationProgress = valueAnimator.getAnimatedFraction();
-    }
-
-    public boolean isOpenOrOpening() {
-        return mOpenAnimationProgress > 0;
-    }
-
-    /**
-     * Creates an animator to play when the shortcut container is being closed.
-     */
-    public Animator createCloseAnimation(boolean isContainerAboveIcon, boolean pivotLeft,
-            long duration) {
-        Point center = getIconCenter();
-        int arrowCenter = getResources().getDimensionPixelSize(pivotLeft ^ mIsRtl ?
-                R.dimen.popup_arrow_horizontal_center_start :
-                R.dimen.popup_arrow_horizontal_center_end);
-        ValueAnimator closeAnimator = new ZoomRevealOutlineProvider(center.x, center.y,
-                mPillRect, this, mIconView, isContainerAboveIcon, pivotLeft, arrowCenter)
-                        .createRevealAnimator(this, true);
-        // Scale down the duration and interpolator according to the progress
-        // that the open animation was at when the close started.
-        closeAnimator.setDuration((long) (duration * mOpenAnimationProgress));
-        closeAnimator.setInterpolator(new CloseInterpolator(mOpenAnimationProgress));
-        closeAnimator.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mOpenAnimationProgress = 0;
-            }
-        });
-        return closeAnimator;
-    }
-
-    /**
-     * Returns the position of the center of the icon relative to the container.
-     */
-    public Point getIconCenter() {
-        sTempPoint.y = getMeasuredHeight() / 2;
-        sTempPoint.x = getResources().getDimensionPixelSize(R.dimen.bg_popup_item_height) / 2;
-        if (Utilities.isRtl(getResources())) {
-            sTempPoint.x = getMeasuredWidth() - sTempPoint.x;
-        }
-        return sTempPoint;
+    public void setBackgroundWithCorners(int color, @RoundedCornerFlags int roundedCorners) {
+        mRoundedCorners = roundedCorners;
+        float rTop = (roundedCorners & ROUNDED_TOP_CORNERS) == 0 ? 0 : getBackgroundRadius();
+        float rBot = (roundedCorners & ROUNDED_BOTTOM_CORNERS) == 0 ? 0 : getBackgroundRadius();
+        float[] radii = new float[] {rTop, rTop, rTop, rTop, rBot, rBot, rBot, rBot};
+        ShapeDrawable roundRectBackground = new ShapeDrawable(new RoundRectShape(radii, null, null));
+        roundRectBackground.getPaint().setColor(color);
+        setBackground(roundRectBackground);
     }
 
     protected float getBackgroundRadius() {
         return getResources().getDimensionPixelSize(R.dimen.bg_round_rect_radius);
     }
-
-    public abstract int getArrowColor(boolean isArrowAttachedToBottom);
-
-    /**
-     * Extension of {@link PillRevealOutlineProvider} which scales the icon based on the height.
-     */
-    private static class ZoomRevealOutlineProvider extends PillRevealOutlineProvider {
-
-        private final View mTranslateView;
-        private final View mZoomView;
-
-        private final float mFullHeight;
-        private final float mTranslateYMultiplier;
-
-        private final boolean mPivotLeft;
-        private final float mTranslateX;
-        private final float mArrowCenter;
-
-        public ZoomRevealOutlineProvider(int x, int y, Rect pillRect, PopupItemView translateView,
-                View zoomView, boolean isContainerAboveIcon, boolean pivotLeft, float arrowCenter) {
-            super(x, y, pillRect, translateView.getBackgroundRadius());
-            mTranslateView = translateView;
-            mZoomView = zoomView;
-            mFullHeight = pillRect.height();
-
-            mTranslateYMultiplier = isContainerAboveIcon ? 0.5f : -0.5f;
-
-            mPivotLeft = pivotLeft;
-            mTranslateX = pivotLeft ? arrowCenter : pillRect.right - arrowCenter;
-            mArrowCenter = arrowCenter;
-        }
-
-        @Override
-        public void setProgress(float progress) {
-            super.setProgress(progress);
-
-            if (mZoomView != null) {
-                mZoomView.setScaleX(progress);
-                mZoomView.setScaleY(progress);
-            }
-
-            float height = mOutline.height();
-            mTranslateView.setTranslationY(mTranslateYMultiplier * (mFullHeight - height));
-
-            float offsetX = Math.min(mOutline.width(), mArrowCenter);
-            float pivotX = mPivotLeft ? (mOutline.left + offsetX) : (mOutline.right - offsetX);
-            mTranslateView.setTranslationX(mTranslateX - pivotX);
-        }
-    }
-
-    /**
-     * An interpolator that reverses the current open animation progress.
-     */
-    private static class CloseInterpolator extends LogAccelerateInterpolator {
-        private float mStartProgress;
-        private float mRemainingProgress;
-
-        /**
-         * @param openAnimationProgress The progress that the open interpolator ended at.
-         */
-        public CloseInterpolator(float openAnimationProgress) {
-            super(100, 0);
-            mStartProgress = 1f - openAnimationProgress;
-            mRemainingProgress = openAnimationProgress;
-        }
-
-        @Override
-        public float getInterpolation(float v) {
-            return mStartProgress + super.getInterpolation(v) * mRemainingProgress;
-        }
-    }
 }
diff --git a/src/com/android/launcher3/popup/PopupPopulator.java b/src/com/android/launcher3/popup/PopupPopulator.java
index c62d877..fd00105 100644
--- a/src/com/android/launcher3/popup/PopupPopulator.java
+++ b/src/com/android/launcher3/popup/PopupPopulator.java
@@ -305,14 +305,12 @@
         if (view instanceof DeepShortcutView) {
             // Expanded system shortcut, with both icon and text shown on white background.
             final DeepShortcutView shortcutView = (DeepShortcutView) view;
-            shortcutView.getIconView().setBackground(info.getIcon(context,
-                    android.R.attr.textColorTertiary));
+            shortcutView.getIconView().setBackground(info.getIcon(context));
             shortcutView.getBubbleText().setText(info.getLabel(context));
         } else if (view instanceof ImageView) {
             // Only the system shortcut icon shows on a gray background header.
             final ImageView shortcutIcon = (ImageView) view;
-            shortcutIcon.setImageDrawable(info.getIcon(context,
-                    android.R.attr.textColorHint));
+            shortcutIcon.setImageDrawable(info.getIcon(context));
             shortcutIcon.setContentDescription(info.getLabel(context));
         }
         view.setTag(info);
diff --git a/src/com/android/launcher3/popup/SystemShortcut.java b/src/com/android/launcher3/popup/SystemShortcut.java
index f158f71..6254d2d 100644
--- a/src/com/android/launcher3/popup/SystemShortcut.java
+++ b/src/com/android/launcher3/popup/SystemShortcut.java
@@ -13,18 +13,20 @@
 import com.android.launcher3.R;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.util.PackageUserKey;
-import com.android.launcher3.util.Themes;
 import com.android.launcher3.widget.WidgetsBottomSheet;
 
 import java.util.List;
 
+import static com.android.launcher3.userevent.nano.LauncherLogProto.Action;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
+
 /**
  * Represents a system shortcut for a given app. The shortcut should have a static label and
  * icon, and an onClickListener that depends on the item that the shortcut services.
  *
  * Example system shortcuts, defined as inner classes, include Widgets and AppInfo.
  */
-public abstract class SystemShortcut {
+public abstract class SystemShortcut extends ItemInfo {
     private final int mIconResId;
     private final int mLabelResId;
 
@@ -33,10 +35,8 @@
         mLabelResId = labelResId;
     }
 
-    public Drawable getIcon(Context context, int colorAttr) {
-        Drawable icon = context.getResources().getDrawable(mIconResId, context.getTheme()).mutate();
-        icon.setTint(Themes.getAttrColor(context, colorAttr));
-        return icon;
+    public Drawable getIcon(Context context) {
+        return context.getResources().getDrawable(mIconResId, context.getTheme());
     }
 
     public String getLabel(Context context) {
@@ -68,6 +68,8 @@
                             (WidgetsBottomSheet) launcher.getLayoutInflater().inflate(
                                     R.layout.widgets_bottom_sheet, launcher.getDragLayer(), false);
                     widgetsBottomSheet.populateAndShow(itemInfo);
+                    launcher.getUserEventDispatcher().logActionOnControl(Action.Touch.TAP,
+                            ControlType.WIDGETS_BUTTON, view);
                 }
             };
         }
@@ -87,6 +89,8 @@
                     Rect sourceBounds = launcher.getViewBounds(view);
                     Bundle opts = launcher.getActivityLaunchOptions(view);
                     InfoDropTarget.startDetailsActivityForInfo(itemInfo, launcher, null, sourceBounds, opts);
+                    launcher.getUserEventDispatcher().logActionOnControl(Action.Touch.TAP,
+                            ControlType.APPINFO_TARGET, view);
                 }
             };
         }
diff --git a/src/com/android/launcher3/provider/ImportDataTask.java b/src/com/android/launcher3/provider/ImportDataTask.java
index b0482f8..314f244 100644
--- a/src/com/android/launcher3/provider/ImportDataTask.java
+++ b/src/com/android/launcher3/provider/ImportDataTask.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3.provider;
 
+import static com.android.launcher3.Utilities.getDevicePrefs;
+
 import android.content.ContentProviderOperation;
 import android.content.ContentValues;
 import android.content.Context;
@@ -36,7 +38,7 @@
 import com.android.launcher3.DefaultLayoutParser;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetInfo;
-import com.android.launcher3.LauncherFiles;
+import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.LauncherSettings.Settings;
@@ -46,7 +48,6 @@
 import com.android.launcher3.Workspace;
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.model.GridSizeMigrationTask;
 import com.android.launcher3.util.LongArrayMap;
@@ -112,7 +113,7 @@
             screenOps.add(ContentProviderOperation.newInsert(
                     LauncherSettings.WorkspaceScreens.CONTENT_URI).withValues(v).build());
         }
-        mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY, screenOps);
+        mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY, screenOps);
         importWorkspaceItems(allScreens.get(0), screenIdMap);
 
         GridSizeMigrationTask.markForMigration(mContext, mMaxGridSizeX, mMaxGridSizeY, mHotseatSize);
@@ -289,7 +290,7 @@
                 }
 
                 if (insertOperations.size() >= BATCH_INSERT_SIZE) {
-                    mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY,
+                    mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY,
                             insertOperations);
                     insertOperations.clear();
                 }
@@ -300,7 +301,7 @@
             throw new Exception("Insufficient data");
         }
         if (!insertOperations.isEmpty()) {
-            mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY,
+            mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY,
                     insertOperations);
             insertOperations.clear();
         }
@@ -319,7 +320,7 @@
             mHotseatSize = (int) hotseatItems.keyAt(hotseatItems.size() - 1) + 1;
 
             if (!insertOperations.isEmpty()) {
-                mContext.getContentResolver().applyBatch(ProviderConfig.AUTHORITY,
+                mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY,
                         insertOperations);
             }
         }
@@ -377,10 +378,6 @@
         return false;
     }
 
-    private static SharedPreferences getDevicePrefs(Context c) {
-        return c.getSharedPreferences(LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE);
-    }
-
     private static final int getMyHotseatLayoutId(Context context) {
         return LauncherAppState.getIDP(context).numHotseatIcons <= 5
                 ? R.xml.dw_phone_hotseat
diff --git a/src/com/android/launcher3/provider/LauncherDbUtils.java b/src/com/android/launcher3/provider/LauncherDbUtils.java
index 1758350..74373d3 100644
--- a/src/com/android/launcher3/provider/LauncherDbUtils.java
+++ b/src/com/android/launcher3/provider/LauncherDbUtils.java
@@ -19,15 +19,16 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
+import android.database.DatabaseUtils;
 import android.database.sqlite.SQLiteDatabase;
 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.logging.FileLog;
 
 import java.util.ArrayList;
+import java.util.Collection;
 
 /**
  * A set of utility methods for Launcher DB used for DB updates and migration.
@@ -44,14 +45,14 @@
      * items are simply deleted.
      */
     public static boolean prepareScreenZeroToHostQsb(Context context, SQLiteDatabase db) {
-        db.beginTransaction();
-        try {
+        try (SQLiteTransaction t = new SQLiteTransaction(db)) {
             // Get the existing screens
             ArrayList<Long> screenIds = getScreenIdsFromCursor(db.query(WorkspaceScreens.TABLE_NAME,
                     null, null, null, null, null, WorkspaceScreens.SCREEN_RANK));
 
             if (screenIds.isEmpty()) {
                 // No update needed
+                t.commit();
                 return true;
             }
             if (screenIds.get(0) != 0) {
@@ -68,23 +69,20 @@
             }
 
             // Check if the first row is empty
-            try (Cursor c = db.query(Favorites.TABLE_NAME, null,
-                    "container = -100 and screen = 0 and cellY = 0", null, null, null, null)) {
-                if (c.getCount() == 0) {
-                    // First row is empty, no need to migrate.
-                    return true;
-                }
+            if (DatabaseUtils.queryNumEntries(db, Favorites.TABLE_NAME,
+                    "container = -100 and screen = 0 and cellY = 0") == 0) {
+                // First row is empty, no need to migrate.
+                t.commit();
+                return true;
             }
 
             new LossyScreenMigrationTask(context, LauncherAppState.getIDP(context), db)
                     .migrateScreen0();
-            db.setTransactionSuccessful();
+            t.commit();
             return true;
         } catch (Exception e) {
             Log.e(TAG, "Failed to update workspace size", e);
             return false;
-        } finally {
-            db.endTransaction();
         }
     }
 
@@ -104,19 +102,40 @@
      * Parses the cursor containing workspace screens table and returns the list of screen IDs
      */
     public static ArrayList<Long> getScreenIdsFromCursor(Cursor sc) {
-        ArrayList<Long> screenIds = new ArrayList<Long>();
         try {
-            final int idIndex = sc.getColumnIndexOrThrow(WorkspaceScreens._ID);
-            while (sc.moveToNext()) {
-                try {
-                    screenIds.add(sc.getLong(idIndex));
-                } catch (Exception e) {
-                    FileLog.d(TAG, "Invalid screen id", e);
-                }
-            }
+            return iterateCursor(sc,
+                    sc.getColumnIndexOrThrow(WorkspaceScreens._ID),
+                    new ArrayList<Long>());
         } finally {
             sc.close();
         }
-        return screenIds;
+    }
+
+    public static <T extends Collection<Long>> T iterateCursor(Cursor c, int columnIndex, T out) {
+        while (c.moveToNext()) {
+            out.add(c.getLong(columnIndex));
+        }
+        return out;
+    }
+
+    /**
+     * Utility class to simplify managing sqlite transactions
+     */
+    public static class SQLiteTransaction implements AutoCloseable {
+        private final SQLiteDatabase mDb;
+
+        public SQLiteTransaction(SQLiteDatabase db) {
+            mDb = db;
+            db.beginTransaction();
+        }
+
+        public void commit() {
+            mDb.setTransactionSuccessful();
+        }
+
+        @Override
+        public void close() {
+            mDb.endTransaction();
+        }
     }
 }
diff --git a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
index 4addbfa..51890d1 100644
--- a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
+++ b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
@@ -21,7 +21,6 @@
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Point;
-import android.util.Log;
 
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.LauncherSettings.Favorites;
@@ -31,7 +30,6 @@
 import com.android.launcher3.util.LongArrayMap;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 
 /**
  * An extension of {@link GridSizeMigrationTask} which migrates only one screen and
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index dc85aba..00e2644 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -27,6 +27,7 @@
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction;
 import com.android.launcher3.util.LogConfig;
 
 import java.io.InvalidObjectException;
@@ -47,16 +48,13 @@
 
     public static boolean performRestore(DatabaseHelper helper) {
         SQLiteDatabase db = helper.getWritableDatabase();
-        db.beginTransaction();
-        try {
+        try (SQLiteTransaction t = new SQLiteTransaction(db)) {
             new RestoreDbTask().sanitizeDB(helper, db);
-            db.setTransactionSuccessful();
+            t.commit();
             return true;
         } catch (Exception e) {
             FileLog.e(TAG, "Failed to verify db", e);
             return false;
-        } finally {
-            db.endTransaction();
         }
     }
 
diff --git a/src/com/android/launcher3/qsb/QsbBlockerView.java b/src/com/android/launcher3/qsb/QsbBlockerView.java
deleted file mode 100644
index 5379336..0000000
--- a/src/com/android/launcher3/qsb/QsbBlockerView.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.qsb;
-
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Paint;
-import android.util.AttributeSet;
-import android.view.View;
-
-import com.android.launcher3.Launcher;
-import com.android.launcher3.Workspace;
-import com.android.launcher3.Workspace.OnStateChangeListener;
-import com.android.launcher3.Workspace.State;
-
-/**
- * A simple view used to show the region blocked by QSB during drag and drop.
- */
-public class QsbBlockerView extends View implements OnStateChangeListener {
-
-    private static final int VISIBLE_ALPHA = 100;
-
-    private final Paint mBgPaint;
-
-    public QsbBlockerView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
-        mBgPaint.setColor(Color.WHITE);
-        mBgPaint.setAlpha(0);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        super.onAttachedToWindow();
-
-        Workspace w = Launcher.getLauncher(getContext()).getWorkspace();
-        w.setOnStateChangeListener(this);
-        prepareStateChange(w.getState(), null);
-    }
-
-    @Override
-    public void prepareStateChange(State toState, AnimatorSet targetAnim) {
-        int finalAlpha = getAlphaForState(toState);
-        if (targetAnim == null) {
-            mBgPaint.setAlpha(finalAlpha);
-            invalidate();
-        } else {
-            ObjectAnimator anim = ObjectAnimator.ofArgb(mBgPaint, "alpha", finalAlpha);
-            anim.addUpdateListener(new AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                    invalidate();
-                }
-            });
-            targetAnim.play(anim);
-        }
-    }
-
-    private static int getAlphaForState(State state) {
-        switch (state) {
-            case SPRING_LOADED:
-            case OVERVIEW:
-            case OVERVIEW_HIDDEN:
-                return VISIBLE_ALPHA;
-        }
-        return 0;
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        canvas.drawPaint(mBgPaint);
-    }
-}
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
index df7f695..5ce78dc 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
@@ -65,8 +65,10 @@
     }
 
     public static boolean supportsShortcuts(ItemInfo info) {
+        boolean isItemPromise = info instanceof com.android.launcher3.ShortcutInfo
+                && ((com.android.launcher3.ShortcutInfo) info).isPromise();
         return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
-                && !info.isDisabled();
+                && !info.isDisabled() && !isItemPromise;
     }
 
     public boolean wasLastCallSuccess() {
diff --git a/src/com/android/launcher3/shortcuts/ShortcutCache.java b/src/com/android/launcher3/shortcuts/ShortcutCache.java
index d4db96d..5742d1d 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutCache.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutCache.java
@@ -19,9 +19,8 @@
 import android.annotation.TargetApi;
 import android.os.Build;
 import android.os.UserHandle;
+import android.util.ArrayMap;
 import android.util.LruCache;
-
-import java.util.HashMap;
 import java.util.List;
 
 /**
@@ -31,18 +30,15 @@
  */
 @TargetApi(Build.VERSION_CODES.N)
 public class ShortcutCache {
-    private static final String TAG = "ShortcutCache";
-    private static final boolean LOGD = false;
-
     private static final int CACHE_SIZE = 30; // Max number shortcuts we cache.
 
-    private LruCache<ShortcutKey, ShortcutInfoCompat> mCachedShortcuts;
+    private final LruCache<ShortcutKey, ShortcutInfoCompat> mCachedShortcuts;
     // We always keep pinned shortcuts in the cache.
-    private HashMap<ShortcutKey, ShortcutInfoCompat> mPinnedShortcuts;
+    private final ArrayMap<ShortcutKey, ShortcutInfoCompat> mPinnedShortcuts;
 
     public ShortcutCache() {
         mCachedShortcuts = new LruCache<>(CACHE_SIZE);
-        mPinnedShortcuts = new HashMap<>();
+        mPinnedShortcuts = new ArrayMap<>();
     }
 
     /**
diff --git a/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java b/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
index ab8de6b..e9d2b50 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutDragPreviewProvider.java
@@ -23,10 +23,10 @@
 import android.graphics.drawable.Drawable;
 import android.view.View;
 
-import com.android.launcher3.graphics.HolographicOutlineHelper;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.graphics.DragPreviewProvider;
+import com.android.launcher3.graphics.HolographicOutlineHelper;
 
 /**
  * Extension of {@link DragPreviewProvider} which generates bitmaps scaled to the default icon size.
diff --git a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
index 37047bb..9c91c87 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutInfoCompat.java
@@ -18,15 +18,11 @@
 
 import android.annotation.TargetApi;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ShortcutInfo;
 import android.os.Build;
 import android.os.UserHandle;
 
-import com.android.launcher3.ItemInfo;
-import com.android.launcher3.compat.UserManagerCompat;
-
 /**
  * Wrapper class for {@link android.content.pm.ShortcutInfo}, representing deep shortcuts into apps.
  *
diff --git a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
index 5b3b02e..340a6f0 100644
--- a/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
+++ b/src/com/android/launcher3/shortcuts/ShortcutsItemView.java
@@ -16,12 +16,10 @@
 
 package com.android.launcher3.shortcuts;
 
-import android.animation.Animator;
-import android.animation.AnimatorSet;
 import android.content.Context;
 import android.graphics.Point;
-import android.support.v4.content.ContextCompat;
 import android.util.AttributeSet;
+import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
 import android.widget.LinearLayout;
@@ -30,9 +28,7 @@
 import com.android.launcher3.BubbleTextView;
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.R;
-import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.dragndrop.DragView;
 import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
@@ -135,7 +131,17 @@
             if (mSystemShortcutIcons == null) {
                 mSystemShortcutIcons = (LinearLayout) mLauncher.getLayoutInflater().inflate(
                         R.layout.system_shortcut_icons, mShortcutsLayout, false);
-                mShortcutsLayout.addView(mSystemShortcutIcons, 0);
+
+                View divider = LayoutInflater.from(getContext()).inflate(
+                        R.layout.horizontal_divider, this, false);
+
+                if (mShortcutsLayout.getChildCount() > 0) {
+                    mShortcutsLayout.addView(divider);
+                }
+                mShortcutsLayout.addView(mSystemShortcutIcons);
+                if (mShortcutsLayout.getChildCount() == 1) {
+                    mShortcutsLayout.addView(divider);
+                }
             }
             mSystemShortcutIcons.addView(shortcutView, index);
         } else {
@@ -210,51 +216,6 @@
     }
 
     @Override
-    public Animator createOpenAnimation(boolean isContainerAboveIcon, boolean pivotLeft) {
-        AnimatorSet openAnimation = LauncherAnimUtils.createAnimatorSet();
-        openAnimation.play(super.createOpenAnimation(isContainerAboveIcon, pivotLeft));
-        for (int i = 0; i < mShortcutsLayout.getChildCount(); i++) {
-            if (!(mShortcutsLayout.getChildAt(i) instanceof DeepShortcutView)) {
-                continue;
-            }
-            DeepShortcutView shortcutView = ((DeepShortcutView) mShortcutsLayout.getChildAt(i));
-            View deepShortcutIcon = shortcutView.getIconView();
-            deepShortcutIcon.setScaleX(0);
-            deepShortcutIcon.setScaleY(0);
-            openAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder(
-                    deepShortcutIcon, new PropertyListBuilder().scale(1).build()));
-        }
-        return openAnimation;
-    }
-
-    @Override
-    public Animator createCloseAnimation(boolean isContainerAboveIcon, boolean pivotLeft,
-            long duration) {
-        AnimatorSet closeAnimation = LauncherAnimUtils.createAnimatorSet();
-        closeAnimation.play(super.createCloseAnimation(isContainerAboveIcon, pivotLeft, duration));
-        for (int i = 0; i < mShortcutsLayout.getChildCount(); i++) {
-            if (!(mShortcutsLayout.getChildAt(i) instanceof DeepShortcutView)) {
-                continue;
-            }
-            DeepShortcutView shortcutView = ((DeepShortcutView) mShortcutsLayout.getChildAt(i));
-            View deepShortcutIcon = shortcutView.getIconView();
-            deepShortcutIcon.setScaleX(1);
-            deepShortcutIcon.setScaleY(1);
-            closeAnimation.play(LauncherAnimUtils.ofPropertyValuesHolder(
-                    deepShortcutIcon, new PropertyListBuilder().scale(0).build()));
-        }
-        return closeAnimation;
-    }
-
-    @Override
-    public int getArrowColor(boolean isArrowAttachedToBottom) {
-        return ContextCompat.getColor(getContext(),
-                isArrowAttachedToBottom || mSystemShortcutIcons == null
-                        ? R.color.popup_background_color
-                        : R.color.popup_header_background_color);
-    }
-
-    @Override
     public void fillInLogContainerData(View v, ItemInfo info, LauncherLogProto.Target target,
             LauncherLogProto.Target targetParent) {
         target.itemType = LauncherLogProto.ItemType.DEEPSHORTCUT;
diff --git a/src/com/android/launcher3/testing/LauncherExtension.java b/src/com/android/launcher3/testing/LauncherExtension.java
index aedca8d..8d43518 100644
--- a/src/com/android/launcher3/testing/LauncherExtension.java
+++ b/src/com/android/launcher3/testing/LauncherExtension.java
@@ -2,7 +2,6 @@
 
 import android.content.Intent;
 import android.graphics.Color;
-import android.graphics.Rect;
 import android.os.Bundle;
 import android.view.Menu;
 import android.view.View;
@@ -11,8 +10,6 @@
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherCallbacks;
-import com.android.launcher3.allapps.AllAppsSearchBarController;
-import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.launcher3.util.ComponentKey;
 
 import java.io.FileDescriptor;
@@ -200,11 +197,6 @@
         }
 
         @Override
-        public AllAppsSearchBarController getAllAppsSearchBarController() {
-            return null;
-        }
-
-        @Override
         public List<ComponentKey> getPredictedApps() {
             // To debug app predictions, enable AlphabeticalAppsList#DEBUG_PREDICTIONS
             return new ArrayList<>();
@@ -216,11 +208,6 @@
         }
 
         @Override
-        public void setLauncherSearchCallback(Object callbacks) {
-            // Do nothing
-        }
-
-        @Override
         public void onAttachedToWindow() {
         }
 
diff --git a/src/com/android/launcher3/util/CachedPackageTracker.java b/src/com/android/launcher3/util/CachedPackageTracker.java
deleted file mode 100644
index 314b4c0..0000000
--- a/src/com/android/launcher3/util/CachedPackageTracker.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.util;
-
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.pm.LauncherActivityInfo;
-import android.os.UserHandle;
-
-import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.LauncherAppsCompat;
-import com.android.launcher3.compat.LauncherAppsCompat.OnAppsChangedCallbackCompat;
-import com.android.launcher3.compat.UserManagerCompat;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Utility class to track list of installed packages. It persists the list so that apps
- * installed/uninstalled while Launcher was dead can also be handled properly.
- */
-public abstract class CachedPackageTracker implements OnAppsChangedCallbackCompat {
-
-    protected static final String INSTALLED_PACKAGES_PREFIX = "installed_packages_for_user_";
-
-    protected final SharedPreferences mPrefs;
-    protected final UserManagerCompat mUserManager;
-    protected final LauncherAppsCompat mLauncherApps;
-
-    public CachedPackageTracker(Context context, String preferenceFileName) {
-        mPrefs = context.getSharedPreferences(preferenceFileName, Context.MODE_PRIVATE);
-        mUserManager = UserManagerCompat.getInstance(context);
-        mLauncherApps = LauncherAppsCompat.getInstance(context);
-    }
-
-    /**
-     * Checks the list of user apps, and generates package event accordingly.
-     * {@see #onLauncherAppsAdded}, {@see #onLauncherPackageRemoved}
-     */
-    public void processUserApps(List<LauncherActivityInfo> apps, UserHandle user) {
-        String prefKey = INSTALLED_PACKAGES_PREFIX + mUserManager.getSerialNumberForUser(user);
-        HashSet<String> oldPackageSet = new HashSet<>();
-        final boolean userAppsExisted = getUserApps(oldPackageSet, prefKey);
-
-        HashSet<String> packagesRemoved = new HashSet<>(oldPackageSet);
-        HashSet<String> newPackageSet = new HashSet<>();
-        ArrayList<LauncherActivityInstallInfo> packagesAdded = new ArrayList<>();
-
-        for (LauncherActivityInfo info : apps) {
-            String packageName = info.getComponentName().getPackageName();
-            newPackageSet.add(packageName);
-            packagesRemoved.remove(packageName);
-
-            if (!oldPackageSet.contains(packageName)) {
-                oldPackageSet.add(packageName);
-                packagesAdded.add(new LauncherActivityInstallInfo(
-                        info, info.getFirstInstallTime()));
-            }
-        }
-
-        if (!packagesAdded.isEmpty() || !packagesRemoved.isEmpty()) {
-            mPrefs.edit().putStringSet(prefKey, newPackageSet).apply();
-
-            if (!packagesAdded.isEmpty()) {
-                Collections.sort(packagesAdded);
-                onLauncherAppsAdded(packagesAdded, user, userAppsExisted);
-            }
-
-            if (!packagesRemoved.isEmpty()) {
-                for (String pkg : packagesRemoved) {
-                    onLauncherPackageRemoved(pkg, user);
-                }
-            }
-        }
-    }
-
-    /**
-     * Reads the list of user apps which have already been processed.
-     * @return false if the list didn't exist, true otherwise
-     */
-    private boolean getUserApps(HashSet<String> outExistingApps, String prefKey) {
-        Set<String> userApps = mPrefs.getStringSet(prefKey, null);
-        if (userApps == null) {
-            return false;
-        } else {
-            outExistingApps.addAll(userApps);
-            return true;
-        }
-    }
-
-    @Override
-    public void onPackageRemoved(String packageName, UserHandle user) {
-        String prefKey = INSTALLED_PACKAGES_PREFIX + mUserManager.getSerialNumberForUser(user);
-        HashSet<String> packageSet = new HashSet<>();
-        if (getUserApps(packageSet, prefKey) && packageSet.remove(packageName)) {
-            mPrefs.edit().putStringSet(prefKey, packageSet).apply();
-        }
-
-        onLauncherPackageRemoved(packageName, user);
-    }
-
-    @Override
-    public void onPackageAdded(String packageName, UserHandle user) {
-        String prefKey = INSTALLED_PACKAGES_PREFIX + mUserManager.getSerialNumberForUser(user);
-        HashSet<String> packageSet = new HashSet<>();
-        final boolean userAppsExisted = getUserApps(packageSet, prefKey);
-        if (!packageSet.contains(packageName)) {
-            List<LauncherActivityInfo> activities =
-                    mLauncherApps.getActivityList(packageName, user);
-            if (!activities.isEmpty()) {
-                LauncherActivityInfo activityInfo = activities.get(0);
-
-                packageSet.add(packageName);
-                mPrefs.edit().putStringSet(prefKey, packageSet).apply();
-                onLauncherAppsAdded(Arrays.asList(
-                        new LauncherActivityInstallInfo(activityInfo, System.currentTimeMillis())),
-                        user, userAppsExisted);
-            }
-        }
-    }
-
-    @Override
-    public void onPackageChanged(String packageName, UserHandle user) { }
-
-    @Override
-    public void onPackagesAvailable(
-            String[] packageNames, UserHandle user, boolean replacing) { }
-
-    @Override
-    public void onPackagesUnavailable(
-            String[] packageNames, UserHandle user, boolean replacing) { }
-
-    @Override
-    public void onPackagesSuspended(String[] packageNames, UserHandle user) { }
-
-    @Override
-    public void onPackagesUnsuspended(String[] packageNames, UserHandle user) { }
-
-    /**
-     * Called when new launcher apps are added.
-     * @param apps list of newly added activities. Only one entry per package is sent.
-     * @param user the user for this event. All activities in {@param apps} will belong to
-     *             the same user.
-     * @param userAppsExisted false if the list was processed for the first time, like in case
-     *                        when Launcher was newly installed or a new user was added.
-     */
-    protected abstract void onLauncherAppsAdded(List<LauncherActivityInstallInfo> apps,
-            UserHandle user, boolean userAppsExisted);
-
-    /**
-     * Called when apps are removed from the system.
-     */
-    protected abstract void onLauncherPackageRemoved(String packageName, UserHandle user);
-
-    public static class LauncherActivityInstallInfo
-            implements Comparable<LauncherActivityInstallInfo> {
-        public final LauncherActivityInfo info;
-        public final long installTime;
-
-        public LauncherActivityInstallInfo(LauncherActivityInfo info, long installTime) {
-            this.info = info;
-            this.installTime = installTime;
-        }
-
-        @Override
-        public int compareTo(LauncherActivityInstallInfo another) {
-            return Utilities.longCompare(installTime, another.installTime);
-        }
-    }
-}
diff --git a/src/com/android/launcher3/util/FocusLogic.java b/src/com/android/launcher3/util/FocusLogic.java
index afc45fe..b80e94d 100644
--- a/src/com/android/launcher3/util/FocusLogic.java
+++ b/src/com/android/launcher3/util/FocusLogic.java
@@ -23,7 +23,6 @@
 
 import com.android.launcher3.CellLayout;
 import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.ShortcutAndWidgetContainer;
 import com.android.launcher3.config.FeatureFlags;
 
diff --git a/src/com/android/launcher3/util/IOUtils.java b/src/com/android/launcher3/util/IOUtils.java
new file mode 100644
index 0000000..77c21fe
--- /dev/null
+++ b/src/com/android/launcher3/util/IOUtils.java
@@ -0,0 +1,55 @@
+/*
+ * 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.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Supports various IO utility functions
+ */
+public class IOUtils {
+
+    private static final int BUF_SIZE = 0x1000; // 4K
+
+    public static byte[] toByteArray(File file) throws IOException {
+        try (InputStream in = new FileInputStream(file)) {
+            return toByteArray(in);
+        }
+    }
+
+    public static byte[] toByteArray(InputStream in) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        copy(in, out);
+        return out.toByteArray();
+    }
+
+    public static long copy(InputStream from, OutputStream to) throws IOException {
+        byte[] buf = new byte[BUF_SIZE];
+        long total = 0;
+        int r;
+        while ((r = from.read(buf)) != -1) {
+            to.write(buf, 0, r);
+            total += r;
+        }
+        return total;
+    }
+}
diff --git a/src/com/android/launcher3/util/LooperExecuter.java b/src/com/android/launcher3/util/LooperExecutor.java
similarity index 94%
rename from src/com/android/launcher3/util/LooperExecuter.java
rename to src/com/android/launcher3/util/LooperExecutor.java
index 4db999b..5b7c20b 100644
--- a/src/com/android/launcher3/util/LooperExecuter.java
+++ b/src/com/android/launcher3/util/LooperExecutor.java
@@ -25,11 +25,11 @@
 /**
  * Extension of {@link AbstractExecutorService} which executed on a provided looper.
  */
-public class LooperExecuter extends AbstractExecutorService {
+public class LooperExecutor extends AbstractExecutorService {
 
     private final Handler mHandler;
 
-    public LooperExecuter(Looper looper) {
+    public LooperExecutor(Looper looper) {
         mHandler = new Handler(looper);
     }
 
diff --git a/src/com/android/launcher3/util/LooperIdleLock.java b/src/com/android/launcher3/util/LooperIdleLock.java
new file mode 100644
index 0000000..35cac14
--- /dev/null
+++ b/src/com/android/launcher3/util/LooperIdleLock.java
@@ -0,0 +1,71 @@
+/*
+ * 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.util;
+
+import android.os.Looper;
+import android.os.MessageQueue;
+
+import com.android.launcher3.Utilities;
+
+/**
+ * Utility class to block execution until the UI looper is idle.
+ */
+public class LooperIdleLock implements MessageQueue.IdleHandler, Runnable {
+
+    private final Object mLock;
+
+    private boolean mIsLocked;
+
+    public LooperIdleLock(Object lock, Looper looper) {
+        mLock = lock;
+        mIsLocked = true;
+        if (Utilities.ATLEAST_MARSHMALLOW) {
+            looper.getQueue().addIdleHandler(this);
+        } else {
+            // Looper.myQueue() only gives the current queue. Move the execution to the UI thread
+            // so that the IdleHandler is attached to the correct message queue.
+            new LooperExecutor(looper).execute(this);
+        }
+    }
+
+    @Override
+    public void run() {
+        Looper.myQueue().addIdleHandler(this);
+    }
+
+    @Override
+    public boolean queueIdle() {
+        synchronized (mLock) {
+            mIsLocked = false;
+            mLock.notify();
+        }
+        return false;
+    }
+
+    public boolean awaitLocked(long ms) {
+        if (mIsLocked) {
+            try {
+                // Just in case mFlushingWorkerThread changes but we aren't woken up,
+                // wait no longer than 1sec at a time
+                mLock.wait(ms);
+            } catch (InterruptedException ex) {
+                // Ignore
+            }
+        }
+        return mIsLocked;
+    }
+}
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
index ce603c4..091dd84 100644
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
@@ -19,23 +19,23 @@
 import android.content.Context;
 import android.content.SharedPreferences;
 import android.content.pm.LauncherActivityInfo;
+import android.os.Handler;
 import android.os.Process;
 import android.os.UserHandle;
-import android.support.v4.os.BuildCompat;
 
-import com.android.launcher3.AppInfo;
 import com.android.launcher3.FolderInfo;
-import com.android.launcher3.IconCache;
+import com.android.launcher3.InstallShortcutReceiver;
 import com.android.launcher3.ItemInfo;
-import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherFiles;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.R;
 import com.android.launcher3.SessionCommitReceiver;
 import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.shortcuts.ShortcutInfoCompat;
+import com.android.launcher3.model.BgDataModel;
+import com.android.launcher3.model.ModelWriter;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -47,11 +47,6 @@
  */
 public class ManagedProfileHeuristic {
 
-    /**
-     * Maintain a set of packages installed per user.
-     */
-    private static final String INSTALLED_PACKAGES_PREFIX = "installed_packages_for_user_";
-
     private static final String USER_FOLDER_ID_PREFIX = "user_folder_";
 
     /**
@@ -59,165 +54,154 @@
      */
     private static final long AUTO_ADD_TO_FOLDER_DURATION = 8 * 60 * 60 * 1000;
 
-    public static ManagedProfileHeuristic get(Context context, UserHandle user) {
-        if (!Process.myUserHandle().equals(user)) {
-            return new ManagedProfileHeuristic(context, user);
-        }
-        return null;
-    }
-
-    private final Context mContext;
-    private final LauncherModel mModel;
-    private final UserHandle mUser;
-    private final IconCache mIconCache;
-    private final boolean mAddIconsToHomescreen;
-
-    private ManagedProfileHeuristic(Context context, UserHandle user) {
-        mContext = context;
-        mUser = user;
-        mModel = LauncherAppState.getInstance(context).getModel();
-        mIconCache = LauncherAppState.getInstance(context).getIconCache();
-        mAddIconsToHomescreen =
-                !BuildCompat.isAtLeastO() || SessionCommitReceiver.isEnabled(context);
-    }
-
-    public void processPackageRemoved(String[] packages) {
-        Preconditions.assertWorkerThread();
-        ManagedProfilePackageHandler handler = new ManagedProfilePackageHandler();
-        for (String pkg : packages) {
-            handler.onPackageRemoved(pkg, mUser);
-        }
-    }
-
-    public void processPackageAdd(String[] packages) {
-        Preconditions.assertWorkerThread();
-        ManagedProfilePackageHandler handler = new ManagedProfilePackageHandler();
-        for (String pkg : packages) {
-            handler.onPackageAdded(pkg, mUser);
-        }
-    }
-
-    public void processUserApps(List<LauncherActivityInfo> apps) {
-        Preconditions.assertWorkerThread();
-        new ManagedProfilePackageHandler().processUserApps(apps, mUser);
-    }
-
-    private class ManagedProfilePackageHandler extends CachedPackageTracker {
-
-        private ManagedProfilePackageHandler() {
-            super(mContext, LauncherFiles.MANAGED_USER_PREFERENCES_KEY);
+    public static void onAllAppsLoaded(final Context context,
+            List<LauncherActivityInfo> apps, UserHandle user) {
+        if (Process.myUserHandle().equals(user)) {
+            return;
         }
 
-        protected void onLauncherAppsAdded(
-                List<LauncherActivityInstallInfo> apps, UserHandle user, boolean userAppsExisted) {
-            ArrayList<ShortcutInfo> workFolderApps = new ArrayList<>();
-            ArrayList<ShortcutInfo> homescreenApps = new ArrayList<>();
+        UserFolderInfo ufi = new UserFolderInfo(context, user, null);
+        // We only handle folder creation once. Later icon additions are handled using package
+        // or session events.
+        if (ufi.folderAlreadyCreated) {
+            return;
+        }
 
-            int count = apps.size();
-            long folderCreationTime =
-                    mUserManager.getUserCreationTime(user) + AUTO_ADD_TO_FOLDER_DURATION;
+        if (Utilities.isAtLeastO() && !SessionCommitReceiver.isEnabled(context)) {
+            // Just mark the folder id preference to avoid new folder creation later.
+            ufi.prefs.edit().putLong(ufi.folderIdKey, ItemInfo.NO_ID).apply();
+            return;
+        }
 
-            boolean quietModeEnabled = UserManagerCompat.getInstance(mContext)
-                    .isQuietModeEnabled(user);
-            for (int i = 0; i < count; i++) {
-                LauncherActivityInstallInfo info = apps.get(i);
-                AppInfo appInfo = new AppInfo(info.info, user, quietModeEnabled);
-                mIconCache.getTitleAndIcon(appInfo, info.info, false /* useLowResIcon */);
-                ShortcutInfo si = appInfo.makeShortcut();
-                ((info.installTime <= folderCreationTime) ? workFolderApps : homescreenApps).add(si);
-            }
-
-            finalizeWorkFolder(user, workFolderApps, homescreenApps);
-
-            // Do not add shortcuts on the homescreen for the first time. This prevents the launcher
-            // getting filled with the managed user apps, when it start with a fresh DB (or after
-            // a very long time).
-            if (userAppsExisted && !homescreenApps.isEmpty() && mAddIconsToHomescreen) {
-                mModel.addAndBindAddedWorkspaceItems(new ArrayList<ItemInfo>(homescreenApps));
+        InstallShortcutReceiver.enableInstallQueue(InstallShortcutReceiver.FLAG_BULK_ADD);
+        for (LauncherActivityInfo app : apps) {
+            // Queue all items which should go in the work folder.
+            if (app.getFirstInstallTime() < ufi.addIconToFolderTime) {
+                InstallShortcutReceiver.queueActivityInfo(app, context);
             }
         }
+        // Post the queue update on next frame, so that the loader gets finished.
+        new Handler(LauncherModel.getWorkerLooper()).post(new Runnable() {
+            @Override
+            public void run() {
+                InstallShortcutReceiver.disableAndFlushInstallQueue(
+                        InstallShortcutReceiver.FLAG_BULK_ADD, context);
+            }
+        });
+    }
 
-        @Override
-        protected void onLauncherPackageRemoved(String packageName, UserHandle user) {
+
+    /**
+     * Utility class to help workspace icon addition.
+     */
+    public static class UserFolderInfo {
+
+        final ArrayList<ShortcutInfo> pendingShortcuts = new ArrayList<>();
+
+        final UserHandle user;
+
+        final long userSerial;
+        // Time until which icons will be added to folder instead.
+        final long addIconToFolderTime;
+
+        final String folderIdKey;
+        final SharedPreferences prefs;
+
+        final boolean folderAlreadyCreated;
+        final FolderInfo folderInfo;
+
+        boolean folderPendingAddition;
+
+        public UserFolderInfo(Context context, UserHandle user, BgDataModel dataModel) {
+            this.user = user;
+
+            UserManagerCompat um = UserManagerCompat.getInstance(context);
+            userSerial = um.getSerialNumberForUser(user);
+            addIconToFolderTime = um.getUserCreationTime(user) + AUTO_ADD_TO_FOLDER_DURATION;
+
+            folderIdKey = USER_FOLDER_ID_PREFIX + userSerial;
+            prefs = prefs(context);
+
+            folderAlreadyCreated = prefs.contains(folderIdKey);
+            if (dataModel != null) {
+                if (folderAlreadyCreated) {
+                    long folderId = prefs.getLong(folderIdKey, ItemInfo.NO_ID);
+                    folderInfo = dataModel.folders.get(folderId);
+                } else {
+                    folderInfo = new FolderInfo();
+                    folderInfo.title = context.getText(R.string.work_folder_name);
+                    folderInfo.setOption(FolderInfo.FLAG_WORK_FOLDER, true, null);
+                    folderPendingAddition = true;
+                }
+            } else {
+                folderInfo = null;
+            }
         }
 
         /**
-         * Adds and binds shortcuts marked to be added to the work folder.
+         * Returns the ItemInfo which should be added to the workspace. In case the the provided
+         * {@link ShortcutInfo} or a wrapped {@link FolderInfo} or null.
          */
-        private void finalizeWorkFolder(
-                UserHandle user, final ArrayList<ShortcutInfo> workFolderApps,
-                ArrayList<ShortcutInfo> homescreenApps) {
-            if (workFolderApps.isEmpty()) {
+        public ItemInfo convertToWorkspaceItem(
+                ShortcutInfo shortcut, LauncherActivityInfo activityInfo) {
+            if (activityInfo.getFirstInstallTime() >= addIconToFolderTime) {
+                return shortcut;
+            }
+
+            if (folderAlreadyCreated) {
+                if (folderInfo == null) {
+                    // Work folder was deleted by user, add icon to home screen.
+                    return shortcut;
+                } else {
+                    // Add item to work folder instead. Nothing needs to be added
+                    // on the homescreen.
+                    pendingShortcuts.add(shortcut);
+                    return null;
+                }
+            }
+
+            pendingShortcuts.add(shortcut);
+            folderInfo.add(shortcut, false);
+            if (folderPendingAddition) {
+                folderPendingAddition = false;
+                return folderInfo;
+            } else {
+                // WorkFolder already requested to be added. Nothing new needs to be added.
+                return null;
+            }
+        }
+
+        public void applyPendingState(ModelWriter writer) {
+            if (folderInfo == null) {
                 return;
             }
-            // Try to get a work folder.
-            String folderIdKey = USER_FOLDER_ID_PREFIX + mUserManager.getSerialNumberForUser(user);
-            if (!mAddIconsToHomescreen) {
-                if (!mPrefs.contains(folderIdKey)) {
-                    // Just mark the folder id preference to avoid new folder creation later.
-                    mPrefs.edit().putLong(folderIdKey, -1).apply();
-                }
-                return;
+
+            int startingRank = 0;
+            if (folderAlreadyCreated) {
+                startingRank = folderInfo.contents.size();
             }
-            if (mPrefs.contains(folderIdKey)) {
-                long folderId = mPrefs.getLong(folderIdKey, 0);
-                final FolderInfo workFolder = mModel.findFolderById(folderId);
 
-                if (workFolder == null || !workFolder.hasOption(FolderInfo.FLAG_WORK_FOLDER)) {
-                    // Could not get a work folder. Add all the icons to homescreen.
-                    homescreenApps.addAll(0, workFolderApps);
-                    return;
-                }
-                saveWorkFolderShortcuts(folderId, workFolder.contents.size(), workFolderApps);
+            for (ShortcutInfo info : pendingShortcuts) {
+                info.rank = startingRank++;
+                writer.addItemToDatabase(info, folderInfo.id, 0, 0, 0);
+            }
 
+            if (folderAlreadyCreated) {
                 // FolderInfo could already be bound. We need to add shortcuts on the UI thread.
                 new MainThreadExecutor().execute(new Runnable() {
 
                     @Override
                     public void run() {
-                        workFolder.prepareAutoUpdate();
-                        for (ShortcutInfo info : workFolderApps) {
-                            workFolder.add(info, false);
+                        folderInfo.prepareAutoUpdate();
+                        for (ShortcutInfo info : pendingShortcuts) {
+                            folderInfo.add(info, false);
                         }
                     }
                 });
             } else {
-                // Create a new folder.
-                final FolderInfo workFolder = new FolderInfo();
-                workFolder.title = mContext.getText(R.string.work_folder_name);
-                workFolder.setOption(FolderInfo.FLAG_WORK_FOLDER, true, null);
-
-                // Add all shortcuts before adding it to the UI, as an empty folder might get deleted.
-                for (ShortcutInfo info : workFolderApps) {
-                    workFolder.add(info, false);
-                }
-
-                // Add the item to home screen and DB. This also generates an item id synchronously.
-                ArrayList<ItemInfo> itemList = new ArrayList<>(1);
-                itemList.add(workFolder);
-                mModel.addAndBindAddedWorkspaceItems(itemList);
-                mPrefs.edit().putLong(folderIdKey, workFolder.id).apply();
-
-                saveWorkFolderShortcuts(workFolder.id, 0, workFolderApps);
+                prefs.edit().putLong(folderIdKey, folderInfo.id).apply();
             }
         }
-
-        @Override
-        public void onShortcutsChanged(String packageName, List<ShortcutInfoCompat> shortcuts,
-                UserHandle user) {
-            // Do nothing
-        }
-    }
-
-    /**
-     * Add work folder shortcuts to the DB.
-     */
-    private void saveWorkFolderShortcuts(
-            long workFolderId, int startingRank, ArrayList<ShortcutInfo> workFolderApps) {
-        for (ItemInfo info : workFolderApps) {
-            info.rank = startingRank++;
-            mModel.getWriter(false).addItemToDatabase(info, workFolderId, 0, 0, 0);
-        }
     }
 
     /**
@@ -225,14 +209,12 @@
      */
     public static void processAllUsers(List<UserHandle> users, Context context) {
         UserManagerCompat userManager = UserManagerCompat.getInstance(context);
-        HashSet<String> validKeys = new HashSet<String>();
+        HashSet<String> validKeys = new HashSet<>();
         for (UserHandle user : users) {
-            addAllUserKeys(userManager.getSerialNumberForUser(user), validKeys);
+            validKeys.add(USER_FOLDER_ID_PREFIX + userManager.getSerialNumberForUser(user));
         }
 
-        SharedPreferences prefs = context.getSharedPreferences(
-                LauncherFiles.MANAGED_USER_PREFERENCES_KEY,
-                Context.MODE_PRIVATE);
+        SharedPreferences prefs = prefs(context);
         SharedPreferences.Editor editor = prefs.edit();
         for (String key : prefs.getAll().keySet()) {
             if (!validKeys.contains(key)) {
@@ -242,11 +224,6 @@
         editor.apply();
     }
 
-    private static void addAllUserKeys(long userSerial, HashSet<String> keysOut) {
-        keysOut.add(INSTALLED_PACKAGES_PREFIX + userSerial);
-        keysOut.add(USER_FOLDER_ID_PREFIX + userSerial);
-    }
-
     /**
      * For each user, if a work folder has not been created, mark it such that the folder will
      * never get created.
@@ -260,11 +237,8 @@
             if (myUser.equals(user)) {
                 continue;
             }
-
             if (prefs == null) {
-                prefs = context.getSharedPreferences(
-                        LauncherFiles.MANAGED_USER_PREFERENCES_KEY,
-                        Context.MODE_PRIVATE);
+                prefs = prefs(context);
             }
             String folderIdKey = USER_FOLDER_ID_PREFIX + userManager.getSerialNumberForUser(user);
             if (!prefs.contains(folderIdKey)) {
@@ -272,4 +246,9 @@
             }
         }
     }
+
+    public static SharedPreferences prefs(Context context) {
+        return context.getSharedPreferences(
+                LauncherFiles.MANAGED_USER_PREFERENCES_KEY, Context.MODE_PRIVATE);
+    }
 }
diff --git a/src/com/android/launcher3/util/MultiStateAlphaController.java b/src/com/android/launcher3/util/MultiStateAlphaController.java
deleted file mode 100644
index 956fc9e..0000000
--- a/src/com/android/launcher3/util/MultiStateAlphaController.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.view.View;
-import android.view.accessibility.AccessibilityManager;
-
-import java.util.Arrays;
-
-/**
- * A utility class which divides the alpha for a view across multiple states.
- */
-public class MultiStateAlphaController {
-
-    private final View mTargetView;
-    private final float[] mAlphas;
-    private final AccessibilityManager mAm;
-    private int mZeroAlphaListenerCount = 0;
-
-    public MultiStateAlphaController(View view, int stateCount) {
-        mTargetView = view;
-        mAlphas = new float[stateCount];
-        Arrays.fill(mAlphas, 1);
-
-        mAm = (AccessibilityManager) view.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
-    }
-
-    public void setAlphaAtIndex(float alpha, int index) {
-        mAlphas[index] = alpha;
-        updateAlpha();
-    }
-
-    private void updateAlpha() {
-        // Only update the alpha if no zero-alpha animation is running.
-        if (mZeroAlphaListenerCount > 0) {
-            return;
-        }
-        float finalAlpha = 1;
-        for (float a : mAlphas) {
-            finalAlpha = finalAlpha * a;
-        }
-        mTargetView.setAlpha(finalAlpha);
-        mTargetView.setVisibility(finalAlpha > 0 ? View.VISIBLE
-                : (mAm.isEnabled() ? View.GONE : View.INVISIBLE));
-    }
-
-    /**
-     * Returns an animator which changes the alpha at the index {@param index}
-     * to {@param finalAlpha}. Alphas at other index are not affected.
-     */
-    public Animator animateAlphaAtIndex(float finalAlpha, final int index) {
-        final ValueAnimator anim;
-
-        if (Float.compare(finalAlpha, mAlphas[index]) == 0) {
-            // Return a dummy animator to avoid null checks.
-            anim = ValueAnimator.ofFloat(0, 0);
-        } else {
-            ValueAnimator animator = ValueAnimator.ofFloat(mAlphas[index], finalAlpha);
-            animator.addUpdateListener(new AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                    float value = (Float) valueAnimator.getAnimatedValue();
-                    setAlphaAtIndex(value, index);
-                }
-            });
-            anim = animator;
-        }
-
-        if (Float.compare(finalAlpha, 0f) == 0) {
-            // In case when any channel is animating to 0, and the current alpha is also 0, do not
-            // update alpha of the target view while the animation is running.
-            // We special case '0' because if any channel is set to 0, values of other
-            // channels do not matter.
-            anim.addListener(new ZeroAlphaAnimatorListener());
-        }
-        return anim;
-    }
-
-    private class ZeroAlphaAnimatorListener extends AnimatorListenerAdapter {
-
-        private boolean mStartedAtZero = false;
-
-        @Override
-        public void onAnimationStart(Animator animation) {
-            mStartedAtZero = Float.compare(mTargetView.getAlpha(), 0f) == 0;
-            if (mStartedAtZero) {
-                mZeroAlphaListenerCount++;
-                mTargetView.setAlpha(0);
-            }
-        }
-
-        @Override
-        public void onAnimationEnd(Animator animation) {
-            if (mStartedAtZero) {
-                mZeroAlphaListenerCount--;
-                updateAlpha();
-            }
-        }
-    }
-}
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index e12b2d4..13034dd 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -30,9 +30,11 @@
 import android.text.TextUtils;
 
 import com.android.launcher3.AppInfo;
+import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.LauncherAppsCompat;
 
+import java.net.URISyntaxException;
 import java.util.List;
 
 /**
@@ -149,4 +151,20 @@
                         .appendQueryParameter("id", packageName)
                         .build());
     }
+
+    /**
+     * Creates a new market search intent.
+     */
+    public static Intent getMarketSearchIntent(Context context, String query) {
+        try {
+            Intent intent = Intent.parseUri(context.getString(R.string.market_search_intent), 0);
+            if (!TextUtils.isEmpty(query)) {
+                intent.setData(
+                        intent.getData().buildUpon().appendQueryParameter("q", query).build());
+            }
+            return intent;
+        } catch (URISyntaxException e) {
+            throw new RuntimeException(e);
+        }
+    }
 }
diff --git a/src/com/android/launcher3/util/PillRevealOutlineProvider.java b/src/com/android/launcher3/util/PillRevealOutlineProvider.java
deleted file mode 100644
index a57d69f..0000000
--- a/src/com/android/launcher3/util/PillRevealOutlineProvider.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.graphics.Rect;
-import android.view.ViewOutlineProvider;
-
-/**
- * A {@link ViewOutlineProvider} that animates a reveal in a "pill" shape.
- * A pill is simply a round rect, but we assume the width is greater than
- * the height and that the radius is equal to half the height.
- */
-public class PillRevealOutlineProvider extends RevealOutlineAnimation {
-
-    private int mCenterX;
-    private int mCenterY;
-    private float mFinalRadius;
-    protected Rect mPillRect;
-
-    /**
-     * @param x reveal center x
-     * @param y reveal center y
-     * @param pillRect round rect that represents the final pill shape
-     */
-    public PillRevealOutlineProvider(int x, int y, Rect pillRect) {
-        this(x, y, pillRect, pillRect.height() / 2f);
-    }
-
-    public PillRevealOutlineProvider(int x, int y, Rect pillRect, float radius) {
-        mCenterX = x;
-        mCenterY = y;
-        mPillRect = pillRect;
-        mOutlineRadius = mFinalRadius = radius;
-    }
-
-    @Override
-    public boolean shouldRemoveElevationDuringAnimation() {
-        return false;
-    }
-
-    @Override
-    public void setProgress(float progress) {
-        // Assumes width is greater than height.
-        int centerToEdge = Math.max(mCenterX, mPillRect.width() - mCenterX);
-        int currentSize = (int) (progress * centerToEdge);
-
-        // Bound the outline to the final pill shape defined by mPillRect.
-        mOutline.left = Math.max(mPillRect.left, mCenterX - currentSize);
-        mOutline.top = Math.max(mPillRect.top, mCenterY - currentSize);
-        mOutline.right = Math.min(mPillRect.right, mCenterX + currentSize);
-        mOutline.bottom = Math.min(mPillRect.bottom, mCenterY + currentSize);
-        mOutlineRadius = Math.min(mFinalRadius, mOutline.height() / 2);
-    }
-}
diff --git a/src/com/android/launcher3/util/Preconditions.java b/src/com/android/launcher3/util/Preconditions.java
index 89353e1..7ab0d31 100644
--- a/src/com/android/launcher3/util/Preconditions.java
+++ b/src/com/android/launcher3/util/Preconditions.java
@@ -19,7 +19,7 @@
 import android.os.Looper;
 
 import com.android.launcher3.LauncherModel;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 
 /**
  * A set of utility methods for thread verification.
@@ -27,25 +27,25 @@
 public class Preconditions {
 
     public static void assertNotNull(Object o) {
-        if (ProviderConfig.IS_DOGFOOD_BUILD && o == null) {
+        if (FeatureFlags.IS_DOGFOOD_BUILD && o == null) {
             throw new IllegalStateException();
         }
     }
 
     public static void assertWorkerThread() {
-        if (ProviderConfig.IS_DOGFOOD_BUILD && !isSameLooper(LauncherModel.getWorkerLooper())) {
+        if (FeatureFlags.IS_DOGFOOD_BUILD && !isSameLooper(LauncherModel.getWorkerLooper())) {
             throw new IllegalStateException();
         }
     }
 
     public static void assertUIThread() {
-        if (ProviderConfig.IS_DOGFOOD_BUILD && !isSameLooper(Looper.getMainLooper())) {
+        if (FeatureFlags.IS_DOGFOOD_BUILD && !isSameLooper(Looper.getMainLooper())) {
             throw new IllegalStateException();
         }
     }
 
     public static void assertNonUiThread() {
-        if (ProviderConfig.IS_DOGFOOD_BUILD && isSameLooper(Looper.getMainLooper())) {
+        if (FeatureFlags.IS_DOGFOOD_BUILD && isSameLooper(Looper.getMainLooper())) {
             throw new IllegalStateException();
         }
     }
diff --git a/src/com/android/launcher3/util/SQLiteCacheHelper.java b/src/com/android/launcher3/util/SQLiteCacheHelper.java
index ef10f97..9084bfb 100644
--- a/src/com/android/launcher3/util/SQLiteCacheHelper.java
+++ b/src/com/android/launcher3/util/SQLiteCacheHelper.java
@@ -10,7 +10,7 @@
 import android.util.Log;
 
 import com.android.launcher3.Utilities;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.config.FeatureFlags;
 
 /**
  * An extension of {@link SQLiteOpenHelper} with utility methods for a single table cache DB.
@@ -19,7 +19,7 @@
 public abstract class SQLiteCacheHelper {
     private static final String TAG = "SQLiteCacheHelper";
 
-    private static final boolean NO_ICON_CACHE = ProviderConfig.IS_DOGFOOD_BUILD &&
+    private static final boolean NO_ICON_CACHE = FeatureFlags.IS_DOGFOOD_BUILD &&
             Utilities.isPropertyEnabled(LogConfig.MEMORY_ONLY_ICON_CACHE);
 
     private final String mTableName;
diff --git a/src/com/android/launcher3/util/TestingUtils.java b/src/com/android/launcher3/util/TestingUtils.java
index 665c371..a7cc42b 100644
--- a/src/com/android/launcher3/util/TestingUtils.java
+++ b/src/com/android/launcher3/util/TestingUtils.java
@@ -3,7 +3,6 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.SharedPreferences;
 import android.util.Log;
 import android.view.Gravity;
 import android.view.View;
@@ -11,7 +10,6 @@
 
 import com.android.launcher3.CustomAppWidget;
 import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index d863339..89597b9 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -20,7 +20,7 @@
 import android.content.res.TypedArray;
 import android.graphics.Color;
 import android.graphics.ColorMatrix;
-import android.view.ContextThemeWrapper;
+import android.graphics.drawable.Drawable;
 
 /**
  * Various utility methods associated with theming.
@@ -31,10 +31,6 @@
         return getAttrColor(context, android.R.attr.colorAccent);
     }
 
-    public static int getColorPrimary(Context context, int theme) {
-        return getAttrColor(new ContextThemeWrapper(context, theme), android.R.attr.colorPrimary);
-    }
-
     public static int getAttrColor(Context context, int attr) {
         TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
         int colorAccent = ta.getColor(0, 0);
@@ -42,6 +38,20 @@
         return colorAccent;
     }
 
+    public static boolean getAttrBoolean(Context context, int attr) {
+        TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
+        boolean value = ta.getBoolean(0, false);
+        ta.recycle();
+        return value;
+    }
+
+    public static Drawable getAttrDrawable(Context context, int attr) {
+        TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
+        Drawable value = ta.getDrawable(0);
+        ta.recycle();
+        return value;
+    }
+
     /**
      * Returns the alpha corresponding to the theme attribute {@param attr}, in the range [0, 255].
      */
diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
index 9bd2882..4cb6ca8 100644
--- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java
+++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
@@ -16,12 +16,10 @@
 
 package com.android.launcher3.util;
 
-import android.util.Log;
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewTreeObserver.OnDrawListener;
 
-import com.android.launcher3.DeferredHandler;
 import com.android.launcher3.Launcher;
 
 import java.util.ArrayList;
@@ -34,7 +32,7 @@
         OnAttachStateChangeListener {
 
     private final ArrayList<Runnable> mTasks = new ArrayList<>();
-    private final DeferredHandler mHandler;
+    private final Executor mExecutor;
 
     private Launcher mLauncher;
     private View mAttachedView;
@@ -43,8 +41,8 @@
     private boolean mLoadAnimationCompleted;
     private boolean mFirstDrawCompleted;
 
-    public ViewOnDrawExecutor(DeferredHandler handler) {
-        mHandler = handler;
+    public ViewOnDrawExecutor(Executor executor) {
+        mExecutor = executor;
     }
 
     public void attachTo(Launcher launcher) {
@@ -92,7 +90,7 @@
         // Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
         if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
             for (final Runnable r : mTasks) {
-                mHandler.post(r);
+                mExecutor.execute(r);
             }
             markCompleted();
         }
diff --git a/src/com/android/launcher3/widget/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
index e0a80c6..f47ca3eeb 100644
--- a/src/com/android/launcher3/widget/WidgetsRecyclerView.java
+++ b/src/com/android/launcher3/widget/WidgetsRecyclerView.java
@@ -21,9 +21,8 @@
 import android.support.v7.widget.LinearLayoutManager;
 import android.util.AttributeSet;
 import android.view.View;
+
 import com.android.launcher3.BaseRecyclerView;
-import com.android.launcher3.model.PackageItemInfo;
-import com.android.launcher3.model.WidgetsModel;
 
 /**
  * The widgets recycler view.
diff --git a/src_config/com/android/launcher3/config/ProviderConfig.java b/src_config/com/android/launcher3/BuildConfig.java
similarity index 67%
rename from src_config/com/android/launcher3/config/ProviderConfig.java
rename to src_config/com/android/launcher3/BuildConfig.java
index 491fa65..4df75a1 100644
--- a/src_config/com/android/launcher3/config/ProviderConfig.java
+++ b/src_config/com/android/launcher3/BuildConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 The Android Open Source Project
+ * 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.
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.launcher3.config;
+package com.android.launcher3;
 
-public class ProviderConfig {
-
-    public static final String AUTHORITY = "com.android.launcher3.settings".intern();
-
-    public static final boolean IS_DOGFOOD_BUILD = true;
+/**
+ * Config file used by Make. This file is automatically generated when using gradle.
+ */
+public class BuildConfig {
+    public static final String APPLICATION_ID = "com.android.launcher3";
 }
diff --git a/src_config/com/android/launcher3/config/FeatureFlags.java b/src_flags/com/android/launcher3/config/FeatureFlags.java
similarity index 76%
rename from src_config/com/android/launcher3/config/FeatureFlags.java
rename to src_flags/com/android/launcher3/config/FeatureFlags.java
index 4e337a2..ed169b6 100644
--- a/src_config/com/android/launcher3/config/FeatureFlags.java
+++ b/src_flags/com/android/launcher3/config/FeatureFlags.java
@@ -20,6 +20,9 @@
  * Defines a set of flags used to control various launcher behaviors
  */
 public final class FeatureFlags {
+
+    public static final boolean IS_DOGFOOD_BUILD = true;
+
     private FeatureFlags() {}
 
     // Custom flags go below this
@@ -28,12 +31,17 @@
     public static boolean LAUNCHER3_USE_SYSTEM_DRAG_DRIVER = true;
     public static boolean LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW = false;
     public static boolean LAUNCHER3_ALL_APPS_PULL_UP = true;
-    public static boolean LAUNCHER3_NEW_FOLDER_ANIMATION = false;
+    public static boolean LAUNCHER3_NEW_FOLDER_ANIMATION = true;
     // When enabled allows to use any point on the fast scrollbar to start dragging.
     public static boolean LAUNCHER3_DIRECT_SCROLL = true;
     // When enabled while all-apps open, the soft input will be set to adjust resize .
-    public static boolean LAUNCHER3_UPDATE_SOFT_INPUT_MODE = false;
-
+    public static boolean LAUNCHER3_UPDATE_SOFT_INPUT_MODE = true;
+    // When enabled the promise icon is visible in all apps while installation an app.
+    public static boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = true;
+    // When enabled uses the AllAppsRadialGradientAndScrimDrawable for all apps
+    public static boolean LAUNCHER3_GRADIENT_ALL_APPS = true;
+    // When enabled allows use of physics based motions in the Launcher.
+    public static boolean LAUNCHER3_PHYSICS = true;
 
     // Feature flag to enable moving the QSB on the 0th screen of the workspace.
     public static final boolean QSB_ON_FIRST_SCREEN = true;
@@ -45,10 +53,12 @@
     public static final boolean LIGHT_STATUS_BAR = false;
     // When enabled icons are badged with the number of notifications associated with that app.
     public static final boolean BADGE_ICONS = true;
-    // When enabled, icons not supporting {@link AdaptiveIconDrawable} will be wrapped in this class.
+    // When enabled, icons not supporting {@link AdaptiveIconDrawable} will be wrapped in {@link FixedScaleDrawable}.
     public static final boolean LEGACY_ICON_TREATMENT = true;
     // When enabled, adaptive icons would have shadows baked when being stored to icon cache.
     public static final boolean ADAPTIVE_ICON_SHADOW = true;
     // When enabled, app discovery will be enabled if service is implemented
     public static final boolean DISCOVERY_ENABLED = false;
+    // When enabled, the qsb will be moved to the hotseat.
+    public static final boolean QSB_IN_HOTSEAT = true;
 }
diff --git a/tests/res/raw/db_schema_v10.json b/tests/res/raw/db_schema_v10.json
new file mode 100644
index 0000000..a5e290e
--- /dev/null
+++ b/tests/res/raw/db_schema_v10.json
@@ -0,0 +1,4 @@
+{
+  "version" : 10,
+  "downgrade_to_9" : []
+}
\ No newline at end of file
diff --git a/tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
similarity index 98%
rename from tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java
rename to tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
index 18570de..20b23b0 100644
--- a/tests/src/com/android/launcher3/allapps/DefaultAppSearchAlgorithmTest.java
+++ b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.launcher3.allapps;
+package com.android.launcher3.allapps.search;
 
 import android.content.ComponentName;
 import android.test.InstrumentationTestCase;
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
index d0ba907..4c80902 100644
--- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
+++ b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
@@ -10,9 +10,9 @@
 import android.util.Pair;
 
 import com.android.launcher3.ItemInfo;
+import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.ShortcutInfo;
-import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.util.GridOccupancy;
 import com.android.launcher3.util.LongArrayMap;
 import com.android.launcher3.util.Provider;
@@ -21,6 +21,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.verify;
@@ -50,7 +51,11 @@
     }
 
     private AddWorkspaceItemsTask newTask(ItemInfo... items) {
-        return new AddWorkspaceItemsTask(Provider.of(Arrays.asList(items))) {
+        List<Pair<ItemInfo, Object>> list = new ArrayList<>();
+        for (ItemInfo item : items) {
+            list.add(Pair.create(item, null));
+        }
+        return new AddWorkspaceItemsTask(Provider.of(list)) {
 
             @Override
             protected void updateScreens(Context context, ArrayList<Long> workspaceScreens) { }
@@ -178,6 +183,6 @@
             v.put(LauncherSettings.WorkspaceScreens.SCREEN_RANK, i);
             ops.add(ContentProviderOperation.newInsert(uri).withValues(v).build());
         }
-        getMockContentResolver().applyBatch(ProviderConfig.AUTHORITY, ops);
+        getMockContentResolver().applyBatch(LauncherProvider.AUTHORITY, ops);
     }
 }
diff --git a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java b/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
index b9944db..13e0986 100644
--- a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
+++ b/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
@@ -16,7 +16,6 @@
 import com.android.launcher3.AllAppsList;
 import com.android.launcher3.AppFilter;
 import com.android.launcher3.AppInfo;
-import com.android.launcher3.DeferredHandler;
 import com.android.launcher3.IconCache;
 import com.android.launcher3.InvariantDeviceProfile;
 import com.android.launcher3.ItemInfo;
@@ -24,7 +23,7 @@
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherModel.BaseModelUpdateTask;
 import com.android.launcher3.LauncherModel.Callbacks;
-import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.LauncherProvider;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.Provider;
 import com.android.launcher3.util.TestLauncherProvider;
@@ -36,6 +35,7 @@
 import java.lang.reflect.Field;
 import java.util.HashMap;
 import java.util.List;
+import java.util.concurrent.Executor;
 
 import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Mockito.atLeast;
@@ -64,7 +64,7 @@
     public Callbacks callbacks;
 
     public BaseModelUpdateTaskTestCase() {
-        super(TestLauncherProvider.class, ProviderConfig.AUTHORITY);
+        super(TestLauncherProvider.class, LauncherProvider.AUTHORITY);
     }
 
     @Override
@@ -102,14 +102,14 @@
         f.setAccessible(true);
         f.set(task, mockModel);
 
-        DeferredHandler mockHandler = mock(DeferredHandler.class);
-        f = BaseModelUpdateTask.class.getDeclaredField("mUiHandler");
+        Executor mockExecutor = mock(Executor.class);
+        f = BaseModelUpdateTask.class.getDeclaredField("mUiExecutor");
         f.setAccessible(true);
-        f.set(task, mockHandler);
+        f.set(task, mockExecutor);
 
         task.execute(appState, bgDataModel, allAppsList);
         ArgumentCaptor<Runnable> captor = ArgumentCaptor.forClass(Runnable.class);
-        verify(mockHandler, atLeast(0)).post(captor.capture());
+        verify(mockExecutor, atLeast(0)).execute(captor.capture());
 
         return captor.getAllValues();
     }
diff --git a/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java b/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
new file mode 100644
index 0000000..1d9148b
--- /dev/null
+++ b/tests/src/com/android/launcher3/model/DbDowngradeHelperTest.java
@@ -0,0 +1,194 @@
+/*
+ * 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 static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotSame;
+import static junit.framework.Assert.assertTrue;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.launcher3.LauncherProvider;
+import com.android.launcher3.LauncherProvider.DatabaseHelper;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.R;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.File;
+
+/**
+ * Tests for {@link DbDowngradeHelper}
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DbDowngradeHelperTest {
+
+    private static final String SCHEMA_FILE = "test_schema.json";
+    private static final String DB_FILE = "test.db";
+
+    private Context mContext;
+    private File mSchemaFile;
+    private File mDbFile;
+
+    @Before
+    public void setup() {
+        mContext = InstrumentationRegistry.getTargetContext();
+        mSchemaFile = mContext.getFileStreamPath(SCHEMA_FILE);
+        mDbFile = mContext.getDatabasePath(DB_FILE);
+    }
+
+    @Test
+    public void testUpdateSchemaFile() throws Exception {
+        Context myContext = InstrumentationRegistry.getContext();
+        int testResId = myContext.getResources().getIdentifier(
+                "db_schema_v10", "raw", myContext.getPackageName());
+        mSchemaFile.delete();
+        assertFalse(mSchemaFile.exists());
+
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, myContext, testResId);
+        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);
+        assertNotSame(0, mSchemaFile.lastModified());
+
+        // Schema is not updated when version is same
+        assertTrue(mSchemaFile.setLastModified(0));
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 10, myContext, testResId);
+        assertEquals(0, mSchemaFile.lastModified());
+
+        // Schema is not updated on version downgrade
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, 3, myContext, testResId);
+        assertEquals(0, mSchemaFile.lastModified());
+    }
+
+    @Test
+    public void testDowngrade_success_v24() throws Exception {
+        setupTestDb();
+
+        TestOpenHelper helper = new TestOpenHelper(24);
+        assertEquals(24, helper.getReadableDatabase().getVersion());
+        helper.close();
+    }
+
+    @Test
+    public void testDowngrade_success_v22() throws Exception {
+        setupTestDb();
+
+        SQLiteOpenHelper helper = new TestOpenHelper(22);
+        assertEquals(22, helper.getWritableDatabase().getVersion());
+
+        // Check column does not exist
+        try (Cursor c = helper.getWritableDatabase().query(Favorites.TABLE_NAME,
+                null, null, null, null, null, null)) {
+            assertEquals(-1, c.getColumnIndex(Favorites.OPTIONS));
+
+            // Check data is present
+            assertEquals(10, c.getCount());
+        }
+        helper.close();
+
+        helper = new DatabaseHelper(mContext, null, DB_FILE) {
+            @Override
+            public void onOpen(SQLiteDatabase db) { }
+        };
+        assertEquals(LauncherProvider.SCHEMA_VERSION, helper.getWritableDatabase().getVersion());
+
+        try (Cursor c = helper.getWritableDatabase().query(Favorites.TABLE_NAME,
+                null, null, null, null, null, null)) {
+            // Check column exists
+            assertNotSame(-1, c.getColumnIndex(Favorites.OPTIONS));
+
+            // Check data is present
+            assertEquals(10, c.getCount());
+        }
+        helper.close();
+    }
+
+    @Test(expected = DowngradeFailException.class)
+    public void testDowngrade_fail_v20() throws Exception {
+        setupTestDb();
+
+        TestOpenHelper helper = new TestOpenHelper(20);
+        helper.getReadableDatabase().getVersion();
+    }
+
+    private void setupTestDb() throws Exception {
+        mSchemaFile.delete();
+        mDbFile.delete();
+
+        DbDowngradeHelper.updateSchemaFile(mSchemaFile, LauncherProvider.SCHEMA_VERSION, mContext,
+                R.raw.downgrade_schema);
+
+        DatabaseHelper dbHelper = new DatabaseHelper(mContext, null, DB_FILE) {
+            @Override
+            public void onOpen(SQLiteDatabase db) { }
+        };
+        // Insert dummy data
+        for (int i = 0; i < 10; i++) {
+            ContentValues values = new ContentValues();
+            values.put(Favorites._ID, i);
+            values.put(Favorites.TITLE, "title " + i);
+            dbHelper.getWritableDatabase().insert(Favorites.TABLE_NAME, null, values);
+        }
+        dbHelper.close();
+    }
+
+    private class TestOpenHelper extends SQLiteOpenHelper {
+
+        public TestOpenHelper(int version) {
+            super(mContext, DB_FILE, null, version);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase sqLiteDatabase) {
+            throw new RuntimeException("DB should already be created");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            throw new RuntimeException("Only downgrade supported");
+        }
+
+        @Override
+        public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            try {
+                DbDowngradeHelper.parse(mSchemaFile).onDowngrade(db, oldVersion, newVersion);
+            } catch (Exception e) {
+                throw new DowngradeFailException(e);
+            }
+        }
+    }
+
+    private static class DowngradeFailException extends RuntimeException {
+        public DowngradeFailException(Exception e) {
+            super(e);
+        }
+    }
+}
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
index fc7fe48..fd62d36 100644
--- a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
+++ b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
@@ -1,7 +1,6 @@
 package com.android.launcher3.model;
 
 import android.content.ContentValues;
-import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
 import android.graphics.Point;
@@ -10,9 +9,9 @@
 
 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.FeatureFlags;
-import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.model.GridSizeMigrationTask.MultiStepMigrationTask;
 import com.android.launcher3.util.TestLauncherProvider;
 
@@ -40,7 +39,7 @@
     private InvariantDeviceProfile mIdp;
 
     public GridSizeMigrationTaskTest() {
-        super(TestLauncherProvider.class, ProviderConfig.AUTHORITY);
+        super(TestLauncherProvider.class, LauncherProvider.AUTHORITY);
     }
 
     @Override
diff --git a/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java b/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
index d655562..ed893c4 100644
--- a/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
+++ b/tests/src/com/android/launcher3/model/PackageInstallStateChangedTaskTest.java
@@ -21,9 +21,8 @@
     }
 
     private PackageInstallStateChangedTask newTask(String pkg, int progress) {
-        PackageInstallInfo installInfo = new PackageInstallInfo(pkg);
-        installInfo.progress = progress;
-        installInfo.state = PackageInstallerCompat.STATUS_INSTALLING;
+        int state = PackageInstallerCompat.STATUS_INSTALLING;
+        PackageInstallInfo installInfo = new PackageInstallInfo(pkg, state, progress);
         return new PackageInstallStateChangedTask(installInfo);
     }
 
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index df2b662..97f7b50 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -39,13 +39,12 @@
 import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.ui.LauncherInstrumentationTestCase;
 import com.android.launcher3.util.ContentWriter;
-import com.android.launcher3.util.LooperExecuter;
+import com.android.launcher3.util.LooperExecutor;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
 import com.android.launcher3.widget.WidgetHostViewLoader;
 
 import java.util.Set;
 import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -340,7 +339,7 @@
      * Blocks the current thread until all the jobs in the main worker thread are complete.
      */
     private void waitUntilLoaderIdle() throws Exception {
-        new LooperExecuter(LauncherModel.getWorkerLooper())
+        new LooperExecutor(LauncherModel.getWorkerLooper())
                 .submit(new Runnable() {
                     @Override
                     public void run() { }