Empty commit to trigger a build.
am: 8dfc049598

Change-Id: Ic3dae2d96ac6dac123392c4d232e1362f3206a32
diff --git a/AndroidManifest-common.xml b/AndroidManifest-common.xml
index 23ea195..86ae73e 100644
--- a/AndroidManifest-common.xml
+++ b/AndroidManifest-common.xml
@@ -76,6 +76,14 @@
             android:process=":wallpaper_chooser">
         </service>
 
+        <service android:name="com.android.launcher3.notification.NotificationListener"
+                 android:enabled="@bool/notification_badging_enabled"
+                 android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
+            <intent-filter>
+                <action android:name="android.service.notification.NotificationListenerService" />
+            </intent-filter>
+        </service>
+
         <meta-data android:name="android.nfc.disable_beam_default"
                        android:value="true" />
 
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6c5990d..418b3a3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -56,6 +56,7 @@
         android:hardwareAccelerated="true"
         android:icon="@mipmap/ic_launcher_home"
         android:label="@string/derived_app_name"
+        android:theme="@style/LauncherTheme"
         android:largeHeap="@bool/config_largeHeap"
         android:restoreAnyVersion="true"
         android:supportsRtl="true" >
@@ -69,7 +70,6 @@
             android:launchMode="singleTask"
             android:clearTaskOnLaunch="true"
             android:stateNotNeeded="true"
-            android:theme="@style/LauncherTheme"
             android:windowSoftInputMode="adjustPan"
             android:screenOrientation="nosensor"
             android:configChanges="keyboard|keyboardHidden|navigation"
@@ -90,6 +90,7 @@
         <activity
             android:name="com.android.launcher3.SettingsActivity"
             android:label="@string/settings_button_text"
+            android:theme="@android:style/Theme.DeviceDefault.Settings"
             android:autoRemoveFromRecents="true">
             <intent-filter>
                 <action android:name="android.intent.action.APPLICATION_PREFERENCES" />
diff --git a/res/drawable/all_apps_divider.xml b/res/drawable/all_apps_divider.xml
index 3fe5295..4bd274d 100644
--- a/res/drawable/all_apps_divider.xml
+++ b/res/drawable/all_apps_divider.xml
@@ -15,6 +15,6 @@
 -->
 <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
-    <solid android:color="@color/all_apps_divider_color" />
+    <solid android:color="?android:attr/colorControlHighlight" />
     <size android:height="1dp" />
 </shape>
\ No newline at end of file
diff --git a/res/drawable/all_apps_search_hint.xml b/res/drawable/all_apps_search_hint.xml
index 36a0f03..b2ff7a4 100644
--- a/res/drawable/all_apps_search_hint.xml
+++ b/res/drawable/all_apps_search_hint.xml
@@ -15,6 +15,6 @@
      limitations under the License.
 -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:color="#00FFFFFF" android:state_focused="true" />
+    <item android:color="@android:color/transparent" android:state_focused="true" />
     <item android:color="?android:attr/colorAccent"/>
 </selector>
\ No newline at end of file
diff --git a/res/drawable/bg_pill_focused.xml b/res/drawable/bg_pill_focused.xml
index 37afad0..54075d9 100644
--- a/res/drawable/bg_pill_focused.xml
+++ b/res/drawable/bg_pill_focused.xml
@@ -16,9 +16,8 @@
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:state_focused="true">
-        <shape xmlns:android="http://schemas.android.com/apk/res/android"
-               android:shape="rectangle">
-            <stroke android:color="#616161" android:width="2dp"/>
+        <shape android:shape="rectangle">
+            <stroke android:color="?android:attr/colorControlActivated" android:width="2dp" />
             <corners android:radius="@dimen/bg_pill_radius" />
         </shape>
     </item>
diff --git a/res/drawable/deep_shortcuts_drag_handle.xml b/res/drawable/deep_shortcuts_drag_handle.xml
index 99d2b07..82e844d 100644
--- a/res/drawable/deep_shortcuts_drag_handle.xml
+++ b/res/drawable/deep_shortcuts_drag_handle.xml
@@ -18,9 +18,10 @@
         android:width="@dimen/deep_shortcut_drag_handle_size"
         android:height="@dimen/deep_shortcut_drag_handle_size"
         android:viewportWidth="24.0"
-        android:viewportHeight="24.0">
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/textColorHint" >
 
     <path
         android:pathData="M20 9H4v2h16V9zM4 15h16v-2H4v2z"
-        android:fillColor="#4D000000"/>
+        android:fillColor="@android:color/white" />
 </vector>
\ No newline at end of file
diff --git a/res/drawable/ic_setting.xml b/res/drawable/ic_setting.xml
index 8a50c0c..e89c158 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="#FFFFFFFF"
+        android:fillColor="@color/workspace_icon_text_color"
         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_wallpaper.xml b/res/drawable/ic_wallpaper.xml
index 7af4b2a..b7fcfbf 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="#FFFFFFFF"
+        android:fillColor="@color/workspace_icon_text_color"
         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 3e7bd7b..97706e3 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="#FFFFFFFF"
+        android:fillColor="@color/workspace_icon_text_color"
         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/drawable/quantum_panel.xml b/res/drawable/quantum_panel.xml
deleted file mode 100644
index fda1003..0000000
--- a/res/drawable/quantum_panel.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
-       android:drawable="@drawable/quantum_panel_shape"
-       android:insetBottom="@dimen/quantum_panel_outer_padding"
-       android:insetLeft="@dimen/quantum_panel_outer_padding"
-       android:insetRight="@dimen/quantum_panel_outer_padding"
-       android:insetTop="@dimen/quantum_panel_outer_padding" />
diff --git a/res/drawable/quantum_panel_shape.xml b/res/drawable/quantum_panel_shape.xml
deleted file mode 100644
index 1083615..0000000
--- a/res/drawable/quantum_panel_shape.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-     Copyright (C) 2015 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<shape xmlns:android="http://schemas.android.com/apk/res/android"
-       android:shape="rectangle">
-    <solid android:color="@color/quantum_panel_bg_color" />
-    <corners
-        android:radius="2dp" />
-</shape>
\ No newline at end of file
diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml
index 5f5b38b..d6bdac2 100644
--- a/res/layout/all_apps.xml
+++ b/res/layout/all_apps.xml
@@ -22,7 +22,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
-    launcher:revealBackground="@drawable/quantum_panel_shape">
+    launcher:revealBackground="@drawable/round_rect_primary">
 
     <View
         android:id="@+id/reveal_view"
@@ -54,8 +54,7 @@
             android:descendantFocusability="afterDescendants"
             android:focusable="true"
             android:paddingStart="@dimen/container_fastscroll_thumb_max_width"
-            android:paddingEnd="@dimen/container_fastscroll_thumb_max_width"
-            android:theme="@style/AllAppsOverscroll" />
+            android:paddingEnd="@dimen/container_fastscroll_thumb_max_width" />
 
         <!-- Fast scroller popup -->
         <TextView
@@ -87,7 +86,7 @@
                 android:maxLines="1"
                 android:scrollHorizontally="true"
                 android:singleLine="true"
-                android:textColor="#4c4c4c"
+                android:textColor="?android:attr/textColorSecondary"
                 android:hint="@string/all_apps_search_bar_hint"
                 android:textColorHint="@drawable/all_apps_search_hint"
                 android:textSize="16sp" />
@@ -95,11 +94,11 @@
 
     </com.android.launcher3.allapps.AllAppsRecyclerViewContainerView>
     <View
+        style="@style/AllAppsNavBarProtection"
         android:id="@+id/nav_bar_bg"
         android:layout_width="match_parent"
         android:layout_height="0dp"
         android:layout_gravity="bottom"
-        android:background="@color/all_apps_navbar_color"
         android:focusable="false"
         android:visibility="invisible" />
 </com.android.launcher3.allapps.AllAppsContainerView>
\ No newline at end of file
diff --git a/res/layout/all_apps_button.xml b/res/layout/all_apps_button.xml
index 68cc109..4bc780a 100644
--- a/res/layout/all_apps_button.xml
+++ b/res/layout/all_apps_button.xml
@@ -14,6 +14,4 @@
      limitations under the License.
 -->
 
-<TextView xmlns:android="http://schemas.android.com/apk/res/android"
-   style="@style/Icon"
-   android:focusable="true" />
+<TextView style="@style/BaseIcon" />
diff --git a/res/layout/all_apps_empty_search.xml b/res/layout/all_apps_empty_search.xml
index e1635d6..463adac 100644
--- a/res/layout/all_apps_empty_search.xml
+++ b/res/layout/all_apps_empty_search.xml
@@ -25,7 +25,6 @@
     android:paddingRight="16dp"
     android:fontFamily="sans-serif-medium"
     android:textSize="14sp"
-    android:textColor="#212121"
-    android:alpha="0.56"
+    android:textColor="?android:attr/textColorTertiary"
     android:focusable="false" />
 
diff --git a/res/layout/all_apps_icon.xml b/res/layout/all_apps_icon.xml
index 3d4bef7..1e83041 100644
--- a/res/layout/all_apps_icon.xml
+++ b/res/layout/all_apps_icon.xml
@@ -16,12 +16,13 @@
 <com.android.launcher3.BubbleTextView
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
-    style="@style/Icon.AllApps"
+    style="@style/BaseIcon"
     android:id="@+id/icon"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:layout_gravity="center"
-    android:focusable="true"
     launcher:iconDisplay="all_apps"
-    launcher:centerVertically="true" />
+    launcher:centerVertically="true"
+    android:paddingLeft="4dp"
+    android:paddingRight="4dp"
+    android:drawablePadding="@dimen/dynamic_grid_icon_drawable_padding" />
 
diff --git a/res/layout/app_icon.xml b/res/layout/app_icon.xml
index 831cee5..fa6eb89 100644
--- a/res/layout/app_icon.xml
+++ b/res/layout/app_icon.xml
@@ -14,6 +14,4 @@
      limitations under the License.
 -->
 
-<com.android.launcher3.BubbleTextView xmlns:android="http://schemas.android.com/apk/res/android"
-   style="@style/Icon"
-   android:focusable="true" />
+<com.android.launcher3.BubbleTextView style="@style/BaseIcon.Workspace" />
diff --git a/res/layout/deep_shortcut.xml b/res/layout/deep_shortcut.xml
index 1f67682..6c1d4da 100644
--- a/res/layout/deep_shortcut.xml
+++ b/res/layout/deep_shortcut.xml
@@ -16,18 +16,28 @@
 
 <com.android.launcher3.shortcuts.DeepShortcutView
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="@dimen/bg_pill_width"
     android:layout_height="@dimen/bg_pill_height"
     android:elevation="@dimen/deep_shortcuts_elevation"
-    android:background="@drawable/bg_white_pill">
+    android:background="@drawable/bg_white_pill" >
 
-<com.android.launcher3.shortcuts.DeepShortcutTextView
+    <com.android.launcher3.shortcuts.DeepShortcutTextView
+        style="@style/BaseIcon"
         android:id="@+id/deep_shortcut"
-        style="@style/Icon.DeepShortcut"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:focusable="true"
-        android:background="@drawable/bg_pill_focused" />
+        android:background="@drawable/bg_pill_focused"
+        android:gravity="start|center_vertical"
+        android:textAlignment="viewStart"
+        android:paddingStart="@dimen/bg_pill_height"
+        android:paddingEnd="@dimen/deep_shortcut_padding_end"
+        android:drawableEnd="@drawable/deep_shortcuts_drag_handle"
+        android:drawablePadding="@dimen/deep_shortcut_drawable_padding"
+        android:textSize="14sp"
+        android:fontFamily="sans-serif"
+        launcher:layoutHorizontal="true"
+        launcher:iconDisplay="shortcut_popup"
+        launcher:iconSizeOverride="@dimen/deep_shortcut_icon_size"
+        android:elevation="@dimen/deep_shortcuts_elevation" />
 
     <View
         android:id="@+id/popup_item_icon"
diff --git a/res/layout/folder_application.xml b/res/layout/folder_application.xml
index 4d00331..de861a0 100644
--- a/res/layout/folder_application.xml
+++ b/res/layout/folder_application.xml
@@ -14,6 +14,9 @@
      limitations under the License.
 -->
 
-<com.android.launcher3.BubbleTextView xmlns:android="http://schemas.android.com/apk/res/android"
-   style="@style/Icon.Folder"
-   android:focusable="true" />
+<com.android.launcher3.BubbleTextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    style="@style/BaseIcon"
+    android:includeFontPadding="false"
+    launcher:iconDisplay="folder" />
diff --git a/res/layout/folder_icon.xml b/res/layout/folder_icon.xml
index 9eb8c9a..ccc6b01 100644
--- a/res/layout/folder_icon.xml
+++ b/res/layout/folder_icon.xml
@@ -21,8 +21,9 @@
     android:orientation="vertical"
     android:focusable="true" >
     <com.android.launcher3.BubbleTextView
-        style="@style/Icon"
+        style="@style/BaseIcon.Workspace"
         android:id="@+id/folder_icon_name"
+        android:focusable="false"
         android:layout_gravity="top"
         android:layout_width="match_parent"
         android:layout_height="match_parent" />
diff --git a/res/layout/notification_main.xml b/res/layout/notification_main.xml
index efb74b0..84827f1 100644
--- a/res/layout/notification_main.xml
+++ b/res/layout/notification_main.xml
@@ -21,7 +21,6 @@
     android:layout_height="match_parent"
     android:orientation="horizontal"
     android:focusable="true"
-    android:background="@drawable/bg_pill_focused"
     android:elevation="@dimen/notification_elevation" >
 
     <View
@@ -39,13 +38,20 @@
         android:gravity="center_vertical">
         <TextView
             android:id="@+id/title"
-            style="@style/Icon.DeepNotification"
+            android:textAlignment="viewStart"
+            android:fontFamily="sans-serif"
+            android:textSize="14sp"
+            android:textColor="?android:attr/textColorSecondary"
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
 
         <TextView
             android:id="@+id/text"
-            style="@style/Icon.DeepNotification.SubText"
+            android:paddingEnd="4dp"
+            android:textSize="12sp"
+            android:textAlignment="viewStart"
+            android:fontFamily="sans-serif"
+            android:textColor="?android:attr/textColorTertiary"
             android:layout_width="match_parent"
             android:layout_height="wrap_content" />
     </LinearLayout>
diff --git a/res/layout/qsb_default_view.xml b/res/layout/qsb_default_view.xml
index 82bdea5..3075f80 100644
--- a/res/layout/qsb_default_view.xml
+++ b/res/layout/qsb_default_view.xml
@@ -23,7 +23,7 @@
         android:layout_height="48dp"
         android:layout_margin="16dp"
         android:layout_gravity="center_vertical"
-        android:background="@drawable/quantum_panel_shape"
+        android:background="@drawable/round_rect_primary"
         android:elevation="2dp"
         android:orientation="horizontal">
 
@@ -35,7 +35,7 @@
             android:gravity="center_vertical"
             android:paddingStart="16dp"
             android:text="@string/abandoned_search"
-            android:textColor="@color/quantum_panel_text_color"
+            android:textColor="?android:attr/textColorSecondary"
             android:textAppearance="?android:textAppearanceMedium"
             android:clickable="true"
             android:background="?android:attr/selectableItemBackground" />
@@ -46,7 +46,7 @@
             android:visibility="gone"
             android:layout_height="match_parent"
             android:src="@drawable/ic_setting"
-            android:tint="@color/quantum_panel_text_color"
+            android:tint="?android:attr/textColorSecondary"
             android:contentDescription="@string/gadget_setup_text"
             android:padding="8dp"
             android:background="?android:attr/selectableItemBackground" />
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index da2a861..cde6540 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -18,7 +18,7 @@
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:background="@drawable/quantum_panel"
+    android:background="@drawable/round_rect_primary"
     android:elevation="5dp"
     android:orientation="vertical" >
 
@@ -46,7 +46,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
             android:layout_weight="1"
-            android:background="#00000000"
+            android:background="@android:color/transparent"
             android:fontFamily="sans-serif-condensed"
             android:gravity="center_horizontal"
             android:hint="@string/folder_hint_text"
@@ -54,10 +54,10 @@
             android:paddingBottom="@dimen/folder_label_padding_bottom"
             android:paddingTop="@dimen/folder_label_padding_top"
             android:singleLine="true"
-            android:textColor="#ff777777"
+            android:textColor="?android:attr/textColorTertiary"
             android:includeFontPadding="false"
-            android:textColorHighlight="#ffCCCCCC"
-            android:textColorHint="#ff808080"
+            android:textColorHighlight="?android:attr/colorControlHighlight"
+            android:textColorHint="?android:attr/textColorHint"
             android:textSize="@dimen/folder_label_text_size" />
 
         <com.android.launcher3.pageindicators.PageIndicatorDots
diff --git a/res/layout/user_folder_icon_normalized.xml b/res/layout/user_folder_icon_normalized.xml
index a8af201..2063f32 100644
--- a/res/layout/user_folder_icon_normalized.xml
+++ b/res/layout/user_folder_icon_normalized.xml
@@ -18,7 +18,7 @@
     xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:background="@drawable/quantum_panel"
+    android:background="@drawable/round_rect_primary"
     android:elevation="5dp"
     android:orientation="vertical" >
 
@@ -46,7 +46,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
             android:layout_weight="1"
-            android:background="#00000000"
+            android:background="@android:color/transparent"
             android:fontFamily="sans-serif-condensed"
             android:textStyle="bold"
             android:gravity="center_horizontal"
@@ -55,9 +55,9 @@
             android:paddingBottom="@dimen/folder_label_padding_bottom"
             android:paddingTop="@dimen/folder_label_padding_top"
             android:singleLine="true"
-            android:textColor="#EE777777"
-            android:textColorHighlight="#ffCCCCCC"
-            android:textColorHint="#ff808080"
+            android:textColor="?android:attr/textColorTertiary"
+            android:textColorHighlight="?android:attr/colorControlHighlight"
+            android:textColorHint="?android:attr/textColorHint"
             android:textSize="@dimen/folder_label_text_size" />
 
         <com.android.launcher3.pageindicators.PageIndicatorDots
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index dd427e3..5fe2f1d 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dubbeltik en hou om \'n legstuk op te tel of gebruik gepasmaakte handelinge."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed by %2$d hoog"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Deursoek programme"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Laai tans programme …"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Geen programme gevind wat met \"<xliff:g id="QUERY">%1$s</xliff:g>\" ooreenstem nie"</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 02d5cc1..92f83ed 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 437e974..3862774 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-az-rAZ/strings.xml b/res/values-az-rAZ/strings.xml
index fe0ef4f..d38e4ed 100644
--- a/res/values-az-rAZ/strings.xml
+++ b/res/values-az-rAZ/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index bd7b874..8d16653 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dvaput dodirnite i zadržite da biste izabrali 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 od %1$d i visina od %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pretražite 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 za „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
diff --git a/res/values-be-rBY/strings.xml b/res/values-be-rBY/strings.xml
index b15dc60..f1b3aee 100644
--- a/res/values-be-rBY/strings.xml
+++ b/res/values-be-rBY/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 13d1641..4b9bba6 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index 6137f03..0d639a6 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-bs-rBA/strings.xml b/res/values-bs-rBA/strings.xml
index 705ca04..4a658d2 100644
--- a/res/values-bs-rBA/strings.xml
+++ b/res/values-bs-rBA/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index c12ec8d..36d18bf 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Fes doble toc i mantén premut per seleccionar un widget o per utilitzar les accions personalitzades."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d d\'amplada per %2$d d\'alçada"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Cerca a les aplicacions"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"S\'estan carregant les aplicacions..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"No s\'ha trobat cap aplicació que coincideixi amb <xliff:g id="QUERY">%1$s</xliff:g>"</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 8eacd0a..d34c22b 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dvojitým klepnutím a podržením vyberte widget, případně použijte vlastní akce."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"šířka %1$d, výška %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Hledat aplikace"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Načítání aplikací…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Dotazu „<xliff:g id="QUERY">%1$s</xliff:g>“ neodpovídají žádné aplikace"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 220bd4b..009750c 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tryk to gange, og hold fingeren nede for at vælge en widget eller bruge tilpassede handlinger."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i bredden og %2$d i højden"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Søg i Apps"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Indlæser apps…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Der blev ikke fundet nogen apps, som matcher \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 990c901..e28517b 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Zum Hinzufügen auf Widget doppeltippen und gedrückt halten oder benutzerdefinierte Aktionen verwenden."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breit und %2$d hoch"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"In Apps suchen"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Apps werden geladen..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Keine Apps für \"<xliff:g id="QUERY">%1$s</xliff:g>\" gefunden"</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index c82b7ee..00be6b3 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index baae4b0..15e3b47 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Double-tap &amp; hold to pick up a widget or use customised actions."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Search Apps"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Loading Apps…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"No Apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index baae4b0..15e3b47 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Double-tap &amp; hold to pick up a widget or use customised actions."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Search Apps"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Loading Apps…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"No Apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index baae4b0..15e3b47 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Double-tap &amp; hold to pick up a widget or use customised actions."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Search Apps"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Loading Apps…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"No Apps found matching \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 250f784..791cf98 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Presiona dos veces y mantén presionado para elegir un widget o usa una acción personalizada."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Buscar aplicaciones"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Cargando aplicaciones…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"No hay aplicaciones que coincidan con <xliff:g id="QUERY">%1$s</xliff:g>."</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 1fdf3ef..da229d6 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toca dos veces y mantén pulsado el widget que quieras seleccionar o utiliza acciones 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 ancho por %2$d de alto"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Busca aplicaciones"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Cargando aplicaciones…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index a0ee1e9..5b376cc 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index b2aed2e..f6062db 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 88a4fb5..5a29aae 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 0aa01b9..f0a1211 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Valitse widget tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla kohdetta pitkään."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Leveys: %1$d, korkeus: %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Sovellushaku"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Ladataan sovelluksia…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"”<xliff:g id="QUERY">%1$s</xliff:g>” ei palauttanut sovelluksia."</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index e261b74..6509f29 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Touchez 2x un widget et maintenez doigt dessus pour l’ajouter ou utiliser des actions personnalisées"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur sur %2$d de hauteur"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Rechercher des applications"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Chargement des applications en cours..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Aucune application trouvée correspondant à « <xliff:g id="QUERY">%1$s</xliff:g> »"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 591dff7..d3a15b1 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Appuyez 2 fois et maintenez la pression pour sélectionner widget ou utilisez actions personnalisées."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur et %2$d de hauteur"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Rechercher dans les applications"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Chargement des applications en cours…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Aucune application ne correspond à la requête \"<xliff:g id="QUERY">%1$s</xliff:g>\"."</string>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index 766cddb..b3e8a69 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-gu-rIN/strings.xml b/res/values-gu-rIN/strings.xml
index c14816a..d61df90 100644
--- a/res/values-gu-rIN/strings.xml
+++ b/res/values-gu-rIN/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 5534768..900ebb0 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index ce370f9..a74de33 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dodirnite dvaput i držite kako biste podigli widget ili pokušajte prilagođenim radnjama."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d širine i %2$d visine"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pretraži aplikacije"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Učitavanje aplikacija…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nema aplikacija podudarnih s upitom \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index c2003b6..6334433 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Modul mozgatásához koppintson rá duplán és tartsa lenyomva, vagy használjon egyéni műveleteket."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d széles és %2$d magas"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Alkalmazások keresése"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Alkalmazások betöltése…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Egy alkalmazás sem található a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre."</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 7884895..ea3b9dc 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 469c116..4c826ea 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Ketuk dua kalip &amp; tahan untuk mengambil widget atau menggunakan tindakan khusus."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"lebar %1$d x tinggi %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Telusuri Apps"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Memuat Aplikasi..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Tidak ditemukan Aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index f39628d..186c174 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index e4e1242..6b44c5b 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tocca due volte e tieni premuto per scegliere un widget o per utilizzare azioni personalizzate."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d di larghezza per %2$d di altezza"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Cerca app"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Caricamento di app…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index c04bf12..e28fb9f 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index ea9d381..fc058e4 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"ダブルタップ後に押し続けてウィジェットを選択するか、カスタム操作を使用してください。"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"幅 %1$d、高さ %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 7c41389..f2c480d 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index 7762cd7..1919ac1 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index 862a652..40f4702 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index 55fe36c..1c29c74 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 85b50c8..cede509 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 75700ce..8e02c3b 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 31b7db4..3d39ccf 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 1564d45..3f075fb 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dukart palieskite ir laikykite, kad pasirinktumėte valdiklį ar naudotumėte tinkintus veiksmus."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plotis ir %2$d aukštis"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Ieškoti programų"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Įkeliamos programos..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nerasta jokių užklausą „<xliff:g id="QUERY">%1$s</xliff:g>“ atitinkančių programų"</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 6458d0b..57f5f78 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Lai atlasītu logrīku, veiciet dubultskārienu uz tā un turiet to vai arī veiciet pielāgotas darbības."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plats un %2$d augsts"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Meklēt lietotnes"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Notiek lietotņu ielāde…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Vaicājumam “<xliff:g id="QUERY">%1$s</xliff:g>” neatbilda neviena lietotne."</string>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index 83da8a1..f82b39a 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index 0e8c313..d1185c1 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index d9efe5d..7b70aae 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index 5938b8e..c8e6377 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 63de9cb..45410f3 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index c65f3ab..e79ff88 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 38f027a..591c626 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dobbelttrykk og hold inne for å velge en modul eller bruke tilpassede handlinger."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bredde x %2$d høyde"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Søk i apper"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Laster inn apper …"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Fant ingen apper som samsvarer med «<xliff:g id="QUERY">%1$s</xliff:g>»"</string>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index c97eaa2..91b1e1b 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 90f4b9e..4223743 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Dubbeltik en blijf aanraken om een widget toe te voegen of aangepaste acties te gebruiken."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed en %2$d hoog"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Apps zoeken"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Apps laden…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Er zijn geen apps gevonden die overeenkomen met \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
diff --git a/res/values-pa-rIN/strings.xml b/res/values-pa-rIN/strings.xml
index 38769aa..c1192c5 100644
--- a/res/values-pa-rIN/strings.xml
+++ b/res/values-pa-rIN/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 1e2fc47..ed60ee3 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Kliknij dwukrotnie i przytrzymaj, by wybrać widżet lub użyć działań niestandardowych."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Szerokość %1$d, wysokość %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Szukaj w aplikacjach"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Wczytuję aplikacje…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nie znaleziono aplikacji pasujących do zapytania „<xliff:g id="QUERY">%1$s</xliff:g>”"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 000c7ad..37e16aa 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toque duas vezes sem soltar para escolher um widget ou utilize ações 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 largura por %2$d de altura"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pesquisar aplicações"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"A carregar aplicações..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Não foram encontradas aplic. que correspondam a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 9969997..b142e6c 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Toque duas vezes e segure para selecionar um widget ou usar ações 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 largura por %2$d de altura"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pesquisar apps"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Carregando apps…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 6faf57f..3d92993 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Atingeți de două ori și mențineți apăsat ca să alegeți un widget sau folosiți acțiuni personalizate."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lățime și %2$d înălțime"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Căutați aplicații"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Se încarcă aplicațiile..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nu s-a găsit nicio aplicație pentru „<xliff:g id="QUERY">%1$s</xliff:g>”"</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 7bc1819..0e2fc96 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Чтобы выбрать виджет, нажмите на него дважды и не отпускайте или выполните предложенные действия."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d, высота %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index 86f616e..5bfd10c 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index d0a2e59..cc95676 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Miniaplikáciu pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"šírka %1$d, výška %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Hľadať aplikácie"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Načítavajú sa aplikácie..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nenašli sa žiadne aplikácie zodpovedajúce dopytu <xliff:g id="QUERY">%1$s</xliff:g>"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 0682f8d..4bbefaa 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Če želite izbrati pripomoček ali uporabiti dejanja po meri, se ga dvakrat dotaknite in ga pridržite."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, višina %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Iskanje po aplikacijah"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Nalaganje aplikacij …"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Ni aplikacij, ki bi ustrezale poizvedbi »<xliff:g id="QUERY">%1$s</xliff:g>«"</string>
diff --git a/res/values-sq-rAL/strings.xml b/res/values-sq-rAL/strings.xml
index 701eaf8..2c6c8d6 100644
--- a/res/values-sq-rAL/strings.xml
+++ b/res/values-sq-rAL/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index a396f18..086b9fa 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index bedef80..255381a 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Tryck två gånger och håll kvar om du vill ta upp en widget eller använda anpassade åtgärder."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bred gånger %2$d hög"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Sök efter appar"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Läser in appar …"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Det gick inte att hitta några appar som matchar <xliff:g id="QUERY">%1$s</xliff:g>"</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 20654e0..76a1487 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Gonga mara mbili na ushikilie ile uchague wijeti au utumie vitendo maalum."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Upana wa %1$d na kimo cha %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Tafuta Programu"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Inapakia Programu..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Haikupata programu zinazolingana na \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index 674edaa..de809b1 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -25,6 +25,7 @@
         <item name="android:windowShowWallpaper">true</item>
         <item name="android:windowNoTitle">true</item>
         <item name="android:windowActionModeOverlay">true</item>
+        <item name="android:colorEdgeEffect">?android:attr/textColorSecondary</item>
     </style>
 
     <!-- Workspace -->
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index fd51b71..49658dd2 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index ba19ddc..f42309d 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 4bcda7a..ef67660 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -33,6 +33,10 @@
     <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 x สูง %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 55e02e9..50b0df3 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"I-double tap nang matagal upang pumili ng widget o gumamit ng mga custom na pagkilos."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ang lapad at %2$d ang taas"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Mga App sa Paghahanap"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Nilo-load ang Mga App…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Walang nakitang Mga App na tumutugma sa \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index f30b559..296de0f 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Bir widget\'ı seçmek veya özel işlemleri kullanmak için iki kez hafifçe dokunun ve basılı tutun."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"genişlik: %1$d, yükseklik: %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Uygulamalarda Ara"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Uygulamalar Yükleniyor…"</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ile eşleşen uygulama bulunamadı"</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 750b6a0..0d6c6bc 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index b285de0..e7a1af8 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index 77b7367..0f85353 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-v25/bools.xml b/res/values-v25/bools.xml
new file mode 100644
index 0000000..6f7ecd9
--- /dev/null
+++ b/res/values-v25/bools.xml
@@ -0,0 +1,22 @@
+<?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.
+*/
+-->
+
+<resources>
+    <!-- TODO(b/35443111): remove from v25 and keep in v26 -->
+    <bool name="notification_badging_enabled">true</bool>
+</resources>
\ No newline at end of file
diff --git a/res/values-v26/bools.xml b/res/values-v26/bools.xml
new file mode 100644
index 0000000..1093f78
--- /dev/null
+++ b/res/values-v26/bools.xml
@@ -0,0 +1,21 @@
+<?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.
+*/
+-->
+
+<resources>
+    <bool name="notification_badging_enabled">true</bool>
+</resources>
\ No newline at end of file
diff --git a/res/values-v26/styles.xml b/res/values-v26/styles.xml
index 6877623..cb18409 100644
--- a/res/values-v26/styles.xml
+++ b/res/values-v26/styles.xml
@@ -21,4 +21,11 @@
     <style name="WidgetContainerTheme" parent="@android:style/Theme.DeviceDefault.Settings">
         <item name="android:colorEdgeEffect">?android:attr/textColorSecondary</item>
     </style>
+
+    <!-- From O and above, we show a dark nav bar in all-apps -->
+    <style name="AllAppsNavBarProtection">
+        <item name="android:alpha">0.6</item>
+        <item name="android:background">?android:attr/colorPrimary</item>
+    </style>
+
 </resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 2d953e6..d83ba54 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Nhấn đúp và giữ để chọn tiện ích hoặc sử dụng tác vụ tùy chỉnh."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Rộng %1$d x cao %2$d"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Tìm kiếm ứng dụng"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Đang tải ứng dụng..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Không tìm thấy ứng dụng nào phù hợp với \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 7967812..c037948 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 236fc42..15a62e5 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 8d4c744..3d77283 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -33,6 +33,10 @@
     <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>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <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>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 88d4295..edbb64d 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -33,6 +33,10 @@
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"Thepha kabili bese uyabamba ukuze uthathe iwijethi noma sebenzisa izenzo ezingokwezifiso."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ububanzi ngokungu-%2$d ukuya phezulu"</string>
+    <!-- no translation found for add_item_request_drag_hint (8662194377800507270) -->
+    <skip />
+    <!-- no translation found for place_automatically (1502491650329146581) -->
+    <skip />
     <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Sesha Izinhlelo Zokusebenza"</string>
     <string name="all_apps_loading_message" msgid="7557140873644765180">"Ilayisha izinhlelo zokusebenza..."</string>
     <string name="all_apps_no_search_results" msgid="6332185285860416787">"Azikho izinhlelo zokusebenza ezitholakele ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
diff --git a/res/values/bools.xml b/res/values/bools.xml
new file mode 100644
index 0000000..cc4a7ba
--- /dev/null
+++ b/res/values/bools.xml
@@ -0,0 +1,21 @@
+<?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.
+*/
+-->
+
+<resources>
+    <bool name="notification_badging_enabled">false</bool>
+</resources>
\ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
index d166a79..a02df16 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -26,21 +26,11 @@
     <color name="focused_background">#80c6c5c5</color>
 
     <color name="workspace_icon_text_color">#FFF</color>
-
     <color name="workspace_edge_effect_color">#FFFFFFFF</color>
-    <color name="folder_edge_effect_color">#FF757575</color>
-    <color name="page_indicator_dot_color">#FFDDDDDD</color>
 
-    <color name="quantum_panel_text_color">#FF666666</color>
-    <color name="quantum_panel_bg_color">#FFF5F5F5</color>
+    <color name="default_shadow_color_no_alpha">#FF000000</color>
 
     <color name="outline_color">#FFFFFFFF</color>
-    <color name="all_apps_divider_color">#1E000000</color>
-    <color name="all_apps_caret_color">#FFFFFFFF</color>
-    <color name="all_apps_caret_shadow_color">#22000000</color>
-    <color name="all_apps_container_color">#FFF2F2F2</color>
-    <color name="all_apps_navbar_color">#28000000</color>
-    <color name="all_apps_light_navbar_color">#AAF2F2F2</color>
 
     <color name="spring_loaded_panel_color">#40FFFFFF</color>
     <color name="spring_loaded_highlighted_panel_border_color">#FFF</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 70f5b32..517bf9f 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -89,6 +89,7 @@
     <dimen name="widget_preview_key_shadow_distance">1dp</dimen>
     <dimen name="widget_preview_corner_radius">2dp</dimen>
     <dimen name="widget_preview_cell_divider_width">0.5dp</dimen>
+    <dimen name="widget_preview_shortcut_padding">8dp</dimen>
 
     <dimen name="widget_section_height">56dp</dimen>
     <dimen name="widget_section_icon_size">40dp</dimen>
@@ -120,9 +121,6 @@
 
     <dimen name="spring_loaded_panel_border">1dp</dimen>
 
-<!-- Theme -->
-    <dimen name="quantum_panel_outer_padding">4dp</dimen>
-
 <!-- Folders -->
     <!-- The size of the padding on the preview background drawable -->
     <dimen name="folder_preview_padding">6dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index a6f44f6..c1280c7 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -53,9 +53,9 @@
     <!-- Accessibility spoken message format for the dimensions of a widget in the drawer -->
     <string name="widget_accessible_dims_format">%1$d wide by %2$d high</string>
     <!-- Message to tell the user to press and hold a widget/icon to add it  -->
-    <string name="add_item_request_drag_hint" translatable="false">Touch &amp; hold to place on home screen</string>
+    <string name="add_item_request_drag_hint">Touch &amp; hold to place on home screen</string>
     <!-- Button label to automatically add icon on home screen [CHAR_LIMIT=50] -->
-    <string name="place_automatically" translatable="false">Place automatically</string>
+    <string name="place_automatically">Place automatically</string>
 
     <!-- All Apps -->
     <!-- Search bar text in the apps view. [CHAR_LIMIT=50] -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 879c7d8..8a46e83 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -24,11 +24,17 @@
         <item name="android:colorBackgroundCacheHint">@null</item>
         <item name="android:windowShowWallpaper">true</item>
         <item name="android:windowNoTitle">true</item>
+        <item name="android:colorEdgeEffect">#FF757575</item>
     </style>
 
     <style name="LauncherTheme" parent="@style/BaseLauncherTheme"></style>
 
-    <style name="Theme" parent="@style/LauncherTheme"></style>
+    <!-- Theme for the widget container. Overridden on API 26. -->
+    <style name="WidgetContainerTheme" parent="@android:style/Theme.DeviceDefault.Settings">
+        <item name="android:colorEdgeEffect">?android:attr/textColorSecondaryInverse</item>
+        <item name="android:textColorPrimary">?android:attr/textColorPrimaryInverse</item>
+        <item name="android:textColorSecondary">?android:attr/textColorSecondaryInverse</item>
+    </style>
 
     <style name="FastScrollerPopup" >
         <item name="android:background">@drawable/container_fastscroll_popup_bg</item>
@@ -44,88 +50,35 @@
         <item name="android:includeFontPadding">false</item>
     </style>
 
-    <!-- Theme for the widget container. Overridden on API 25. -->
-    <style name="WidgetContainerTheme" parent="@android:style/Theme.DeviceDefault.Settings">
-        <item name="android:colorEdgeEffect">@color/workspace_edge_effect_color</item>
-        <item name="android:textColorPrimary">?android:attr/textColorPrimaryInverse</item>
-        <item name="android:textColorSecondary">?android:attr/textColorSecondaryInverse</item>
+    <!-- Style for nav bar background in all-apps screen -->
+    <style name="AllAppsNavBarProtection">
+        <item name="android:alpha">?android:attr/spotShadowAlpha</item>
+        <item name="android:background">@color/default_shadow_color_no_alpha</item>
     </style>
 
-    <!-- Overscroll effect -->
-    <style name="AllAppsOverscroll" parent="@android:style/Theme.DeviceDefault.Light">
-        <item name="android:colorEdgeEffect">@color/folder_edge_effect_color</item>
-    </style>
-
-    <!-- Different icons -->
-    <style name="Icon">
+    <!-- Base theme for BubbleTextView and sub classes -->
+    <style name="BaseIcon">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">match_parent</item>
         <item name="android:layout_gravity">center</item>
+        <item name="android:focusable">true</item>
         <item name="android:gravity">center_horizontal</item>
         <item name="android:singleLine">true</item>
         <item name="android:ellipsize">marquee</item>
+        <item name="android:textColor">?android:attr/textColorSecondary</item>
+        <item name="android:fontFamily">sans-serif-condensed</item>
+
+        <!-- No shadows in the base theme -->
+        <item name="android:shadowRadius">0</item>
+        <item name="customShadows">false</item>
+    </style>
+
+    <!-- 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:fontFamily">sans-serif-condensed</item>
-    </style>
-
-    <style name="Icon.AllApps">
-        <item name="android:background">@null</item>
-        <item name="android:textColor">@color/quantum_panel_text_color</item>
-        <item name="android:drawablePadding">@dimen/dynamic_grid_icon_drawable_padding</item>
-        <item name="android:shadowRadius">0</item>
-        <item name="android:paddingLeft">4dp</item>
-        <item name="android:paddingRight">4dp</item>
-        <item name="customShadows">false</item>
-    </style>
-
-    <style name="Icon.Folder">
-        <item name="android:background">@null</item>
-        <item name="android:textColor">@color/quantum_panel_text_color</item>
-        <item name="android:shadowRadius">0</item>
-        <item name="android:gravity">center_horizontal</item>
-        <item name="android:includeFontPadding">false</item>
-        <item name="customShadows">false</item>
-        <item name="iconDisplay">folder</item>
-    </style>
-
-    <style name="Icon.DeepShortcut">
-        <item name="android:gravity">start|center_vertical</item>
-        <item name="android:textAlignment">viewStart</item>
-        <item name="android:elevation">@dimen/deep_shortcuts_elevation</item>
-        <item name="android:paddingStart">@dimen/bg_pill_height</item>
-        <item name="android:paddingEnd">@dimen/deep_shortcut_padding_end</item>
-        <item name="android:drawableEnd">@drawable/deep_shortcuts_drag_handle</item>
-        <item name="android:drawablePadding">@dimen/deep_shortcut_drawable_padding</item>
-        <item name="android:textColor">#FF212121</item>
-        <item name="android:textSize">14sp</item>
-        <item name="android:fontFamily">sans-serif</item>
-        <item name="android:shadowRadius">0</item>
-        <item name="customShadows">false</item>
-        <item name="layoutHorizontal">true</item>
-        <item name="iconDisplay">shortcut_popup</item>
-        <item name="iconSizeOverride">@dimen/deep_shortcut_icon_size</item>
-    </style>
-
-    <style name="Icon.DeepNotification">
-        <item name="android:gravity">start</item>
-        <item name="android:textAlignment">viewStart</item>
-        <item name="android:elevation">@dimen/deep_shortcuts_elevation</item>
-        <item name="android:textColor">#FF212121</item>
-        <item name="android:textSize">14sp</item>
-        <item name="android:fontFamily">sans-serif</item>
-        <item name="android:shadowRadius">0</item>
-        <item name="customShadows">false</item>
-        <item name="layoutHorizontal">true</item>
-        <item name="iconDisplay">shortcut_popup</item>
-        <item name="iconSizeOverride">@dimen/deep_shortcut_icon_size</item>
-    </style>
-
-    <style name="Icon.DeepNotification.SubText">
-        <item name="android:textColor">#FF757575</item>
-        <item name="android:textSize">12sp</item>
-        <item name="android:paddingEnd">4dp</item>
     </style>
 
     <!-- Drop targets -->
@@ -133,11 +86,11 @@
         <item name="android:drawablePadding">7.5dp</item>
         <item name="android:paddingLeft">16dp</item>
         <item name="android:paddingRight">16dp</item>
-        <item name="android:textColor">#FFFFFFFF</item>
+        <item name="android:textColor">@color/workspace_icon_text_color</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">#FF000000</item>
+        <item name="android:shadowColor">@color/default_shadow_color_no_alpha</item>
         <item name="android:shadowDx">0.0</item>
         <item name="android:shadowDy">1.0</item>
         <item name="android:shadowRadius">4.0</item>
diff --git a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
index 4fecc3d..ba7c3f8 100644
--- a/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
+++ b/src/com/android/launcher3/BaseRecyclerViewFastScrollBar.java
@@ -29,6 +29,7 @@
 import android.widget.TextView;
 
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.util.Themes;
 
 /**
  * The track and scrollbar that shows when you scroll the list.
@@ -102,7 +103,7 @@
 
         mThumbPaint = new Paint();
         mThumbPaint.setAntiAlias(true);
-        mThumbPaint.setColor(Utilities.getColorAccent(rv.getContext()));
+        mThumbPaint.setColor(Themes.getColorAccent(rv.getContext()));
         mThumbPaint.setStyle(Paint.Style.FILL);
 
         mWidth = mMinWidth = res.getDimensionPixelSize(R.dimen.container_fastscroll_thumb_min_width);
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index bbf2cb8..1a41e08 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -113,7 +113,7 @@
 
         TypedArray a = context.obtainStyledAttributes(attrs,
                 R.styleable.BubbleTextView, defStyle, 0);
-        mCustomShadowsEnabled = a.getBoolean(R.styleable.BubbleTextView_customShadows, true);
+        mCustomShadowsEnabled = a.getBoolean(R.styleable.BubbleTextView_customShadows, false);
         mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false);
         mDeferShadowGenerationOnTouch =
                 a.getBoolean(R.styleable.BubbleTextView_deferShadowGeneration, false);
@@ -395,7 +395,7 @@
         }
 
         // If text is transparent, don't draw any shadow
-        if (getCurrentTextColor() == getResources().getColor(android.R.color.transparent)) {
+        if ((getCurrentTextColor() >> 24) == 0) {
             getPaint().clearShadowLayer();
             super.draw(canvas);
             return;
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 0df8e5a..e0fcbf0 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -50,6 +50,7 @@
 import com.android.launcher3.accessibility.DragAndDropAccessibilityDelegate;
 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.folder.FolderIcon;
 import com.android.launcher3.graphics.DragPreviewProvider;
@@ -2097,12 +2098,13 @@
             }
 
             setInitialAnimationValues(true);
-            a = new LauncherViewPropertyAnimator(child)
-                .scaleX(initScale)
-                .scaleY(initScale)
-                .translationX(initDeltaX)
-                .translationY(initDeltaY)
-                .setDuration(REORDER_ANIMATION_DURATION);
+            a = LauncherAnimUtils.ofPropertyValuesHolder(child,
+                    new PropertyListBuilder()
+                            .scale(initScale)
+                            .translationX(initDeltaX)
+                            .translationY(initDeltaY)
+                            .build())
+                    .setDuration(REORDER_ANIMATION_DURATION);
             a.setInterpolator(new android.view.animation.DecelerateInterpolator(1.5f));
             a.start();
         }
@@ -2144,7 +2146,7 @@
                 info.spanY = lp.cellVSpan;
 
                 if (requiresDbUpdate) {
-                    LauncherModel.modifyItemInDatabase(getContext(), info, container, screenId,
+                    mLauncher.getModelWriter().modifyItemInDatabase(info, container, screenId,
                             info.cellX, info.cellY, info.spanX, info.spanY);
                 }
             }
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index 5fff2e7..2c69d0a 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -16,9 +16,9 @@
 
 package com.android.launcher3;
 
-import android.content.Context;
 import android.os.Process;
 
+import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.util.ContentWriter;
 
 import java.util.ArrayList;
@@ -128,17 +128,17 @@
     /**
      * @param option flag to set or clear
      * @param isEnabled whether to set or clear the flag
-     * @param context if not null, save changes to the db.
+     * @param writer if not null, save changes to the db.
      */
-    public void setOption(int option, boolean isEnabled, Context context) {
+    public void setOption(int option, boolean isEnabled, ModelWriter writer) {
         int oldOptions = options;
         if (isEnabled) {
             options |= option;
         } else {
             options &= ~option;
         }
-        if (context != null && oldOptions != options) {
-            LauncherModel.updateItemInDatabase(context, this);
+        if (writer != null && oldOptions != options) {
+            writer.updateItemInDatabase(this);
         }
     }
 }
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 4a8a272..47052a7 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -25,7 +25,6 @@
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.graphics.drawable.Drawable;
-import android.support.v4.content.ContextCompat;
 import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
 import android.view.LayoutInflater;
@@ -40,6 +39,7 @@
 import com.android.launcher3.logging.UserEventDispatcher;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
+import com.android.launcher3.util.Themes;
 
 public class Hotseat extends FrameLayout
         implements UserEventDispatcher.LogContainerProvider {
@@ -70,7 +70,7 @@
         mLauncher = Launcher.getLauncher(context);
         mHasVerticalHotseat = mLauncher.getDeviceProfile().isVerticalBarLayout();
         mBackgroundColor = ColorUtils.setAlphaComponent(
-                ContextCompat.getColor(context, R.color.all_apps_container_color), 0);
+                Themes.getAttrColor(context, android.R.attr.colorPrimary), 0);
         mBackground = new ColorDrawable(mBackgroundColor);
         setBackground(mBackground);
     }
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index 6e9820c..1f473a2 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -27,7 +27,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.database.Cursor;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
@@ -45,7 +44,6 @@
 import android.support.annotation.NonNull;
 import android.text.TextUtils;
 import android.util.Log;
-import android.view.ContextThemeWrapper;
 
 import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserManagerCompat;
@@ -56,6 +54,7 @@
 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;
@@ -132,10 +131,9 @@
                 IconProvider.class, context, R.string.icon_provider_class);
         mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
 
-        mActivityBgColor = context.getResources().getColor(R.color.quantum_panel_bg_color);
-        mPackageBgColor = Utilities.getAttrColor(
-                new ContextThemeWrapper(context, R.style.WidgetContainerTheme),
-                android.R.attr.colorPrimary);
+        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.
diff --git a/src/com/android/launcher3/InfoDropTarget.java b/src/com/android/launcher3/InfoDropTarget.java
index d831a3a..34adf47 100644
--- a/src/com/android/launcher3/InfoDropTarget.java
+++ b/src/com/android/launcher3/InfoDropTarget.java
@@ -25,6 +25,7 @@
 import android.widget.Toast;
 
 import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.util.Themes;
 
 public class InfoDropTarget extends UninstallDropTarget {
 
@@ -42,7 +43,7 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         // Get the hover color
-        mHoverColor = Utilities.getColorAccent(getContext());
+        mHoverColor = Themes.getColorAccent(getContext());
 
         setDrawable(R.drawable.ic_info_launcher);
     }
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index e3c6965..8aeab87 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -29,6 +29,7 @@
 
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.config.ProviderConfig;
+import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.util.Thunk;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -187,6 +188,23 @@
         }
     }
 
+    public void dumpDisplayInfo(Context context) {
+        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        Display display = wm.getDefaultDisplay();
+        DisplayMetrics dm = new DisplayMetrics();
+        display.getMetrics(dm);
+
+        Point smallestSize = new Point();
+        Point largestSize = new Point();
+        display.getCurrentSizeRange(smallestSize, largestSize);
+
+        FileLog.e("DisplayInfo", "Default Density: " + DisplayMetrics.DENSITY_DEFAULT);
+        FileLog.e("DisplayInfo", "Density: " + dm.densityDpi);
+        FileLog.e("DisplayInfo", "Smallest size: " + smallestSize);
+        FileLog.e("DisplayInfo", "Largest size: " + largestSize);
+        FileLog.e("DisplayInfo", "minWidth/Height DPS: " + minWidthDps + ", " + minHeightDps);
+    }
+
     ArrayList<InvariantDeviceProfile> getPredefinedDeviceProfiles(Context context) {
         ArrayList<InvariantDeviceProfile> profiles = new ArrayList<>();
         try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index a160c41..624ea4a 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -85,6 +85,7 @@
 import com.android.launcher3.allapps.AllAppsTransitionController;
 import com.android.launcher3.allapps.DefaultAppSearchController;
 import com.android.launcher3.anim.AnimationLayerSet;
+import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.notification.NotificationListener;
 import com.android.launcher3.popup.PopupDataProvider;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
@@ -254,6 +255,7 @@
     private ViewOnDrawExecutor mPendingExecutor;
 
     private LauncherModel mModel;
+    private ModelWriter mModelWriter;
     private IconCache mIconCache;
     private ExtractedColors mExtractedColors;
     private LauncherAccessibilityDelegate mAccessibilityDelegate;
@@ -371,6 +373,7 @@
         mSharedPrefs = Utilities.getPrefs(this);
         mIsSafeModeEnabled = getPackageManager().isSafeMode();
         mModel = app.setLauncher(this);
+        mModelWriter = mModel.getWriter(mDeviceProfile.isVerticalBarLayout());
         mIconCache = app.getIconCache();
         mAccessibilityDelegate = new LauncherAccessibilityDelegate(this);
 
@@ -1498,7 +1501,7 @@
             return;
         }
 
-        LauncherModel.addItemToDatabase(this, info, container, screenId, cellXY[0], cellXY[1]);
+        getModelWriter().addItemToDatabase(info, container, screenId, cellXY[0], cellXY[1]);
         mWorkspace.addInScreen(view, info);
     }
 
@@ -1526,7 +1529,7 @@
         launcherInfo.minSpanY = itemInfo.minSpanY;
         launcherInfo.user = appWidgetInfo.getUser();
 
-        LauncherModel.addItemToDatabase(this, launcherInfo,
+        getModelWriter().addItemToDatabase(launcherInfo,
                 itemInfo.container, itemInfo.screenId, itemInfo.cellX, itemInfo.cellY);
 
         if (hostView == null) {
@@ -1686,6 +1689,10 @@
         return mModel;
     }
 
+    public ModelWriter getModelWriter() {
+        return mModelWriter;
+    }
+
     public SharedPreferences getSharedPrefs() {
         return mSharedPrefs;
     }
@@ -2127,8 +2134,7 @@
         folderInfo.title = getText(R.string.folder_name);
 
         // Update the model
-        LauncherModel.addItemToDatabase(Launcher.this, folderInfo, container, screenId,
-                cellX, cellY);
+        getModelWriter().addItemToDatabase(folderInfo, container, screenId, cellX, cellY);
 
         // Create the view
         FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo);
@@ -2156,7 +2162,7 @@
                 mWorkspace.removeWorkspaceItem(v);
             }
             if (deleteFromDb) {
-                LauncherModel.deleteItemFromDatabase(this, itemInfo);
+                getModelWriter().deleteItemFromDatabase(itemInfo);
             }
         } else if (itemInfo instanceof FolderInfo) {
             final FolderInfo folderInfo = (FolderInfo) itemInfo;
@@ -2165,7 +2171,7 @@
             }
             mWorkspace.removeWorkspaceItem(v);
             if (deleteFromDb) {
-                LauncherModel.deleteFolderAndContentsFromDatabase(this, folderInfo);
+                getModelWriter().deleteFolderAndContentsFromDatabase(folderInfo);
             }
         } else if (itemInfo instanceof LauncherAppWidgetInfo) {
             final LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) itemInfo;
@@ -2194,7 +2200,7 @@
                 }
             }.executeOnExecutor(Utilities.THREAD_POOL_EXECUTOR);
         }
-        LauncherModel.deleteItemFromDatabase(this, widgetInfo);
+        getModelWriter().deleteItemFromDatabase(widgetInfo);
     }
 
     @Override
@@ -3203,6 +3209,9 @@
         if (LauncherAppState.PROFILE_STARTUP) {
             Trace.beginSection("Starting page bind");
         }
+
+        AbstractFloatingView.closeAllOpenViews(this);
+
         setWorkspaceLoading(true);
 
         // Clear the workspace because it's going to be rebound
@@ -3373,7 +3382,7 @@
                         throw (new RuntimeException(desc));
                     } else {
                         Log.d(TAG, desc);
-                        LauncherModel.deleteItemFromDatabase(this, item);
+                        getModelWriter().deleteItemFromDatabase(item);
                         continue;
                     }
                 }
@@ -3470,7 +3479,7 @@
                             + " belongs to component " + item.providerName
                             + ", as the provider is null");
                 }
-                LauncherModel.deleteItemFromDatabase(this, item);
+                getModelWriter().deleteItemFromDatabase(item);
                 return;
             }
 
@@ -3517,14 +3526,14 @@
                                 : LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
                     }
 
-                    LauncherModel.updateItemInDatabase(this, item);
+                    getModelWriter().updateItemInDatabase(item);
                 }
             } else if (item.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_UI_NOT_READY)
                     && (appWidgetInfo.configure == null)) {
                 // The widget was marked as UI not ready, but there is no configure activity to
                 // update the UI.
                 item.restoreStatus = LauncherAppWidgetInfo.RESTORE_COMPLETED;
-                LauncherModel.updateItemInDatabase(this, item);
+                getModelWriter().updateItemInDatabase(item);
             }
         }
 
@@ -3574,7 +3583,7 @@
         info.restoreStatus = finalRestoreFlag;
 
         mWorkspace.reinflateWidgetsIfNecessary();
-        LauncherModel.updateItemInDatabase(this, info);
+        getModelWriter().updateItemInDatabase(info);
         return info;
     }
 
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 55c3703..e0e53a6 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -28,6 +28,7 @@
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.ProviderConfig;
 import com.android.launcher3.dynamicui.ExtractionUtils;
+import com.android.launcher3.model.GridSizeMigrationTask;
 import com.android.launcher3.util.ConfigMonitor;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.TestingUtils;
@@ -53,6 +54,8 @@
         if (INSTANCE == null) {
             if (Looper.myLooper() == Looper.getMainLooper()) {
                 INSTANCE = new LauncherAppState(context.getApplicationContext());
+                GridSizeMigrationTask.logDeviceProfileIfChanged(
+                        INSTANCE.getInvariantDeviceProfile(), context);
             } else {
                 try {
                     return new MainThreadExecutor().submit(new Callable<LauncherAppState>() {
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 9ad8433..5fd5081 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -26,7 +26,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.LauncherActivityInfo;
-import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -57,6 +56,7 @@
 import com.android.launcher3.model.ExtendedModelTask;
 import com.android.launcher3.model.GridSizeMigrationTask;
 import com.android.launcher3.model.LoaderCursor;
+import com.android.launcher3.model.ModelWriter;
 import com.android.launcher3.model.PackageInstallStateChangedTask;
 import com.android.launcher3.model.PackageItemInfo;
 import com.android.launcher3.model.PackageUpdatedTask;
@@ -84,7 +84,6 @@
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.lang.ref.WeakReference;
-import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -266,19 +265,8 @@
         enqueueModelUpdateTask(new AddWorkspaceItemsTask(appsProvider));
     }
 
-    /**
-     * Adds an item to the DB if it was not created previously, or move it to a new
-     * <container, screen, cellX, cellY>
-     */
-    public static void addOrMoveItemInDatabase(Context context, ItemInfo item, long container,
-            long screenId, int cellX, int cellY) {
-        if (item.container == ItemInfo.NO_ID) {
-            // From all apps
-            addItemToDatabase(context, item, container, screenId, cellX, cellY);
-        } else {
-            // From somewhere else
-            moveItemInDatabase(context, item, container, screenId, cellX, cellY);
-        }
+    public ModelWriter getWriter(boolean hasVerticalHotseat) {
+        return new ModelWriter(mApp.getContext(), sBgDataModel, hasVerticalHotseat);
     }
 
     static void checkItemInfoLocked(
@@ -332,281 +320,6 @@
         runOnWorkerThread(r);
     }
 
-    static void updateItemInDatabaseHelper(Context context, final ContentWriter writer,
-            final ItemInfo item, final String callingFunction) {
-        final long itemId = item.id;
-        final Uri uri = LauncherSettings.Favorites.getContentUri(itemId);
-        final ContentResolver cr = context.getContentResolver();
-
-        final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
-        final Context appContext = context.getApplicationContext();
-        Runnable r = new Runnable() {
-            public void run() {
-                cr.update(uri, writer.getValues(appContext), null, null);
-                updateItemArrays(item, itemId, stackTrace);
-            }
-        };
-        runOnWorkerThread(r);
-    }
-
-    static void updateItemsInDatabaseHelper(Context context, final ArrayList<ContentValues> valuesList,
-            final ArrayList<ItemInfo> items, final String callingFunction) {
-        final ContentResolver cr = context.getContentResolver();
-
-        final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
-        Runnable r = new Runnable() {
-            public void run() {
-                ArrayList<ContentProviderOperation> ops =
-                        new ArrayList<ContentProviderOperation>();
-                int count = items.size();
-                for (int i = 0; i < count; i++) {
-                    ItemInfo item = items.get(i);
-                    final long itemId = item.id;
-                    final Uri uri = LauncherSettings.Favorites.getContentUri(itemId);
-                    ContentValues values = valuesList.get(i);
-
-                    ops.add(ContentProviderOperation.newUpdate(uri).withValues(values).build());
-                    updateItemArrays(item, itemId, stackTrace);
-
-                }
-                try {
-                    cr.applyBatch(LauncherProvider.AUTHORITY, ops);
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
-        };
-        runOnWorkerThread(r);
-    }
-
-    static void updateItemArrays(ItemInfo item, long itemId, StackTraceElement[] stackTrace) {
-        // Lock on mBgLock *after* the db operation
-        synchronized (sBgDataModel) {
-            checkItemInfoLocked(itemId, item, stackTrace);
-
-            if (item.container != LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                    item.container != LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
-                // Item is in a folder, make sure this folder exists
-                if (!sBgDataModel.folders.containsKey(item.container)) {
-                    // An items container is being set to a that of an item which is not in
-                    // the list of Folders.
-                    String msg = "item: " + item + " container being set to: " +
-                            item.container + ", not in the list of folders";
-                    Log.e(TAG, msg);
-                }
-            }
-
-            // Items are added/removed from the corresponding FolderInfo elsewhere, such
-            // as in Workspace.onDrop. Here, we just add/remove them from the list of items
-            // that are on the desktop, as appropriate
-            ItemInfo modelItem = sBgDataModel.itemsIdMap.get(itemId);
-            if (modelItem != null &&
-                    (modelItem.container == LauncherSettings.Favorites.CONTAINER_DESKTOP ||
-                     modelItem.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT)) {
-                switch (modelItem.itemType) {
-                    case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION:
-                    case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT:
-                    case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT:
-                    case LauncherSettings.Favorites.ITEM_TYPE_FOLDER:
-                        if (!sBgDataModel.workspaceItems.contains(modelItem)) {
-                            sBgDataModel.workspaceItems.add(modelItem);
-                        }
-                        break;
-                    default:
-                        break;
-                }
-            } else {
-                sBgDataModel.workspaceItems.remove(modelItem);
-            }
-        }
-    }
-
-    /**
-     * Move an item in the DB to a new <container, screen, cellX, cellY>
-     */
-    public static void moveItemInDatabase(Context context, final ItemInfo item, final long container,
-            final long screenId, final int cellX, final int cellY) {
-        item.container = container;
-        item.cellX = cellX;
-        item.cellY = cellY;
-
-        // We store hotseat items in canonical form which is this orientation invariant position
-        // in the hotseat
-        if (context instanceof Launcher && screenId < 0 &&
-                container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
-            item.screenId = Launcher.getLauncher(context).getHotseat()
-                    .getOrderInHotseat(cellX, cellY);
-        } else {
-            item.screenId = screenId;
-        }
-
-        final ContentWriter writer = new ContentWriter(context)
-                .put(LauncherSettings.Favorites.CONTAINER, item.container)
-                .put(LauncherSettings.Favorites.CELLX, item.cellX)
-                .put(LauncherSettings.Favorites.CELLY, item.cellY)
-                .put(LauncherSettings.Favorites.RANK, item.rank)
-                .put(LauncherSettings.Favorites.SCREEN, item.screenId);
-
-        updateItemInDatabaseHelper(context, writer, item, "moveItemInDatabase");
-    }
-
-    /**
-     * Move items in the DB to a new <container, screen, cellX, cellY>. We assume that the
-     * cellX, cellY have already been updated on the ItemInfos.
-     */
-    public static void moveItemsInDatabase(Context context, final ArrayList<ItemInfo> items,
-            final long container, final int screen) {
-
-        ArrayList<ContentValues> contentValues = new ArrayList<ContentValues>();
-        int count = items.size();
-
-        for (int i = 0; i < count; i++) {
-            ItemInfo item = items.get(i);
-            item.container = container;
-
-            // We store hotseat items in canonical form which is this orientation invariant position
-            // in the hotseat
-            if (context instanceof Launcher && screen < 0 &&
-                    container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
-                item.screenId = Launcher.getLauncher(context).getHotseat().getOrderInHotseat(item.cellX,
-                        item.cellY);
-            } else {
-                item.screenId = screen;
-            }
-
-            final ContentValues values = new ContentValues();
-            values.put(LauncherSettings.Favorites.CONTAINER, item.container);
-            values.put(LauncherSettings.Favorites.CELLX, item.cellX);
-            values.put(LauncherSettings.Favorites.CELLY, item.cellY);
-            values.put(LauncherSettings.Favorites.RANK, item.rank);
-            values.put(LauncherSettings.Favorites.SCREEN, item.screenId);
-
-            contentValues.add(values);
-        }
-        updateItemsInDatabaseHelper(context, contentValues, items, "moveItemInDatabase");
-    }
-
-    /**
-     * Move and/or resize item in the DB to a new <container, screen, cellX, cellY, spanX, spanY>
-     */
-    static void modifyItemInDatabase(Context context, final ItemInfo item, final long container,
-            final long screenId, final int cellX, final int cellY, final int spanX, final int spanY) {
-        item.container = container;
-        item.cellX = cellX;
-        item.cellY = cellY;
-        item.spanX = spanX;
-        item.spanY = spanY;
-
-        // We store hotseat items in canonical form which is this orientation invariant position
-        // in the hotseat
-        if (context instanceof Launcher && screenId < 0 &&
-                container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
-            item.screenId = Launcher.getLauncher(context).getHotseat()
-                    .getOrderInHotseat(cellX, cellY);
-        } else {
-            item.screenId = screenId;
-        }
-
-        final ContentWriter writer = new ContentWriter(context)
-                .put(LauncherSettings.Favorites.CONTAINER, item.container)
-                .put(LauncherSettings.Favorites.CELLX, item.cellX)
-                .put(LauncherSettings.Favorites.CELLY, item.cellY)
-                .put(LauncherSettings.Favorites.RANK, item.rank)
-                .put(LauncherSettings.Favorites.SPANX, item.spanX)
-                .put(LauncherSettings.Favorites.SPANY, item.spanY)
-                .put(LauncherSettings.Favorites.SCREEN, item.screenId);
-
-        updateItemInDatabaseHelper(context, writer, item, "modifyItemInDatabase");
-    }
-
-    /**
-     * Update an item to the database in a specified container.
-     */
-    public static void updateItemInDatabase(Context context, final ItemInfo item) {
-        ContentWriter writer = new ContentWriter(context);
-        item.onAddToDatabase(writer);
-        updateItemInDatabaseHelper(context, writer, item, "updateItemInDatabase");
-    }
-
-    /**
-     * Add an item to the database in a specified container. Sets the container, screen, cellX and
-     * cellY fields of the item. Also assigns an ID to the item.
-     */
-    public static void addItemToDatabase(Context context, final ItemInfo item, final long container,
-            final long screenId, final int cellX, final int cellY) {
-        item.container = container;
-        item.cellX = cellX;
-        item.cellY = cellY;
-        // We store hotseat items in canonical form which is this orientation invariant position
-        // in the hotseat
-        if (context instanceof Launcher && screenId < 0 &&
-                container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
-            item.screenId = Launcher.getLauncher(context).getHotseat()
-                    .getOrderInHotseat(cellX, cellY);
-        } else {
-            item.screenId = screenId;
-        }
-
-        final ContentWriter writer = new ContentWriter(context);
-        final ContentResolver cr = context.getContentResolver();
-        item.onAddToDatabase(writer);
-
-        item.id = LauncherSettings.Settings.call(cr, LauncherSettings.Settings.METHOD_NEW_ITEM_ID)
-                .getLong(LauncherSettings.Settings.EXTRA_VALUE);
-
-        writer.put(LauncherSettings.Favorites._ID, item.id);
-
-        final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
-        final Context appContext = context.getApplicationContext();
-        Runnable r = new Runnable() {
-            public void run() {
-                cr.insert(LauncherSettings.Favorites.CONTENT_URI, writer.getValues(appContext));
-
-                synchronized (sBgDataModel) {
-                    checkItemInfoLocked(item.id, item, stackTrace);
-                    sBgDataModel.addItem(appContext, item, true);
-                }
-            }
-        };
-        runOnWorkerThread(r);
-    }
-
-    /**
-     * Removes the specified item from the database
-     */
-    public static void deleteItemFromDatabase(Context context, final ItemInfo item) {
-        ArrayList<ItemInfo> items = new ArrayList<>();
-        items.add(item);
-        deleteItemsFromDatabase(context, items);
-    }
-
-    /**
-     * Removes all the items from the database matching {@param matcher}.
-     */
-    public static void deleteItemsFromDatabase(Context context, ItemInfoMatcher matcher) {
-        deleteItemsFromDatabase(context, matcher.filterItemInfos(sBgDataModel.itemsIdMap));
-    }
-
-    /**
-     * Removes the specified items from the database
-     */
-    public static void deleteItemsFromDatabase(Context context,
-            final Iterable<? extends ItemInfo> items) {
-        final ContentResolver cr = context.getContentResolver();
-        final Context appContext = context.getApplicationContext();
-        Runnable r = new Runnable() {
-            public void run() {
-                for (ItemInfo item : items) {
-                    final Uri uri = LauncherSettings.Favorites.getContentUri(item.id);
-                    cr.delete(uri, null, null);
-
-                    sBgDataModel.removeItem(appContext, item);
-                }
-            }
-        };
-        runOnWorkerThread(r);
-    }
-
     /**
      * Update the order of the workspace screens in the database. The array list contains
      * a list of screen ids in the order that they should appear.
@@ -656,27 +369,6 @@
     }
 
     /**
-     * Remove the specified folder and all its contents from the database.
-     */
-    public static void deleteFolderAndContentsFromDatabase(Context context, final FolderInfo info) {
-        final ContentResolver cr = context.getContentResolver();
-        final Context appContext = context.getApplicationContext();
-
-        Runnable r = new Runnable() {
-            public void run() {
-                cr.delete(LauncherSettings.Favorites.CONTENT_URI,
-                        LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
-                sBgDataModel.removeItem(appContext, info.contents);
-                info.contents.clear();
-
-                cr.delete(LauncherSettings.Favorites.getContentUri(info.id), null, null);
-                sBgDataModel.removeItem(appContext, info);
-            }
-        };
-        runOnWorkerThread(r);
-    }
-
-    /**
      * Set this as the current Launcher activity object for the loader.
      */
     public void initialize(Callbacks callbacks) {
@@ -1340,6 +1032,11 @@
                                         info = new ShortcutInfo(pinnedShortcut, context);
                                         info.iconBitmap = LauncherIcons
                                                 .createShortcutIcon(pinnedShortcut, context);
+                                        if (pmHelper.isAppSuspended(
+                                                info.getTargetComponent().getPackageName(),
+                                                info.user)) {
+                                            info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SUSPENDED;
+                                        }
                                         intent = info.intent;
                                     } else {
                                         // Create a shortcut info in disabled mode for now.
@@ -2193,6 +1890,11 @@
                 }
             });
         }
+
+        public ModelWriter getModelWriter() {
+            // Updates from model task, do not deal with icon position in hotseat.
+            return mModel.getWriter(false /* hasVerticalHotseat */);
+        }
     }
 
     public void updateAndBindShortcutInfo(final ShortcutInfo si, final ShortcutInfoCompat info) {
diff --git a/src/com/android/launcher3/LauncherViewPropertyAnimator.java b/src/com/android/launcher3/LauncherViewPropertyAnimator.java
deleted file mode 100644
index 4406a2c..0000000
--- a/src/com/android/launcher3/LauncherViewPropertyAnimator.java
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.TimeInterpolator;
-import android.view.View;
-import android.view.ViewPropertyAnimator;
-
-import java.util.ArrayList;
-import java.util.EnumSet;
-
-public class LauncherViewPropertyAnimator extends Animator implements AnimatorListener {
-
-    enum Properties {
-            TRANSLATION_X,
-            TRANSLATION_Y,
-            SCALE_X,
-            SCALE_Y,
-            ROTATION_Y,
-            ALPHA,
-            START_DELAY,
-            DURATION,
-            INTERPOLATOR,
-            WITH_LAYER
-    }
-    EnumSet<Properties> mPropertiesToSet = EnumSet.noneOf(Properties.class);
-    ViewPropertyAnimator mViewPropertyAnimator;
-    View mTarget;
-
-    float mTranslationX;
-    float mTranslationY;
-    float mScaleX;
-    float mScaleY;
-    float mRotationY;
-    float mAlpha;
-    long mStartDelay;
-    long mDuration;
-    TimeInterpolator mInterpolator;
-    ArrayList<Animator.AnimatorListener> mListeners = new ArrayList<>();
-    boolean mRunning = false;
-    FirstFrameAnimatorHelper mFirstFrameHelper;
-
-    public LauncherViewPropertyAnimator(View target) {
-        mTarget = target;
-    }
-
-    @Override
-    public void addListener(Animator.AnimatorListener listener) {
-        mListeners.add(listener);
-    }
-
-    @Override
-    public void cancel() {
-        if (mViewPropertyAnimator != null) {
-            mViewPropertyAnimator.cancel();
-        }
-    }
-
-    @Override
-    public Animator clone() {
-        throw new RuntimeException("Not implemented");
-    }
-
-    @Override
-    public void end() {
-        throw new RuntimeException("Not implemented");
-    }
-
-    @Override
-    public long getDuration() {
-        return mDuration;
-    }
-
-    @Override
-    public ArrayList<Animator.AnimatorListener> getListeners() {
-        return mListeners;
-    }
-
-    @Override
-    public long getStartDelay() {
-        return mStartDelay;
-    }
-
-    @Override
-    public void onAnimationCancel(Animator animation) {
-        for (int i = 0; i < mListeners.size(); i++) {
-            Animator.AnimatorListener listener = mListeners.get(i);
-            listener.onAnimationCancel(this);
-        }
-        mRunning = false;
-    }
-
-    @Override
-    public void onAnimationEnd(Animator animation) {
-        for (int i = 0; i < mListeners.size(); i++) {
-            Animator.AnimatorListener listener = mListeners.get(i);
-            listener.onAnimationEnd(this);
-        }
-        mRunning = false;
-    }
-
-    @Override
-    public void onAnimationRepeat(Animator animation) {
-        for (int i = 0; i < mListeners.size(); i++) {
-            Animator.AnimatorListener listener = mListeners.get(i);
-            listener.onAnimationRepeat(this);
-        }
-    }
-
-    @Override
-    public void onAnimationStart(Animator animation) {
-        // This is the first time we get a handle to the internal ValueAnimator
-        // used by the ViewPropertyAnimator.
-        mFirstFrameHelper.onAnimationStart(animation);
-
-        for (int i = 0; i < mListeners.size(); i++) {
-            Animator.AnimatorListener listener = mListeners.get(i);
-            listener.onAnimationStart(this);
-        }
-        mRunning = true;
-    }
-
-    @Override
-    public boolean isRunning() {
-        return mRunning;
-    }
-
-    @Override
-    public boolean isStarted() {
-        return mViewPropertyAnimator != null;
-    }
-
-    @Override
-    public void removeAllListeners() {
-        mListeners.clear();
-    }
-
-    @Override
-    public void removeListener(Animator.AnimatorListener listener) {
-        mListeners.remove(listener);
-    }
-
-    @Override
-    public Animator setDuration(long duration) {
-        mPropertiesToSet.add(Properties.DURATION);
-        mDuration = duration;
-        return this;
-    }
-
-    @Override
-    public void setInterpolator(TimeInterpolator value) {
-        mPropertiesToSet.add(Properties.INTERPOLATOR);
-        mInterpolator = value;
-    }
-
-    @Override
-    public void setStartDelay(long startDelay) {
-        mPropertiesToSet.add(Properties.START_DELAY);
-        mStartDelay = startDelay;
-    }
-
-    @Override
-    public void setTarget(Object target) {
-        throw new RuntimeException("Not implemented");
-    }
-
-    @Override
-    public void setupEndValues() {
-
-    }
-
-    @Override
-    public void setupStartValues() {
-    }
-
-    @Override
-    public void start() {
-        mViewPropertyAnimator = mTarget.animate();
-
-        // FirstFrameAnimatorHelper hooks itself up to the updates on the animator,
-        // and then adjusts the play time to keep the first two frames jank-free
-        mFirstFrameHelper = new FirstFrameAnimatorHelper(mViewPropertyAnimator, mTarget);
-
-        if (mPropertiesToSet.contains(Properties.TRANSLATION_X)) {
-            mViewPropertyAnimator.translationX(mTranslationX);
-        }
-        if (mPropertiesToSet.contains(Properties.TRANSLATION_Y)) {
-            mViewPropertyAnimator.translationY(mTranslationY);
-        }
-        if (mPropertiesToSet.contains(Properties.SCALE_X)) {
-            mViewPropertyAnimator.scaleX(mScaleX);
-        }
-        if (mPropertiesToSet.contains(Properties.ROTATION_Y)) {
-            mViewPropertyAnimator.rotationY(mRotationY);
-        }
-        if (mPropertiesToSet.contains(Properties.SCALE_Y)) {
-            mViewPropertyAnimator.scaleY(mScaleY);
-        }
-        if (mPropertiesToSet.contains(Properties.ALPHA)) {
-            mViewPropertyAnimator.alpha(mAlpha);
-        }
-        if (mPropertiesToSet.contains(Properties.START_DELAY)) {
-            mViewPropertyAnimator.setStartDelay(mStartDelay);
-        }
-        if (mPropertiesToSet.contains(Properties.DURATION)) {
-            mViewPropertyAnimator.setDuration(mDuration);
-        }
-        if (mPropertiesToSet.contains(Properties.INTERPOLATOR)) {
-            mViewPropertyAnimator.setInterpolator(mInterpolator);
-        }
-        if (mPropertiesToSet.contains(Properties.WITH_LAYER)) {
-            mViewPropertyAnimator.withLayer();
-        }
-        mViewPropertyAnimator.setListener(this);
-        mViewPropertyAnimator.start();
-        LauncherAnimUtils.cancelOnDestroyActivity(this);
-    }
-
-    public LauncherViewPropertyAnimator translationX(float value) {
-        mPropertiesToSet.add(Properties.TRANSLATION_X);
-        mTranslationX = value;
-        return this;
-    }
-
-    public LauncherViewPropertyAnimator translationY(float value) {
-        mPropertiesToSet.add(Properties.TRANSLATION_Y);
-        mTranslationY = value;
-        return this;
-    }
-
-    public LauncherViewPropertyAnimator scaleX(float value) {
-        mPropertiesToSet.add(Properties.SCALE_X);
-        mScaleX = value;
-        return this;
-    }
-
-    public LauncherViewPropertyAnimator scaleY(float value) {
-        mPropertiesToSet.add(Properties.SCALE_Y);
-        mScaleY = value;
-        return this;
-    }
-
-    public LauncherViewPropertyAnimator rotationY(float value) {
-        mPropertiesToSet.add(Properties.ROTATION_Y);
-        mRotationY = value;
-        return this;
-    }
-
-    public LauncherViewPropertyAnimator alpha(float value) {
-        mPropertiesToSet.add(Properties.ALPHA);
-        mAlpha = value;
-        return this;
-    }
-
-    public LauncherViewPropertyAnimator withLayer() {
-        mPropertiesToSet.add(Properties.WITH_LAYER);
-        return this;
-    }
-}
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 76e2073..fb6a611 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -47,6 +47,7 @@
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.Interpolator;
 
+import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.pageindicators.PageIndicator;
 import com.android.launcher3.util.LauncherEdgeEffect;
 import com.android.launcher3.util.Thunk;
@@ -1998,11 +1999,12 @@
     // Animate the drag view back to the original position
     private void animateDragViewToOriginalPosition() {
         if (mDragView != null) {
-            Animator anim = new LauncherViewPropertyAnimator(mDragView)
-                    .translationX(0)
-                    .translationY(0)
-                    .scaleX(1)
-                    .scaleY(1)
+            Animator anim = LauncherAnimUtils.ofPropertyValuesHolder(mDragView,
+                    new PropertyListBuilder()
+                            .scale(1)
+                            .translationX(0)
+                            .translationY(0)
+                            .build())
                     .setDuration(REORDERING_DROP_REPOSITION_DURATION);
             anim.addListener(new AnimatorListenerAdapter() {
                 @Override
diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/PendingAppWidgetHostView.java
index 815fd10..43fa4aa 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/PendingAppWidgetHostView.java
@@ -35,6 +35,7 @@
 import com.android.launcher3.IconCache.ItemInfoUpdateReceiver;
 import com.android.launcher3.graphics.DrawableFactory;
 import com.android.launcher3.model.PackageItemInfo;
+import com.android.launcher3.util.Themes;
 
 public class PendingAppWidgetHostView extends LauncherAppWidgetHostView
         implements OnClickListener, ItemInfoUpdateReceiver {
@@ -69,7 +70,7 @@
         mDisabledForSafeMode = disabledForSafeMode;
 
         mPaint = new TextPaint();
-        mPaint.setColor(Utilities.getAttrColor(getContext(), android.R.attr.textColorPrimary));
+        mPaint.setColor(Themes.getAttrColor(getContext(), android.R.attr.textColorPrimary));
         mPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX,
                 mLauncher.getDeviceProfile().iconTextSizePx, getResources().getDisplayMetrics()));
         setBackgroundResource(R.drawable.round_rect_primary);
diff --git a/src/com/android/launcher3/PinchAnimationManager.java b/src/com/android/launcher3/PinchAnimationManager.java
index bae246e..f8196e5 100644
--- a/src/com/android/launcher3/PinchAnimationManager.java
+++ b/src/com/android/launcher3/PinchAnimationManager.java
@@ -24,6 +24,7 @@
 import android.view.View;
 import android.view.animation.LinearInterpolator;
 
+import com.android.launcher3.anim.AnimationLayerSet;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 
@@ -211,7 +212,8 @@
     }
 
     private void animateShowHideView(int index, final View view, boolean show) {
-        Animator animator = new LauncherViewPropertyAnimator(view).alpha(show ? 1 : 0).withLayer();
+        Animator animator = ObjectAnimator.ofFloat(view, View.ALPHA, show ? 1 : 0);
+        animator.addListener(new AnimationLayerSet(view));
         if (show) {
             view.setVisibility(View.VISIBLE);
         } else {
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 78774f3..abc5367 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -27,7 +27,6 @@
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
-import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Color;
 import android.graphics.Matrix;
@@ -608,17 +607,6 @@
         return c == null || c.isEmpty();
     }
 
-    public static int getColorAccent(Context context) {
-        return getAttrColor(context, android.R.attr.colorAccent);
-    }
-
-    public static int getAttrColor(Context context, int attr) {
-        TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
-        int colorAccent = ta.getColor(0, 0);
-        ta.recycle();
-        return colorAccent;
-    }
-
     public static void sendCustomAccessibilityEvent(View target, int type, String text) {
         AccessibilityManager accessibilityManager = (AccessibilityManager)
                 target.getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 3512210..689cc9b 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -14,22 +14,24 @@
 import android.graphics.Bitmap.Config;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
-import android.graphics.ColorMatrix;
-import android.graphics.ColorMatrixColorFilter;
+import android.graphics.Color;
 import android.graphics.Paint;
 import android.graphics.PorterDuff;
 import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
 import android.graphics.RectF;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
 import android.os.Handler;
 import android.os.UserHandle;
+import android.support.v4.graphics.ColorUtils;
 import android.util.Log;
 import android.util.LongSparseArray;
 
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.ShortcutConfigActivityInfo;
 import com.android.launcher3.compat.UserManagerCompat;
+import com.android.launcher3.graphics.LauncherIcons;
 import com.android.launcher3.graphics.ShadowGenerator;
 import com.android.launcher3.model.WidgetItem;
 import com.android.launcher3.util.ComponentKey;
@@ -366,30 +368,13 @@
             drawable.setBounds(x, 0, x + previewWidth, previewHeight);
             drawable.draw(c);
         } else {
-            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);
-            float corner = res.getDimension(R.dimen.widget_preview_corner_radius);
-
-            RectF boxRect = new RectF(shadowBlur, shadowBlur,
-                    previewWidth - shadowBlur, previewHeight - shadowBlur - keyShadowDistance);
-
             final Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
-            p.setColor(0xFFFFFFFF);
-
-            // Key shadow
-            p.setShadowLayer(shadowBlur, 0, keyShadowDistance,
-                    ShadowGenerator.KEY_SHADOW_ALPHA << 24);
-            c.drawRoundRect(boxRect, corner, corner, p);
-
-            // Ambient shadow
-            p.setShadowLayer(shadowBlur, 0, 0, ShadowGenerator.AMBIENT_SHADOW_ALPHA << 24);
-            c.drawRoundRect(boxRect, corner, corner, p);
+            RectF boxRect = drawBoxWithShadow(c, p, previewWidth, previewHeight);
 
             // Draw horizontal and vertical lines to represent individual columns.
-            p.clearShadowLayer();
             p.setStyle(Paint.Style.STROKE);
-            p.setStrokeWidth(res.getDimension(R.dimen.widget_preview_cell_divider_width));
+            p.setStrokeWidth(mContext.getResources()
+                    .getDimension(R.dimen.widget_preview_cell_divider_width));
             p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
 
             float t = boxRect.left;
@@ -426,47 +411,63 @@
         return preview;
     }
 
+    private RectF drawBoxWithShadow(Canvas c, Paint p, 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);
+        float corner = res.getDimension(R.dimen.widget_preview_corner_radius);
+
+        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();
+        return bounds;
+    }
+
     private Bitmap generateShortcutPreview(BaseActivity launcher, ShortcutConfigActivityInfo info,
             int maxWidth, int maxHeight, Bitmap preview) {
+        int iconSize = launcher.getDeviceProfile().iconSizePx;
+        int padding = launcher.getResources()
+                .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
+
+        int size = iconSize + 2 * padding;
+        if (maxHeight < size || maxWidth < size) {
+            throw new RuntimeException("Max size is too small for preview");
+        }
         final Canvas c = new Canvas();
-        if (preview == null) {
-            preview = Bitmap.createBitmap(maxWidth, maxHeight, Config.ARGB_8888);
+        if (preview == null || preview.getWidth() < size || preview.getHeight() < size) {
+            preview = Bitmap.createBitmap(size, size, Config.ARGB_8888);
             c.setBitmap(preview);
-        } else if (preview.getWidth() != maxWidth || preview.getHeight() != maxHeight) {
-            throw new RuntimeException("Improperly sized bitmap passed as argument");
         } else {
+            if (preview.getWidth() > size || preview.getHeight() > size) {
+                preview.reconfigure(size, size, preview.getConfig());
+            }
+
             // Reusing bitmap. Clear it.
             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);
 
-        Drawable icon = mutateOnMainThread(info.getFullResIcon(mIconCache));
-        icon.setFilterBitmap(true);
+        Bitmap icon = LauncherIcons.createScaledBitmapWithoutShadow(
+                mutateOnMainThread(info.getFullResIcon(mIconCache)), mContext);
+        Rect src = new Rect(0, 0, icon.getWidth(), icon.getHeight());
 
-        // Draw a desaturated/scaled version of the icon in the background as a watermark
-        ColorMatrix colorMatrix = new ColorMatrix();
-        colorMatrix.setSaturation(0);
-        icon.setColorFilter(new ColorMatrixColorFilter(colorMatrix));
-        icon.setAlpha((int) (255 * 0.06f));
-
-        Resources res = mContext.getResources();
-        int paddingTop = res.getDimensionPixelOffset(R.dimen.shortcut_preview_padding_top);
-        int paddingLeft = res.getDimensionPixelOffset(R.dimen.shortcut_preview_padding_left);
-        int paddingRight = res.getDimensionPixelOffset(R.dimen.shortcut_preview_padding_right);
-        int scaledIconWidth = (maxWidth - paddingLeft - paddingRight);
-        icon.setBounds(paddingLeft, paddingTop,
-                paddingLeft + scaledIconWidth, paddingTop + scaledIconWidth);
-        icon.draw(c);
-
-        // Draw the final icon at top left corner.
-        // TODO: use top right for RTL
-        int appIconSize = launcher.getDeviceProfile().iconSizePx;
-
-        icon.setAlpha(255);
-        icon.setColorFilter(null);
-        icon.setBounds(0, 0, appIconSize, appIconSize);
-        icon.draw(c);
-
+        boxRect.set(0, 0, iconSize, iconSize);
+        boxRect.offset(padding, padding);
+        c.drawBitmap(icon, src, boxRect, p);
         c.setBitmap(null);
         return preview;
     }
@@ -664,7 +665,6 @@
 
     private static final class WidgetCacheKey extends ComponentKey {
 
-        // TODO: remove dependency on size
         @Thunk final String size;
 
         public WidgetCacheKey(ComponentName componentName, UserHandle user, String size) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 3aa8825..56aa69e 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2654,8 +2654,8 @@
                         }
                     }
 
-                    LauncherModel.modifyItemInDatabase(mLauncher, info, container, screenId, lp.cellX,
-                            lp.cellY, item.spanX, item.spanY);
+                    mLauncher.getModelWriter().modifyItemInDatabase(info, container, screenId,
+                            lp.cellX, lp.cellY, item.spanX, item.spanY);
                 } else {
                     if (!returnToOriginalCellToPreventShuffling) {
                         onNoCellFound(dropTargetLayout);
@@ -3387,7 +3387,7 @@
             }
             // Add the item to DB before adding to screen ensures that the container and other
             // values of the info is properly updated.
-            LauncherModel.addOrMoveItemInDatabase(mLauncher, info, container, screenId,
+            mLauncher.getModelWriter().addOrMoveItemInDatabase(info, container, screenId,
                     mTargetCell[0], mTargetCell[1]);
 
             addInScreen(view, container, screenId, mTargetCell[0], mTargetCell[1],
@@ -4025,7 +4025,7 @@
         HashSet<String> packages = new HashSet<>(1);
         packages.add(packageName);
         ItemInfoMatcher matcher = ItemInfoMatcher.ofPackages(packages, user);
-        LauncherModel.deleteItemsFromDatabase(mLauncher, matcher);
+        mLauncher.getModelWriter().deleteItemsFromDatabase(matcher);
         removeItemsByMatcher(matcher);
     }
 
diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
index 6a71bef..482a2c9 100644
--- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
+++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java
@@ -31,6 +31,7 @@
 import android.view.animation.DecelerateInterpolator;
 
 import com.android.launcher3.anim.AnimationLayerSet;
+import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dragndrop.DragLayer;
 import com.android.launcher3.util.Thunk;
@@ -337,10 +338,9 @@
             if (animated) {
                 float oldBackgroundAlpha = cl.getBackgroundAlpha();
                 if (initialAlpha != finalAlpha) {
-                    LauncherViewPropertyAnimator alphaAnim =
-                            new LauncherViewPropertyAnimator(cl.getShortcutsAndWidgets());
-                    alphaAnim.alpha(finalAlpha)
-                            .setDuration(duration)
+                    Animator alphaAnim = ObjectAnimator.ofFloat(
+                            cl.getShortcutsAndWidgets(), View.ALPHA, finalAlpha);
+                    alphaAnim.setDuration(duration)
                             .setInterpolator(mZoomInInterpolator);
                     mStateAnimator.play(alphaAnim);
                 }
@@ -377,17 +377,16 @@
                 .animateAlphaAtIndex(finalQsbAlpha, Workspace.QSB_ALPHA_INDEX_STATE_CHANGE);
 
         if (animated) {
-            LauncherViewPropertyAnimator scale = new LauncherViewPropertyAnimator(mWorkspace);
-            scale.scaleX(mNewScale)
-                    .scaleY(mNewScale)
-                    .translationY(finalWorkspaceTranslationY)
-                    .setDuration(duration)
-                    .setInterpolator(mZoomInInterpolator);
+            Animator scale = LauncherAnimUtils.ofPropertyValuesHolder(mWorkspace,
+                    new PropertyListBuilder().scale(mNewScale)
+                            .translationY(finalWorkspaceTranslationY).build())
+                    .setDuration(duration);
+            scale.setInterpolator(mZoomInInterpolator);
             mStateAnimator.play(scale);
             Animator hotseatAlpha = mWorkspace.createHotseatAlphaAnimator(finalHotseatAlpha);
 
-            LauncherViewPropertyAnimator overviewPanelAlpha =
-                    new LauncherViewPropertyAnimator(overviewPanel).alpha(finalOverviewPanelAlpha);
+            Animator overviewPanelAlpha = ObjectAnimator.ofFloat(
+                    overviewPanel, View.ALPHA, finalOverviewPanelAlpha);
             overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel,
                     accessibilityEnabled));
 
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index b77493b..a476650 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -168,7 +168,7 @@
                 public void run() {
                     if (item instanceof AppInfo) {
                         ShortcutInfo info = ((AppInfo) item).makeShortcut();
-                        LauncherModel.addItemToDatabase(mLauncher, info,
+                        mLauncher.getModelWriter().addItemToDatabase(info,
                                 LauncherSettings.Favorites.CONTAINER_DESKTOP,
                                 screenId, coordinates[0], coordinates[1]);
 
@@ -194,7 +194,7 @@
 
             final int[] coordinates = new int[2];
             final long screenId = findSpaceOnWorkspace(item, coordinates);
-            LauncherModel.moveItemInDatabase(mLauncher, info,
+            mLauncher.getModelWriter().moveItemInDatabase(info,
                     LauncherSettings.Favorites.CONTAINER_DESKTOP,
                     screenId, coordinates[0], coordinates[1]);
 
@@ -304,7 +304,7 @@
         ((LauncherAppWidgetHostView) host).updateAppWidgetSize(null,
                 sizeRange.left, sizeRange.top, sizeRange.right, sizeRange.bottom);
         host.requestLayout();
-        LauncherModel.updateItemInDatabase(mLauncher, info);
+        mLauncher.getModelWriter().updateItemInDatabase(info);
         announceConfirmation(mLauncher.getString(R.string.widget_resized, info.spanX, info.spanY));
     }
 
diff --git a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
index f7ca703..b784fe7 100644
--- a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
@@ -59,7 +59,7 @@
             Runnable onComplete = new Runnable() {
                 @Override
                 public void run() {
-                    LauncherModel.addItemToDatabase(mLauncher, info,
+                    mLauncher.getModelWriter().addItemToDatabase(info,
                             LauncherSettings.Favorites.CONTAINER_DESKTOP,
                             screenId, coordinates[0], coordinates[1]);
                     ArrayList<ItemInfo> itemList = new ArrayList<>();
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 54d0bbe..0732004 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -464,10 +464,6 @@
             setLayoutParams(mlp);
         } else {
             View navBarBg = findViewById(R.id.nav_bar_bg);
-            if (Utilities.isAtLeastO()) {
-                navBarBg.setBackgroundColor(getResources().getColor(
-                        R.color.all_apps_light_navbar_color));
-            }
             ViewGroup.LayoutParams navBarBgLp = navBarBg.getLayoutParams();
             navBarBgLp.height = insets.bottom;
             navBarBg.setLayoutParams(navBarBgLp);
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index bd877f2..f352304 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -19,8 +19,8 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Point;
-import android.graphics.Rect;
 import android.support.v4.view.accessibility.AccessibilityEventCompat;
+import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
 import android.support.v4.view.accessibility.AccessibilityRecordCompat;
 import android.support.v7.widget.GridLayoutManager;
 import android.support.v7.widget.RecyclerView;
@@ -38,6 +38,9 @@
 import com.android.launcher3.DeviceProfile;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
+import com.android.launcher3.allapps.AlphabeticalAppsList.AdapterItem;
+
+import java.util.List;
 
 /**
  * The grid view adapter of all the apps.
@@ -105,17 +108,53 @@
             final AccessibilityRecordCompat record = AccessibilityEventCompat
                     .asRecord(event);
             record.setItemCount(mApps.getNumFilteredApps());
+            record.setFromIndex(Math.max(0,
+                    record.getFromIndex() - getRowsNotForAccessibility(record.getFromIndex())));
+            record.setToIndex(Math.max(0,
+                    record.getToIndex() - getRowsNotForAccessibility(record.getToIndex())));
         }
 
         @Override
         public int getRowCountForAccessibility(RecyclerView.Recycler recycler,
                 RecyclerView.State state) {
-            if (mApps.hasNoFilteredResults()) {
-                // Disregard the no-search-results text as a list item for accessibility
-                return 0;
-            } else {
-                return super.getRowCountForAccessibility(recycler, state);
+            return super.getRowCountForAccessibility(recycler, state) -
+                    getRowsNotForAccessibility(mApps.getAdapterItems().size() - 1);
+        }
+
+        @Override
+        public void onInitializeAccessibilityNodeInfoForItem(RecyclerView.Recycler recycler,
+                RecyclerView.State state, View host, AccessibilityNodeInfoCompat info) {
+            super.onInitializeAccessibilityNodeInfoForItem(recycler, state, host, info);
+
+            ViewGroup.LayoutParams lp = host.getLayoutParams();
+            AccessibilityNodeInfoCompat.CollectionItemInfoCompat cic = info.getCollectionItemInfo();
+            if (!(lp instanceof LayoutParams) || (cic == null)) {
+                return;
             }
+            LayoutParams glp = (LayoutParams) lp;
+            info.setCollectionItemInfo(AccessibilityNodeInfoCompat.CollectionItemInfoCompat.obtain(
+                    cic.getRowIndex() - getRowsNotForAccessibility(glp.getViewAdapterPosition()),
+                    cic.getRowSpan(),
+                    cic.getColumnIndex(),
+                    cic.getColumnSpan(),
+                    cic.isHeading(),
+                    cic.isSelected()));
+        }
+
+        /**
+         * Returns the number of rows before {@param adapterPosition}, including this position
+         * which should not be counted towards the collection info.
+         */
+        private int getRowsNotForAccessibility(int adapterPosition) {
+            List<AdapterItem> items = mApps.getAdapterItems();
+            adapterPosition = Math.max(adapterPosition, mApps.getAdapterItems().size() - 1);
+            int extraRows = 0;
+            for (int i = 0; i <= adapterPosition; i++) {
+                if ((items.get(i).viewType & VIEW_TYPE_MASK_ICON) == 0) {
+                    extraRows++;
+                }
+            }
+            return extraRows;
         }
 
         @Override
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 547ab2b..b436fa2 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -7,7 +7,6 @@
 import android.animation.ArgbEvaluator;
 import android.animation.ObjectAnimator;
 import android.graphics.Color;
-import android.support.v4.content.ContextCompat;
 import android.support.v4.graphics.ColorUtils;
 import android.support.v4.view.animation.FastOutSlowInInterpolator;
 import android.util.Log;
@@ -26,6 +25,7 @@
 import com.android.launcher3.Workspace;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
+import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.TouchController;
 
 /**
@@ -102,7 +102,7 @@
         mProgress = 1f;
 
         mEvaluator = new ArgbEvaluator();
-        mAllAppsBackgroundColor = ContextCompat.getColor(l, R.color.all_apps_container_color);
+        mAllAppsBackgroundColor = Themes.getAttrColor(l, android.R.attr.colorPrimary);
     }
 
     @Override
diff --git a/src/com/android/launcher3/anim/AnimationLayerSet.java b/src/com/android/launcher3/anim/AnimationLayerSet.java
index d2f5e78..14bcd17 100644
--- a/src/com/android/launcher3/anim/AnimationLayerSet.java
+++ b/src/com/android/launcher3/anim/AnimationLayerSet.java
@@ -29,7 +29,16 @@
  */
 public class AnimationLayerSet extends AnimatorListenerAdapter {
 
-    private final HashMap<View, Integer> mViewsToLayerTypeMap = new HashMap<>();
+    private final HashMap<View, Integer> mViewsToLayerTypeMap;
+
+    public AnimationLayerSet() {
+        mViewsToLayerTypeMap = new HashMap<>();
+    }
+
+    public AnimationLayerSet(View v) {
+        mViewsToLayerTypeMap = new HashMap<>(1);
+        addView(v);
+    }
 
     public void addView(View v) {
         mViewsToLayerTypeMap.put(v, v.getLayerType());
diff --git a/src/com/android/launcher3/anim/PropertyListBuilder.java b/src/com/android/launcher3/anim/PropertyListBuilder.java
new file mode 100644
index 0000000..33e7f66
--- /dev/null
+++ b/src/com/android/launcher3/anim/PropertyListBuilder.java
@@ -0,0 +1,50 @@
+package com.android.launcher3.anim;
+
+import android.animation.PropertyValuesHolder;
+import android.view.View;
+
+import java.util.ArrayList;
+
+/**
+ * Helper class to build a list of {@link PropertyValuesHolder} for view properties
+ */
+public class PropertyListBuilder {
+
+    private final ArrayList<PropertyValuesHolder> mProperties = new ArrayList<>();
+
+    public PropertyListBuilder translationX(float value) {
+        mProperties.add(PropertyValuesHolder.ofFloat(View.TRANSLATION_X, value));
+        return this;
+    }
+
+    public PropertyListBuilder translationY(float value) {
+        mProperties.add(PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, value));
+        return this;
+    }
+
+    public PropertyListBuilder scaleX(float value) {
+        mProperties.add(PropertyValuesHolder.ofFloat(View.SCALE_X, value));
+        return this;
+    }
+
+    public PropertyListBuilder scaleY(float value) {
+        mProperties.add(PropertyValuesHolder.ofFloat(View.SCALE_Y, value));
+        return this;
+    }
+
+    /**
+     * Helper method to set both scaleX and scaleY
+     */
+    public PropertyListBuilder scale(float value) {
+        return scaleX(value).scaleY(value);
+    }
+
+    public PropertyListBuilder alpha(float value) {
+        mProperties.add(PropertyValuesHolder.ofFloat(View.ALPHA, value));
+        return this;
+    }
+
+    public PropertyValuesHolder[] build() {
+        return mProperties.toArray(new PropertyValuesHolder[mProperties.size()]);
+    }
+}
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index b9142ed..44a3686 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
 import android.graphics.Rect;
 import android.os.Bundle;
@@ -72,6 +73,7 @@
             UserHandle user);
     public abstract void startActivityForProfile(ComponentName component, UserHandle user,
             Rect sourceBounds, Bundle opts);
+    public abstract ApplicationInfo getApplicationInfo(String packageName, UserHandle user);
     public abstract void showAppDetailsForProfile(ComponentName component, UserHandle user);
     public abstract void addOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
     public abstract void removeOnAppsChangedCallback(OnAppsChangedCallbackCompat listener);
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
index 3cb721c..776f593 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVL.java
@@ -19,6 +19,7 @@
 import android.content.ComponentName;
 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.PackageManager;
@@ -65,6 +66,12 @@
     }
 
     @Override
+    public ApplicationInfo getApplicationInfo(String packageName, UserHandle user) {
+        List<LauncherActivityInfo> activityList = mLauncherApps.getActivityList(packageName, user);
+        return activityList.size() > 0 ? activityList.get(0).getApplicationInfo() : null;
+    }
+
+    @Override
     public void showAppDetailsForProfile(ComponentName component, UserHandle user) {
         mLauncherApps.startAppDetailsActivity(component, user, null, null);
     }
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
index 0610726..377907a 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatVO.java
@@ -17,6 +17,7 @@
 package com.android.launcher3.compat;
 
 import android.content.Context;
+import android.content.pm.ApplicationInfo;
 import android.content.pm.LauncherActivityInfo;
 import android.content.pm.LauncherApps;
 import android.os.UserHandle;
@@ -34,6 +35,11 @@
     }
 
     @Override
+    public ApplicationInfo getApplicationInfo(String packageName, UserHandle user) {
+        return mLauncherApps.getApplicationInfo(packageName, 0, user);
+    }
+
+    @Override
     public List<ShortcutConfigActivityInfo> getCustomShortcutActivityList() {
         List<ShortcutConfigActivityInfo> result = new ArrayList<>();
 
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionService.java b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
index 1a127dc..f94d442 100644
--- a/src/com/android/launcher3/dynamicui/ColorExtractionService.java
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
@@ -98,7 +98,7 @@
                 if (bitmap != null) {
                     return Palette.from(bitmap).clearFilters().generate();
                 }
-            } catch (IOException e) {
+            } catch (IOException | NullPointerException e) {
                 Log.e(TAG, "Fetching partial bitmap failed, trying old method", e);
             }
         }
@@ -129,7 +129,7 @@
                 if (bitmap != null) {
                     return Palette.from(bitmap).clearFilters().generate();
                 }
-            } catch (IOException e) {
+            } catch (IOException | NullPointerException e) {
                 Log.e(TAG, "Fetching partial bitmap failed, trying old method", e);
             }
         }
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index eacea4a..4ad13d0 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -355,7 +355,7 @@
         // gets saved.
         String newTitle = mFolderName.getText().toString();
         mInfo.setTitle(newTitle);
-        LauncherModel.updateItemInDatabase(mLauncher, mInfo);
+        mLauncher.getModelWriter().updateItemInDatabase(mInfo);
 
         Utilities.sendCustomAccessibilityEvent(
                 this, AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
@@ -445,7 +445,7 @@
         // TODO: Remove this, as with multi-page folders, there will never be any overflow
         for (ShortcutInfo item: overflow) {
             mInfo.remove(item, false);
-            LauncherModel.deleteItemFromDatabase(mLauncher, item);
+            mLauncher.getModelWriter().deleteItemFromDatabase(item);
         }
 
         DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();
@@ -535,7 +535,6 @@
         }
 
         mIsOpen = true;
-        mFolderIcon.growAndFadeOut();
 
         mContent.completePendingPageChanges();
         if (!mDragInProgress) {
@@ -552,6 +551,8 @@
         prepareReveal();
         centerAboutIcon();
 
+        mFolderIcon.growAndFadeOut();
+
         AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
         int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
         int height = getFolderHeight();
@@ -647,7 +648,8 @@
                     mPageIndicator.playEntryAnimation();
 
                     if (updateAnimationFlag) {
-                        mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true, mLauncher);
+                        mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true,
+                                mLauncher.getModelWriter());
                     }
                 }
             });
@@ -973,7 +975,8 @@
         // been refreshed yet.
         if (getItemCount() <= mContent.itemsPerPage()) {
             // Show the animation, next time something is added to the folder.
-            mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, false, mLauncher);
+            mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, false,
+                    mLauncher.getModelWriter());
         }
 
         if (!isFlingToDelete) {
@@ -1022,7 +1025,7 @@
             items.add(info);
         }
 
-        LauncherModel.moveItemsInDatabase(mLauncher, items, mInfo.id, 0);
+        mLauncher.getModelWriter().moveItemsInDatabase(items, mInfo.id, 0);
     }
 
     public void notifyDrop() {
@@ -1086,6 +1089,7 @@
         int folderPivotY = height / 2 + (centeredTop - top);
         setPivotX(folderPivotX);
         setPivotY(folderPivotY);
+
         mFolderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() *
                 (1.0f * folderPivotX / width));
         mFolderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() *
@@ -1189,8 +1193,8 @@
                                 mInfo.screenId);
                         ShortcutInfo finalItem = mInfo.contents.remove(0);
                         newIcon = mLauncher.createShortcut(cellLayout, finalItem);
-                        LauncherModel.addOrMoveItemInDatabase(mLauncher, finalItem, mInfo.container,
-                                mInfo.screenId, mInfo.cellX, mInfo.cellY);
+                        mLauncher.getModelWriter().addOrMoveItemInDatabase(finalItem,
+                                mInfo.container, mInfo.screenId, mInfo.cellX, mInfo.cellY);
                     }
 
                     // Remove the folder
@@ -1301,8 +1305,8 @@
             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.
-            LauncherModel.addOrMoveItemInDatabase(
-                    mLauncher, si, mInfo.id, 0, si.cellX, si.cellY);
+            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) {
@@ -1342,7 +1346,7 @@
 
         if (mContent.getPageCount() > 1) {
             // The animation has already been shown while opening the folder.
-            mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true, mLauncher);
+            mInfo.setOption(FolderInfo.FLAG_MULTI_PAGE_ANIMATION, true, mLauncher.getModelWriter());
         }
 
         if (d.stateAnnouncer != null) {
@@ -1366,8 +1370,8 @@
     public void onAdd(ShortcutInfo item) {
         mContent.createAndAddViewForRank(item, mContent.allocateRankForNewItem());
         mItemsInvalidated = true;
-        LauncherModel.addOrMoveItemInDatabase(
-                mLauncher, item, mInfo.id, 0, item.cellX, item.cellY);
+        mLauncher.getModelWriter().addOrMoveItemInDatabase(
+                item, mInfo.id, 0, item.cellX, item.cellY);
     }
 
     public void onRemove(ShortcutInfo item) {
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index 4a2a735..eecce18 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -45,6 +45,7 @@
 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;
@@ -107,7 +108,7 @@
         mIsRtl = Utilities.isRtl(getResources());
         setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES);
 
-        setEdgeGlowColor(getResources().getColor(R.color.folder_edge_effect_color));
+        setEdgeGlowColor(Themes.getAttrColor(context, android.R.attr.colorEdgeEffect));
         mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
     }
 
@@ -336,7 +337,7 @@
                     info.cellY = newY;
                     info.rank = rank;
                     if (saveChanges) {
-                        LauncherModel.addOrMoveItemInDatabase(getContext(), info,
+                        mFolder.mLauncher.getModelWriter().addOrMoveItemInDatabase(info,
                                 mFolder.mInfo.id, 0, info.cellX, info.cellY);
                     }
                 }
diff --git a/src/com/android/launcher3/graphics/DrawableFactory.java b/src/com/android/launcher3/graphics/DrawableFactory.java
index 2493447..8b207bb 100644
--- a/src/com/android/launcher3/graphics/DrawableFactory.java
+++ b/src/com/android/launcher3/graphics/DrawableFactory.java
@@ -77,7 +77,7 @@
         if (mPreloadProgressPath == null) {
             mPreloadProgressPath = getPreloadProgressPath(context);
         }
-        return new PreloadIconDrawable(icon, mPreloadProgressPath);
+        return new PreloadIconDrawable(icon, mPreloadProgressPath, context);
     }
 
 
diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java
index 7cb69b3..23c6a12 100644
--- a/src/com/android/launcher3/graphics/IconPalette.java
+++ b/src/com/android/launcher3/graphics/IconPalette.java
@@ -23,6 +23,8 @@
 import android.util.Log;
 
 import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.util.Themes;
 
 /**
  * Contains colors based on the dominant color of an icon.
@@ -36,7 +38,6 @@
 
     private static final float MIN_PRELOAD_COLOR_SATURATION = 0.2f;
     private static final float MIN_PRELOAD_COLOR_LIGHTNESS = 0.6f;
-    private static final int DEFAULT_PRELOAD_COLOR = 0xFF009688;
 
     public final int dominantColor;
     public final int backgroundColor;
@@ -53,14 +54,14 @@
     /**
      * Returns a color suitable for the progress bar color of preload icon.
      */
-    public int getPreloadProgressColor() {
+    public int getPreloadProgressColor(Context context) {
         int result = dominantColor;
 
         // Make sure that the dominant color has enough saturation to be visible properly.
         float[] hsv = new float[3];
         Color.colorToHSV(result, hsv);
         if (hsv[1] < MIN_PRELOAD_COLOR_SATURATION) {
-            result = DEFAULT_PRELOAD_COLOR;
+            result = Themes.getColorAccent(context);
         } else {
             hsv[2] = Math.max(MIN_PRELOAD_COLOR_LIGHTNESS, hsv[2]);
             result = Color.HSVToColor(hsv);
diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
index bc07ce1..3514a37 100644
--- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java
+++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java
@@ -20,6 +20,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
+import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
@@ -75,6 +76,8 @@
     private final Matrix mTmpMatrix = new Matrix();
     private final PathMeasure mPathMeasure = new PathMeasure();
 
+    private final Context mContext;
+
     // Path in [0, 100] bounds.
     private final Path mProgressPath;
 
@@ -100,8 +103,9 @@
     /**
      * @param progressPath fixed path in the bounds [0, 0, 100, 100] representing a progress bar.
      */
-    public PreloadIconDrawable(Bitmap b, Path progressPath) {
+    public PreloadIconDrawable(Bitmap b, Path progressPath, Context context) {
         super(b);
+        mContext = context;
         mProgressPath = progressPath;
         mScaledTrackPath = new Path();
         mScaledProgressPath = new Path();
@@ -262,7 +266,7 @@
             setIsDisabled(true);
         } else if (mIndicatorColor == 0) {
             // Update the indicator color
-            mIndicatorColor = getIconPalette().getPreloadProgressColor();
+            mIndicatorColor = getIconPalette().getPreloadProgressColor(mContext);
         }
 
         if (progress < 1 && progress > 0) {
diff --git a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
index c97b3b5..9696054 100644
--- a/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
+++ b/src/com/android/launcher3/model/AddWorkspaceItemsTask.java
@@ -95,7 +95,9 @@
                 }
 
                 // Add the shortcut to the db
-                addItemToDatabase(context, itemInfo, screenId, cordinates);
+                getModelWriter().addItemToDatabase(itemInfo,
+                        LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId,
+                        cordinates[0], cordinates[1]);
 
                 // Save the ShortcutInfo for binding in the workspace
                 addedItemsFinal.add(itemInfo);
@@ -129,11 +131,6 @@
         }
     }
 
-    protected void addItemToDatabase(Context context, ItemInfo item, long screenId, int[] pos) {
-        LauncherModel.addItemToDatabase(context, item,
-                LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId, pos[0], pos[1]);
-    }
-
     protected void updateScreens(Context context, ArrayList<Long> workspaceScreens) {
         LauncherModel.updateWorkspaceScreenOrder(context, workspaceScreens);
     }
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
index bbc7ae4..e50b912 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTask.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -27,6 +27,7 @@
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.logging.FileLog;
 import com.android.launcher3.util.GridOccupancy;
 import com.android.launcher3.util.LongArrayMap;
 
@@ -889,6 +890,23 @@
                 .apply();
     }
 
+    public static void logDeviceProfileIfChanged(InvariantDeviceProfile idp, Context context) {
+        SharedPreferences prefs = Utilities.getPrefs(context);
+        String gridSizeString = getPointString(idp.numColumns, idp.numRows);
+
+        int oldHotseatCount = prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons);
+        String oldSize = prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString);
+        if (gridSizeString.equals(oldSize) && idp.numHotseatIcons == oldHotseatCount) {
+            // Skip if workspace and hotseat sizes have not changed.
+            return;
+        }
+
+        FileLog.e(TAG, "Grid size changed" + gridSizeString);
+        FileLog.e(TAG, "   oldSize: " + oldSize + "  , hotseat: " + oldHotseatCount);
+        FileLog.e(TAG, "   newSize: " + gridSizeString + "  , hotseat: " + idp.numHotseatIcons);
+        idp.dumpDisplayInfo(context);
+    }
+
     /**
      * Migrates the workspace and hotseat in case their sizes changed.
      * @return false if the migration failed.
@@ -900,7 +918,7 @@
         String gridSizeString = getPointString(idp.numColumns, idp.numRows);
 
         if (gridSizeString.equals(prefs.getString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, "")) &&
-                idp.numHotseatIcons != prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons)) {
+                idp.numHotseatIcons == prefs.getInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons)) {
             // Skip if workspace and hotseat sizes have not changed.
             return true;
         }
diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java
new file mode 100644
index 0000000..4931dca
--- /dev/null
+++ b/src/com/android/launcher3/model/ModelWriter.java
@@ -0,0 +1,374 @@
+/*
+ * 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.ContentProviderOperation;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.util.Log;
+
+import com.android.launcher3.FolderInfo;
+import com.android.launcher3.ItemInfo;
+import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherModel;
+import com.android.launcher3.LauncherProvider;
+import com.android.launcher3.LauncherSettings;
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.Settings;
+import com.android.launcher3.ShortcutInfo;
+import com.android.launcher3.util.ContentWriter;
+import com.android.launcher3.util.ItemInfoMatcher;
+import com.android.launcher3.util.LooperExecuter;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.concurrent.Executor;
+
+/**
+ * Class for handling model updates.
+ */
+public class ModelWriter {
+
+    private static final String TAG = "ModelWriter";
+
+    private final Context mContext;
+    private final BgDataModel mBgDataModel;
+    private final Executor mWorkerExecutor;
+    private final boolean mHasVerticalHotseat;
+
+    public ModelWriter(Context context, BgDataModel dataModel, boolean hasVerticalHotseat) {
+        mContext = context;
+        mBgDataModel = dataModel;
+        mWorkerExecutor = new LooperExecuter(LauncherModel.getWorkerLooper());
+        mHasVerticalHotseat = hasVerticalHotseat;
+    }
+
+    private void updateItemInfoProps(
+            ItemInfo item, long container, long screenId, int cellX, int cellY) {
+        item.container = container;
+        item.cellX = cellX;
+        item.cellY = cellY;
+        // We store hotseat items in canonical form which is this orientation invariant position
+        // in the hotseat
+        if (container == Favorites.CONTAINER_HOTSEAT) {
+            item.screenId = mHasVerticalHotseat
+                    ? LauncherAppState.getIDP(mContext).numHotseatIcons - cellY - 1 : cellX;
+        } else {
+            item.screenId = screenId;
+        }
+    }
+
+    /**
+     * Adds an item to the DB if it was not created previously, or move it to a new
+     * <container, screen, cellX, cellY>
+     */
+    public void addOrMoveItemInDatabase(ItemInfo item,
+            long container, long screenId, int cellX, int cellY) {
+        if (item.container == ItemInfo.NO_ID) {
+            // From all apps
+            addItemToDatabase(item, container, screenId, cellX, cellY);
+        } else {
+            // From somewhere else
+            moveItemInDatabase(item, container, screenId, cellX, cellY);
+        }
+    }
+
+    private void checkItemInfoLocked(long itemId, ItemInfo item, StackTraceElement[] stackTrace) {
+        ItemInfo modelItem = mBgDataModel.itemsIdMap.get(itemId);
+        if (modelItem != null && item != modelItem) {
+            // check all the data is consistent
+            if (modelItem instanceof ShortcutInfo && item instanceof ShortcutInfo) {
+                ShortcutInfo modelShortcut = (ShortcutInfo) modelItem;
+                ShortcutInfo shortcut = (ShortcutInfo) item;
+                if (modelShortcut.title.toString().equals(shortcut.title.toString()) &&
+                        modelShortcut.intent.filterEquals(shortcut.intent) &&
+                        modelShortcut.id == shortcut.id &&
+                        modelShortcut.itemType == shortcut.itemType &&
+                        modelShortcut.container == shortcut.container &&
+                        modelShortcut.screenId == shortcut.screenId &&
+                        modelShortcut.cellX == shortcut.cellX &&
+                        modelShortcut.cellY == shortcut.cellY &&
+                        modelShortcut.spanX == shortcut.spanX &&
+                        modelShortcut.spanY == shortcut.spanY) {
+                    // For all intents and purposes, this is the same object
+                    return;
+                }
+            }
+
+            // the modelItem needs to match up perfectly with item if our model is
+            // to be consistent with the database-- for now, just require
+            // modelItem == item or the equality check above
+            String msg = "item: " + ((item != null) ? item.toString() : "null") +
+                    "modelItem: " +
+                    ((modelItem != null) ? modelItem.toString() : "null") +
+                    "Error: ItemInfo passed to checkItemInfo doesn't match original";
+            RuntimeException e = new RuntimeException(msg);
+            if (stackTrace != null) {
+                e.setStackTrace(stackTrace);
+            }
+            throw e;
+        }
+    }
+
+    /**
+     * Move an item in the DB to a new <container, screen, cellX, cellY>
+     */
+    public void moveItemInDatabase(final ItemInfo item,
+            long container, long screenId, int cellX, int cellY) {
+        updateItemInfoProps(item, container, screenId, cellX, cellY);
+
+        final ContentWriter writer = new ContentWriter(mContext)
+                .put(Favorites.CONTAINER, item.container)
+                .put(Favorites.CELLX, item.cellX)
+                .put(Favorites.CELLY, item.cellY)
+                .put(Favorites.RANK, item.rank)
+                .put(Favorites.SCREEN, item.screenId);
+
+        mWorkerExecutor.execute(new UpdateItemRunnable(item, writer));
+    }
+
+    /**
+     * Move items in the DB to a new <container, screen, cellX, cellY>. We assume that the
+     * cellX, cellY have already been updated on the ItemInfos.
+     */
+    public void moveItemsInDatabase(final ArrayList<ItemInfo> items, long container, int screen) {
+        ArrayList<ContentValues> contentValues = new ArrayList<>();
+        int count = items.size();
+
+        for (int i = 0; i < count; i++) {
+            ItemInfo item = items.get(i);
+            updateItemInfoProps(item, container, screen, item.cellX, item.cellY);
+
+            final ContentValues values = new ContentValues();
+            values.put(Favorites.CONTAINER, item.container);
+            values.put(Favorites.CELLX, item.cellX);
+            values.put(Favorites.CELLY, item.cellY);
+            values.put(Favorites.RANK, item.rank);
+            values.put(Favorites.SCREEN, item.screenId);
+
+            contentValues.add(values);
+        }
+        mWorkerExecutor.execute(new UpdateItemsRunnable(items, contentValues));
+    }
+
+    /**
+     * Move and/or resize item in the DB to a new <container, screen, cellX, cellY, spanX, spanY>
+     */
+    public void modifyItemInDatabase(final ItemInfo item,
+            long container, long screenId, int cellX, int cellY, int spanX, int spanY) {
+        updateItemInfoProps(item, container, screenId, cellX, cellY);
+        item.spanX = spanX;
+        item.spanY = spanY;
+
+        final ContentWriter writer = new ContentWriter(mContext)
+                .put(Favorites.CONTAINER, item.container)
+                .put(Favorites.CELLX, item.cellX)
+                .put(Favorites.CELLY, item.cellY)
+                .put(Favorites.RANK, item.rank)
+                .put(Favorites.SPANX, item.spanX)
+                .put(Favorites.SPANY, item.spanY)
+                .put(Favorites.SCREEN, item.screenId);
+
+        mWorkerExecutor.execute(new UpdateItemRunnable(item, writer));
+    }
+
+    /**
+     * Update an item to the database in a specified container.
+     */
+    public void updateItemInDatabase(ItemInfo item) {
+        ContentWriter writer = new ContentWriter(mContext);
+        item.onAddToDatabase(writer);
+        mWorkerExecutor.execute(new UpdateItemRunnable(item, writer));
+    }
+
+    /**
+     * Add an item to the database in a specified container. Sets the container, screen, cellX and
+     * cellY fields of the item. Also assigns an ID to the item.
+     */
+    public void addItemToDatabase(final ItemInfo item,
+            long container, long screenId, int cellX, int cellY) {
+        updateItemInfoProps(item, container, screenId, cellX, cellY);
+
+        final ContentWriter writer = new ContentWriter(mContext);
+        final ContentResolver cr = mContext.getContentResolver();
+        item.onAddToDatabase(writer);
+
+        item.id = Settings.call(cr, Settings.METHOD_NEW_ITEM_ID).getLong(Settings.EXTRA_VALUE);
+        writer.put(Favorites._ID, item.id);
+
+        final StackTraceElement[] stackTrace = new Throwable().getStackTrace();
+        mWorkerExecutor.execute(new Runnable() {
+            public void run() {
+                cr.insert(Favorites.CONTENT_URI, writer.getValues(mContext));
+
+                synchronized (mBgDataModel) {
+                    checkItemInfoLocked(item.id, item, stackTrace);
+                    mBgDataModel.addItem(mContext, item, true);
+                }
+            }
+        });
+    }
+
+    /**
+     * Removes the specified item from the database
+     */
+    public void deleteItemFromDatabase(ItemInfo item) {
+        deleteItemsFromDatabase(Arrays.asList(item));
+    }
+
+    /**
+     * Removes all the items from the database matching {@param matcher}.
+     */
+    public void deleteItemsFromDatabase(ItemInfoMatcher matcher) {
+        deleteItemsFromDatabase(matcher.filterItemInfos(mBgDataModel.itemsIdMap));
+    }
+
+    /**
+     * Removes the specified items from the database
+     */
+    public void deleteItemsFromDatabase(final Iterable<? extends ItemInfo> items) {
+        mWorkerExecutor.execute(new Runnable() {
+            public void run() {
+                for (ItemInfo item : items) {
+                    final Uri uri = Favorites.getContentUri(item.id);
+                    mContext.getContentResolver().delete(uri, null, null);
+
+                    mBgDataModel.removeItem(mContext, item);
+                }
+            }
+        });
+    }
+
+    /**
+     * Remove the specified folder and all its contents from the database.
+     */
+    public void deleteFolderAndContentsFromDatabase(final FolderInfo info) {
+        mWorkerExecutor.execute(new Runnable() {
+            public void run() {
+                ContentResolver cr = mContext.getContentResolver();
+                cr.delete(LauncherSettings.Favorites.CONTENT_URI,
+                        LauncherSettings.Favorites.CONTAINER + "=" + info.id, null);
+                mBgDataModel.removeItem(mContext, info.contents);
+                info.contents.clear();
+
+                cr.delete(LauncherSettings.Favorites.getContentUri(info.id), null, null);
+                mBgDataModel.removeItem(mContext, info);
+            }
+        });
+    }
+
+    private class UpdateItemRunnable extends UpdateItemBaseRunnable {
+        private final ItemInfo mItem;
+        private final ContentWriter mWriter;
+        private final long mItemId;
+
+        UpdateItemRunnable(ItemInfo item, ContentWriter writer) {
+            mItem = item;
+            mWriter = writer;
+            mItemId = item.id;
+        }
+
+        @Override
+        public void run() {
+            Uri uri = Favorites.getContentUri(mItemId);
+            mContext.getContentResolver().update(uri, mWriter.getValues(mContext), null, null);
+            updateItemArrays(mItem, mItemId);
+        }
+    }
+
+    private class UpdateItemsRunnable extends UpdateItemBaseRunnable {
+        private final ArrayList<ContentValues> mValues;
+        private final ArrayList<ItemInfo> mItems;
+
+        UpdateItemsRunnable(ArrayList<ItemInfo> items, ArrayList<ContentValues> values) {
+            mValues = values;
+            mItems = items;
+        }
+
+        @Override
+        public void run() {
+            ArrayList<ContentProviderOperation> ops = new ArrayList<>();
+            int count = mItems.size();
+            for (int i = 0; i < count; i++) {
+                ItemInfo item = mItems.get(i);
+                final long itemId = item.id;
+                final Uri uri = Favorites.getContentUri(itemId);
+                ContentValues values = mValues.get(i);
+
+                ops.add(ContentProviderOperation.newUpdate(uri).withValues(values).build());
+                updateItemArrays(item, itemId);
+            }
+            try {
+                mContext.getContentResolver().applyBatch(LauncherProvider.AUTHORITY, ops);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    private abstract class UpdateItemBaseRunnable implements Runnable {
+        private final StackTraceElement[] mStackTrace;
+
+        UpdateItemBaseRunnable() {
+            mStackTrace = new Throwable().getStackTrace();
+        }
+
+        protected void updateItemArrays(ItemInfo item, long itemId) {
+            // Lock on mBgLock *after* the db operation
+            synchronized (mBgDataModel) {
+                checkItemInfoLocked(itemId, item, mStackTrace);
+
+                if (item.container != Favorites.CONTAINER_DESKTOP &&
+                        item.container != Favorites.CONTAINER_HOTSEAT) {
+                    // Item is in a folder, make sure this folder exists
+                    if (!mBgDataModel.folders.containsKey(item.container)) {
+                        // An items container is being set to a that of an item which is not in
+                        // the list of Folders.
+                        String msg = "item: " + item + " container being set to: " +
+                                item.container + ", not in the list of folders";
+                        Log.e(TAG, msg);
+                    }
+                }
+
+                // Items are added/removed from the corresponding FolderInfo elsewhere, such
+                // as in Workspace.onDrop. Here, we just add/remove them from the list of items
+                // that are on the desktop, as appropriate
+                ItemInfo modelItem = mBgDataModel.itemsIdMap.get(itemId);
+                if (modelItem != null &&
+                        (modelItem.container == Favorites.CONTAINER_DESKTOP ||
+                                modelItem.container == Favorites.CONTAINER_HOTSEAT)) {
+                    switch (modelItem.itemType) {
+                        case Favorites.ITEM_TYPE_APPLICATION:
+                        case Favorites.ITEM_TYPE_SHORTCUT:
+                        case Favorites.ITEM_TYPE_DEEP_SHORTCUT:
+                        case Favorites.ITEM_TYPE_FOLDER:
+                            if (!mBgDataModel.workspaceItems.contains(modelItem)) {
+                                mBgDataModel.workspaceItems.add(modelItem);
+                            }
+                            break;
+                        default:
+                            break;
+                    }
+                } else {
+                    mBgDataModel.workspaceItems.remove(modelItem);
+                }
+            }
+        }
+    }
+}
diff --git a/src/com/android/launcher3/model/PackageUpdatedTask.java b/src/com/android/launcher3/model/PackageUpdatedTask.java
index 211b979..ee7186a 100644
--- a/src/com/android/launcher3/model/PackageUpdatedTask.java
+++ b/src/com/android/launcher3/model/PackageUpdatedTask.java
@@ -270,7 +270,7 @@
                             updatedShortcuts.add(si);
                         }
                         if (infoUpdated) {
-                            LauncherModel.updateItemInDatabase(context, si);
+                            getModelWriter().updateItemInDatabase(si);
                         }
                     } else if (info instanceof LauncherAppWidgetInfo && mOp == OP_ADD) {
                         LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info;
@@ -287,7 +287,7 @@
                             widgetInfo.restoreStatus |= LauncherAppWidgetInfo.FLAG_UI_NOT_READY;
 
                             widgets.add(widgetInfo);
-                            LauncherModel.updateItemInDatabase(context, widgetInfo);
+                            getModelWriter().updateItemInDatabase(widgetInfo);
                         }
                     }
                 }
@@ -295,7 +295,7 @@
 
             bindUpdatedShortcuts(updatedShortcuts, removedShortcuts, mUser);
             if (!removedShortcuts.isEmpty()) {
-                LauncherModel.deleteItemsFromDatabase(context, removedShortcuts);
+                getModelWriter().deleteItemsFromDatabase(removedShortcuts);
             }
 
             if (!widgets.isEmpty()) {
@@ -332,10 +332,10 @@
         }
 
         if (!removedPackages.isEmpty() || !removedComponents.isEmpty()) {
-            LauncherModel.deleteItemsFromDatabase(
-                    context, ItemInfoMatcher.ofPackages(removedPackages, mUser));
-            LauncherModel.deleteItemsFromDatabase(
-                    context, ItemInfoMatcher.ofComponents(removedComponents, mUser));
+            getModelWriter().deleteItemsFromDatabase(
+                    ItemInfoMatcher.ofPackages(removedPackages, mUser));
+            getModelWriter().deleteItemsFromDatabase(
+                    ItemInfoMatcher.ofComponents(removedComponents, mUser));
 
             // Remove any queued items from the install queue
             InstallShortcutReceiver.removeFromInstallQueue(context, removedPackages, mUser);
diff --git a/src/com/android/launcher3/model/ShortcutsChangedTask.java b/src/com/android/launcher3/model/ShortcutsChangedTask.java
index ba7112f..d8a429c 100644
--- a/src/com/android/launcher3/model/ShortcutsChangedTask.java
+++ b/src/com/android/launcher3/model/ShortcutsChangedTask.java
@@ -104,7 +104,7 @@
 
         bindUpdatedShortcuts(updatedShortcutInfos, removedShortcutInfos, mUser);
         if (!removedShortcutInfos.isEmpty()) {
-            LauncherModel.deleteItemsFromDatabase(context, removedShortcutInfos);
+            getModelWriter().deleteItemsFromDatabase(removedShortcutInfos);
         }
 
         if (mUpdateIdMap) {
diff --git a/src/com/android/launcher3/model/UserLockStateChangedTask.java b/src/com/android/launcher3/model/UserLockStateChangedTask.java
index 25f2f9d..363f1ee 100644
--- a/src/com/android/launcher3/model/UserLockStateChangedTask.java
+++ b/src/com/android/launcher3/model/UserLockStateChangedTask.java
@@ -95,7 +95,7 @@
         }
         bindUpdatedShortcuts(updatedShortcutInfos, deletedShortcutInfos, mUser);
         if (!deletedShortcutInfos.isEmpty()) {
-            LauncherModel.deleteItemsFromDatabase(context, deletedShortcutInfos);
+            getModelWriter().deleteItemsFromDatabase(deletedShortcutInfos);
         }
 
         // Remove shortcut id map for that user
diff --git a/src/com/android/launcher3/notification/NotificationFooterLayout.java b/src/com/android/launcher3/notification/NotificationFooterLayout.java
index 58789f6..57ec5d1 100644
--- a/src/com/android/launcher3/notification/NotificationFooterLayout.java
+++ b/src/com/android/launcher3/notification/NotificationFooterLayout.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.Rect;
@@ -30,8 +31,8 @@
 
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAnimUtils;
-import com.android.launcher3.LauncherViewPropertyAnimator;
 import com.android.launcher3.R;
+import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.graphics.IconPalette;
 import com.android.launcher3.popup.PopupContainerWithArrow;
 
@@ -154,10 +155,9 @@
         Rect fromBounds = sTempRect;
         firstNotification.getGlobalVisibleRect(fromBounds);
         float scale = (float) toBounds.height() / fromBounds.height();
-        Animator moveAndScaleIcon = new LauncherViewPropertyAnimator(firstNotification)
-                .translationY(toBounds.top - fromBounds.top
-                        + (fromBounds.height() * scale - fromBounds.height()) / 2)
-                .scaleX(scale).scaleY(scale);
+        Animator moveAndScaleIcon = LauncherAnimUtils.ofPropertyValuesHolder(firstNotification,
+                new PropertyListBuilder().scale(scale).translationY(toBounds.top - fromBounds.top
+                        + (fromBounds.height() * scale - fromBounds.height()) / 2).build());
         moveAndScaleIcon.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
@@ -172,7 +172,7 @@
                 - (mOverflowNotifications.isEmpty() ? 0 : 1);
         for (int i = 1; i < numIcons; i++) {
             final View child = mIconRow.getChildAt(i);
-            Animator shiftChild = new LauncherViewPropertyAnimator(child).translationX(-gapWidth);
+            Animator shiftChild = ObjectAnimator.ofFloat(child, TRANSLATION_X, -gapWidth);
             shiftChild.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
index 639447d..c9b3940 100644
--- a/src/com/android/launcher3/notification/NotificationItemView.java
+++ b/src/com/android/launcher3/notification/NotificationItemView.java
@@ -83,12 +83,20 @@
 
     @Override
     public boolean onInterceptTouchEvent(MotionEvent ev) {
+        if (mMainView.getNotificationInfo() == null) {
+            // The notification hasn't been populated yet.
+            return false;
+        }
         getParent().requestDisallowInterceptTouchEvent(true);
         return mSwipeHelper.onInterceptTouchEvent(ev);
     }
 
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
+        if (mMainView.getNotificationInfo() == null) {
+            // The notification hasn't been populated yet.
+            return false;
+        }
         return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev);
     }
 
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index 206bb31..a627d23 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -40,7 +40,7 @@
  * A {@link NotificationListenerService} that sends updates to its
  * {@link NotificationsChangedListener} when notifications are posted or canceled,
  * as well and when this service first connects. An instance of NotificationListener,
- * and its methods for getting notifications, can be obtained via {@link #getInstance()}.
+ * and its methods for getting notifications, can be obtained via {@link #getInstanceIfConnected()}.
  */
 public class NotificationListener extends NotificationListenerService {
 
@@ -50,6 +50,7 @@
 
     private static NotificationListener sNotificationListenerInstance = null;
     private static NotificationsChangedListener sNotificationsChangedListener;
+    private static boolean sIsConnected;
 
     private final Handler mWorkerHandler;
     private final Handler mUiHandler;
@@ -65,8 +66,9 @@
                     mUiHandler.obtainMessage(message.what, message.obj).sendToTarget();
                     break;
                 case MSG_NOTIFICATION_FULL_REFRESH:
-                    final List<StatusBarNotification> activeNotifications
-                            = filterNotifications(getActiveNotifications());
+                    final List<StatusBarNotification> activeNotifications = sIsConnected
+                            ? filterNotifications(getActiveNotifications())
+                            : new ArrayList<StatusBarNotification>();
                     mUiHandler.obtainMessage(message.what, activeNotifications).sendToTarget();
                     break;
             }
@@ -80,9 +82,9 @@
             switch (message.what) {
                 case MSG_NOTIFICATION_POSTED:
                     if (sNotificationsChangedListener != null) {
-                        Pair<PackageUserKey, String> pair
-                                = (Pair<PackageUserKey, String>) message.obj;
-                        sNotificationsChangedListener.onNotificationPosted(pair.first, pair.second);
+                        NotificationPostedMsg msg = (NotificationPostedMsg) message.obj;
+                        sNotificationsChangedListener.onNotificationPosted(msg.packageUserKey,
+                                msg.notificationKey, msg.shouldBeFilteredOut);
                     }
                     break;
                 case MSG_NOTIFICATION_REMOVED:
@@ -107,10 +109,11 @@
         super();
         mWorkerHandler = new Handler(LauncherModel.getWorkerLooper(), mWorkerCallback);
         mUiHandler = new Handler(Looper.getMainLooper(), mUiCallback);
+        sNotificationListenerInstance = this;
     }
 
-    public static @Nullable NotificationListener getInstance() {
-        return sNotificationListenerInstance;
+    public static @Nullable NotificationListener getInstanceIfConnected() {
+        return sIsConnected ? sNotificationListenerInstance : null;
     }
 
     public static void setNotificationsChangedListener(NotificationsChangedListener listener) {
@@ -119,9 +122,8 @@
         }
         sNotificationsChangedListener = listener;
 
-        NotificationListener notificationListener = getInstance();
-        if (notificationListener != null) {
-            notificationListener.onNotificationFullRefresh();
+        if (sNotificationListenerInstance != null) {
+            sNotificationListenerInstance.onNotificationFullRefresh();
         }
     }
 
@@ -132,7 +134,7 @@
     @Override
     public void onListenerConnected() {
         super.onListenerConnected();
-        sNotificationListenerInstance = this;
+        sIsConnected = true;
         onNotificationFullRefresh();
     }
 
@@ -143,29 +145,38 @@
     @Override
     public void onListenerDisconnected() {
         super.onListenerDisconnected();
-        sNotificationListenerInstance = null;
+        sIsConnected = false;
     }
 
     @Override
     public void onNotificationPosted(final StatusBarNotification sbn) {
         super.onNotificationPosted(sbn);
-        if (!shouldBeFilteredOut(sbn.getNotification())) {
-            Pair<PackageUserKey, String> packageUserKeyAndNotificationKey
-                    = new Pair<>(PackageUserKey.fromNotification(sbn), sbn.getKey());
-            mWorkerHandler.obtainMessage(MSG_NOTIFICATION_POSTED, packageUserKeyAndNotificationKey)
-                    .sendToTarget();
+        mWorkerHandler.obtainMessage(MSG_NOTIFICATION_POSTED, new NotificationPostedMsg(sbn))
+                .sendToTarget();
+    }
+
+    /**
+     * An object containing data to send to MSG_NOTIFICATION_POSTED targets.
+     */
+    private class NotificationPostedMsg {
+        PackageUserKey packageUserKey;
+        String notificationKey;
+        boolean shouldBeFilteredOut;
+
+        NotificationPostedMsg(StatusBarNotification sbn) {
+            packageUserKey = PackageUserKey.fromNotification(sbn);
+            notificationKey = sbn.getKey();
+            shouldBeFilteredOut = shouldBeFilteredOut(sbn.getNotification());
         }
     }
 
     @Override
     public void onNotificationRemoved(final StatusBarNotification sbn) {
         super.onNotificationRemoved(sbn);
-        if (!shouldBeFilteredOut(sbn.getNotification())) {
-            Pair<PackageUserKey, String> packageUserKeyAndNotificationKey
-                    = new Pair<>(PackageUserKey.fromNotification(sbn), sbn.getKey());
-            mWorkerHandler.obtainMessage(MSG_NOTIFICATION_REMOVED, packageUserKeyAndNotificationKey)
-                    .sendToTarget();
-        }
+        Pair<PackageUserKey, String> packageUserKeyAndNotificationKey
+                = new Pair<>(PackageUserKey.fromNotification(sbn), sbn.getKey());
+        mWorkerHandler.obtainMessage(MSG_NOTIFICATION_REMOVED, packageUserKeyAndNotificationKey)
+                .sendToTarget();
     }
 
     /** This makes a potentially expensive binder call and should be run on a background thread. */
@@ -206,7 +217,8 @@
     }
 
     public interface NotificationsChangedListener {
-        void onNotificationPosted(PackageUserKey postedPackageUserKey, String notificationKey);
+        void onNotificationPosted(PackageUserKey postedPackageUserKey, String notificationKey,
+                boolean shouldBeFilteredOut);
         void onNotificationRemoved(PackageUserKey removedPackageUserKey, String notificationKey);
         void onNotificationFullRefresh(List<StatusBarNotification> activeNotifications);
     }
diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java
index 6677c2f..b342525 100644
--- a/src/com/android/launcher3/notification/NotificationMainView.java
+++ b/src/com/android/launcher3/notification/NotificationMainView.java
@@ -18,8 +18,11 @@
 
 import android.animation.Animator;
 import android.animation.AnimatorSet;
+import android.animation.ArgbEvaluator;
+import android.animation.ObjectAnimator;
 import android.animation.ValueAnimator;
 import android.content.Context;
+import android.graphics.drawable.ColorDrawable;
 import android.util.AttributeSet;
 import android.view.MotionEvent;
 import android.view.View;
@@ -29,7 +32,6 @@
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAnimUtils;
-import com.android.launcher3.LauncherViewPropertyAnimator;
 import com.android.launcher3.R;
 import com.android.launcher3.graphics.IconPalette;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -39,10 +41,13 @@
  */
 public class NotificationMainView extends LinearLayout implements SwipeHelper.Callback {
 
+    private final ArgbEvaluator mArgbEvaluator = new ArgbEvaluator();
+
     private NotificationInfo mNotificationInfo;
     private TextView mTitleView;
     private TextView mTextView;
     private IconPalette mIconPalette;
+    private ColorDrawable mColorBackground;
 
     public NotificationMainView(Context context) {
         this(context, null, 0);
@@ -65,7 +70,8 @@
     }
 
     public void applyColors(IconPalette iconPalette) {
-        setBackgroundColor(iconPalette.backgroundColor);
+        mColorBackground = new ColorDrawable(iconPalette.backgroundColor);
+        setBackground(mColorBackground);
         mIconPalette = iconPalette;
     }
 
@@ -81,7 +87,7 @@
         if (animate) {
             mTitleView.setAlpha(0);
             mTextView.setAlpha(0);
-            setBackgroundColor(mIconPalette.secondaryColor);
+            mColorBackground.setColor(mIconPalette.secondaryColor);
         }
         mNotificationInfo = mainNotification;
         mTitleView.setText(mNotificationInfo.title);
@@ -95,16 +101,10 @@
         setTag(new ItemInfo());
         if (animate) {
             AnimatorSet animation = LauncherAnimUtils.createAnimatorSet();
-            Animator textFade = new LauncherViewPropertyAnimator(mTextView).alpha(1);
-            Animator titleFade = new LauncherViewPropertyAnimator(mTitleView).alpha(1);
-            ValueAnimator colorChange = ValueAnimator.ofArgb(mIconPalette.secondaryColor,
-                    mIconPalette.backgroundColor);
-            colorChange.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
-                @Override
-                public void onAnimationUpdate(ValueAnimator valueAnimator) {
-                    setBackgroundColor((Integer) valueAnimator.getAnimatedValue());
-                }
-            });
+            Animator textFade = ObjectAnimator.ofFloat(mTextView, View.ALPHA, 1);
+            Animator titleFade = ObjectAnimator.ofFloat(mTitleView, View.ALPHA, 1);
+            ValueAnimator colorChange = ObjectAnimator.ofObject(mColorBackground, "color",
+                    mArgbEvaluator, mIconPalette.secondaryColor, mIconPalette.backgroundColor);
             animation.playTogether(textFade, titleFade, colorChange);
             animation.setDuration(150);
             animation.start();
diff --git a/src/com/android/launcher3/pageindicators/CaretDrawable.java b/src/com/android/launcher3/pageindicators/CaretDrawable.java
index 4789f69..0a00e24 100644
--- a/src/com/android/launcher3/pageindicators/CaretDrawable.java
+++ b/src/com/android/launcher3/pageindicators/CaretDrawable.java
@@ -24,6 +24,7 @@
 import android.graphics.PixelFormat;
 
 import com.android.launcher3.R;
+import com.android.launcher3.util.Themes;
 
 import android.graphics.drawable.Drawable;
 
@@ -45,14 +46,15 @@
         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.all_apps_caret_color));
+        mCaretPaint.setColor(res.getColor(R.color.workspace_icon_text_color));
         mCaretPaint.setAntiAlias(true);
         mCaretPaint.setStrokeWidth(strokeWidth);
         mCaretPaint.setStyle(Paint.Style.STROKE);
         mCaretPaint.setStrokeCap(Paint.Cap.SQUARE);
         mCaretPaint.setStrokeJoin(Paint.Join.MITER);
 
-        mShadowPaint.setColor(res.getColor(R.color.all_apps_caret_shadow_color));
+        mShadowPaint.setColor(res.getColor(R.color.default_shadow_color_no_alpha));
+        mShadowPaint.setAlpha(Themes.getAlpha(context, android.R.attr.spotShadowAlpha));
         mShadowPaint.setAntiAlias(true);
         mShadowPaint.setStrokeWidth(strokeWidth + (shadowSpread * 2));
         mShadowPaint.setStyle(Paint.Style.STROKE);
diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
index 4f5edc9..6276c80 100644
--- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
+++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java
@@ -37,6 +37,7 @@
 
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
+import com.android.launcher3.util.Themes;
 
 /**
  * {@link PageIndicator} which shows dots per page. The active page is shown with the current
@@ -111,8 +112,8 @@
         mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2;
         setOutlineProvider(new MyOutlineProver());
 
-        mActiveColor = Utilities.getColorAccent(context);
-        mInActiveColor = getResources().getColor(R.color.page_indicator_dot_color);
+        mActiveColor = Themes.getColorAccent(context);
+        mInActiveColor = Themes.getAttrColor(context, android.R.attr.colorControlHighlight);
 
         mIsRtl = Utilities.isRtl(getResources());
     }
diff --git a/src/com/android/launcher3/popup/PopupContainerWithArrow.java b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
index 7fda8b5..d34727c 100644
--- a/src/com/android/launcher3/popup/PopupContainerWithArrow.java
+++ b/src/com/android/launcher3/popup/PopupContainerWithArrow.java
@@ -19,6 +19,7 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
 import android.animation.TimeInterpolator;
 import android.animation.ValueAnimator;
 import android.annotation.SuppressLint;
@@ -53,12 +54,12 @@
 import com.android.launcher3.LauncherAnimUtils;
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.LauncherSettings;
-import com.android.launcher3.LauncherViewPropertyAnimator;
 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.badge.BadgeInfo;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragLayer;
@@ -298,7 +299,7 @@
             anim.setInterpolator(interpolator);
             shortcutAnims.play(anim);
 
-            Animator fadeAnim = new LauncherViewPropertyAnimator(popupItemView).alpha(1);
+            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);
@@ -318,9 +319,8 @@
         // Animate the arrow
         mArrow.setScaleX(0);
         mArrow.setScaleY(0);
-        Animator arrowScale = new LauncherViewPropertyAnimator(mArrow).scaleX(1).scaleY(1);
+        Animator arrowScale = createArrowScaleAnim(1).setDuration(arrowScaleDuration);
         arrowScale.setStartDelay(arrowScaleDelay);
-        arrowScale.setDuration(arrowScaleDuration);
         shortcutAnims.play(arrowScale);
 
         mOpenCloseAnimator = shortcutAnims;
@@ -603,7 +603,7 @@
                 removeNotification.play(removeMargin);
             }
             removeNotification.play(reduceHeight);
-            Animator fade = new LauncherViewPropertyAnimator(notificationView).alpha(0)
+            Animator fade = ObjectAnimator.ofFloat(notificationView, ALPHA, 0)
                     .setDuration(duration);
             fade.addListener(new AnimatorListenerAdapter() {
                 @Override
@@ -620,11 +620,9 @@
             removeNotification.play(fade);
             final long arrowScaleDuration = getResources().getInteger(
                     R.integer.config_deepShortcutArrowOpenDuration);
-            Animator hideArrow = new LauncherViewPropertyAnimator(mArrow)
-                    .scaleX(0).scaleY(0).setDuration(arrowScaleDuration);
+            Animator hideArrow = createArrowScaleAnim(0).setDuration(arrowScaleDuration);
             hideArrow.setStartDelay(0);
-            Animator showArrow = new LauncherViewPropertyAnimator(mArrow)
-                    .scaleX(1).scaleY(1).setDuration(arrowScaleDuration);
+            Animator showArrow = createArrowScaleAnim(1).setDuration(arrowScaleDuration);
             showArrow.setStartDelay((long) (duration - arrowScaleDuration * 1.5));
             removeNotification.playSequentially(hideArrow, showArrow);
             removeNotification.start();
@@ -633,6 +631,10 @@
         notificationView.trimNotifications(badgeInfo.getNotificationKeys());
     }
 
+    private ObjectAnimator createArrowScaleAnim(float scale) {
+        return LauncherAnimUtils.ofPropertyValuesHolder(
+                mArrow, new PropertyListBuilder().scale(scale).build());
+    }
     /**
      * Animates the translationY of this container if it is open above the icon.
      * If it is below the icon, the container already shifts up when the height
@@ -640,8 +642,8 @@
      */
     public @Nullable Animator animateTranslationYBy(int translationY, int duration) {
         if (mIsAboveIcon) {
-            return new LauncherViewPropertyAnimator(this)
-                    .translationY(getTranslationY() + translationY).setDuration(duration);
+            return ObjectAnimator.ofFloat(this, TRANSLATION_Y, getTranslationY() + translationY)
+                    .setDuration(duration);
         }
         return null;
     }
@@ -744,7 +746,7 @@
                         : numOpenShortcuts - i - 1;
                 anim.setStartDelay(stagger * animationIndex);
 
-                Animator fadeAnim = new LauncherViewPropertyAnimator(view).alpha(0);
+                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);
@@ -761,12 +763,13 @@
                 view.setPivotY(iconCenter.y);
 
                 float scale = ((float) mLauncher.getDeviceProfile().iconSizePx) / view.getHeight();
-                LauncherViewPropertyAnimator anim2 = new LauncherViewPropertyAnimator(view)
-                        .scaleX(scale)
-                        .scaleY(scale)
-                        .translationX(mIconShift.x)
-                        .translationY(mIconShift.y);
-                anim2.setDuration(DragView.VIEW_ZOOM_DURATION);
+                Animator anim2 = LauncherAnimUtils.ofPropertyValuesHolder(view,
+                        new PropertyListBuilder()
+                                .scale(scale)
+                                .translationX(mIconShift.x)
+                                .translationY(mIconShift.y)
+                                .build())
+                        .setDuration(DragView.VIEW_ZOOM_DURATION);
                 shortcutAnims.play(anim2);
             }
             anim.addListener(new AnimatorListenerAdapter() {
@@ -777,8 +780,7 @@
             });
             shortcutAnims.play(anim);
         }
-        Animator arrowAnim = new LauncherViewPropertyAnimator(mArrow)
-                .scaleX(0).scaleY(0).setDuration(arrowScaleDuration);
+        Animator arrowAnim = createArrowScaleAnim(0).setDuration(arrowScaleDuration);
         arrowAnim.setStartDelay(0);
         shortcutAnims.play(arrowAnim);
 
diff --git a/src/com/android/launcher3/popup/PopupDataProvider.java b/src/com/android/launcher3/popup/PopupDataProvider.java
index c754fda..ee2930f 100644
--- a/src/com/android/launcher3/popup/PopupDataProvider.java
+++ b/src/com/android/launcher3/popup/PopupDataProvider.java
@@ -58,19 +58,26 @@
     }
 
     @Override
-    public void onNotificationPosted(PackageUserKey postedPackageUserKey, String notificationKey) {
+    public void onNotificationPosted(PackageUserKey postedPackageUserKey, String notificationKey,
+            boolean shouldBeFilteredOut) {
         BadgeInfo badgeInfo = mPackageUserToBadgeInfos.get(postedPackageUserKey);
-        boolean notificationWasAdded; // As opposed to updated.
+        boolean notificationWasAddedOrRemoved; // As opposed to updated.
         if (badgeInfo == null) {
-            BadgeInfo newBadgeInfo = new BadgeInfo(postedPackageUserKey);
-            newBadgeInfo.addNotificationKeyIfNotExists(notificationKey);
-            mPackageUserToBadgeInfos.put(postedPackageUserKey, newBadgeInfo);
-            notificationWasAdded = true;
+            if (!shouldBeFilteredOut) {
+                BadgeInfo newBadgeInfo = new BadgeInfo(postedPackageUserKey);
+                newBadgeInfo.addNotificationKeyIfNotExists(notificationKey);
+                mPackageUserToBadgeInfos.put(postedPackageUserKey, newBadgeInfo);
+                notificationWasAddedOrRemoved = true;
+            } else {
+                notificationWasAddedOrRemoved = false;
+            }
         } else {
-            notificationWasAdded = badgeInfo.addNotificationKeyIfNotExists(notificationKey);
+            notificationWasAddedOrRemoved = shouldBeFilteredOut
+                    ? badgeInfo.removeNotificationKey(notificationKey)
+                    : badgeInfo.addNotificationKeyIfNotExists(notificationKey);
         }
         updateLauncherIconBadges(Utilities.singletonHashSet(postedPackageUserKey),
-                notificationWasAdded);
+                notificationWasAddedOrRemoved);
     }
 
     @Override
@@ -165,7 +172,7 @@
     private boolean updateBadgeIcon(BadgeInfo badgeInfo) {
         boolean hadNotificationToShow = badgeInfo.hasNotificationToShow();
         NotificationInfo notificationInfo = null;
-        NotificationListener notificationListener = NotificationListener.getInstance();
+        NotificationListener notificationListener = NotificationListener.getInstanceIfConnected();
         if (notificationListener != null && badgeInfo.getNotificationKeys().size() == 1) {
             StatusBarNotification[] activeNotifications = notificationListener
                     .getActiveNotifications(new String[] {badgeInfo.getNotificationKeys().get(0)});
@@ -215,13 +222,13 @@
 
     /** This makes a potentially expensive binder call and should be run on a background thread. */
     public List<StatusBarNotification> getStatusBarNotificationsForKeys(String[] notificationKeys) {
-        NotificationListener notificationListener = NotificationListener.getInstance();
+        NotificationListener notificationListener = NotificationListener.getInstanceIfConnected();
         return notificationListener == null ? Collections.EMPTY_LIST
                 : notificationListener.getNotificationsForKeys(notificationKeys);
     }
 
     public void cancelNotification(String notificationKey) {
-        NotificationListener notificationListener = NotificationListener.getInstance();
+        NotificationListener notificationListener = NotificationListener.getInstanceIfConnected();
         if (notificationListener == null) {
             return;
         }
diff --git a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
index 9413913..df7f695 100644
--- a/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
+++ b/src/com/android/launcher3/shortcuts/DeepShortcutManager.java
@@ -65,7 +65,8 @@
     }
 
     public static boolean supportsShortcuts(ItemInfo info) {
-        return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+        return info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
+                && !info.isDisabled();
     }
 
     public boolean wasLastCallSuccess() {
diff --git a/src/com/android/launcher3/util/ManagedProfileHeuristic.java b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
index af61554..577d19f 100644
--- a/src/com/android/launcher3/util/ManagedProfileHeuristic.java
+++ b/src/com/android/launcher3/util/ManagedProfileHeuristic.java
@@ -203,7 +203,7 @@
             long workFolderId, int startingRank, ArrayList<ShortcutInfo> workFolderApps) {
         for (ItemInfo info : workFolderApps) {
             info.rank = startingRank++;
-            LauncherModel.addItemToDatabase(mContext, info, workFolderId, 0, 0, 0);
+            mModel.getWriter(false).addItemToDatabase(info, workFolderId, 0, 0, 0);
         }
     }
 
diff --git a/src/com/android/launcher3/util/PackageManagerHelper.java b/src/com/android/launcher3/util/PackageManagerHelper.java
index e89fc0c..bfa932b 100644
--- a/src/com/android/launcher3/util/PackageManagerHelper.java
+++ b/src/com/android/launcher3/util/PackageManagerHelper.java
@@ -71,6 +71,10 @@
         }
     }
 
+  /**
+   * Returns whether a package is suspended for the current user as per
+   * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
+   */
     public boolean isAppSuspended(String packageName) {
         try {
             ApplicationInfo info = mPm.getApplicationInfo(packageName, 0);
@@ -80,6 +84,16 @@
         }
     }
 
+  /**
+   * Returns whether the target app is suspended for a given user as per
+   * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
+   */
+    public boolean isAppSuspended(String packageName, UserHandle user) {
+        ApplicationInfo info =
+                LauncherAppsCompat.getInstance(mContext).getApplicationInfo(packageName, user);
+        return info != null && isAppSuspended(info);
+    }
+
     public boolean isSafeMode() {
         return mPm.isSafeMode();
     }
@@ -91,6 +105,10 @@
                 AppInfo.makeLaunchIntent(mContext, activities.get(0), user);
     }
 
+  /**
+   * Returns whether an application is suspended as per
+   * {@link android.app.admin.DevicePolicyManager#isPackageSuspended}.
+   */
     public static boolean isAppSuspended(ApplicationInfo info) {
         // The value of FLAG_SUSPENDED was reused by a hidden constant
         // ApplicationInfo.FLAG_PRIVILEGED prior to N, so only check for suspended flag on N
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
new file mode 100644
index 0000000..acd589e
--- /dev/null
+++ b/src/com/android/launcher3/util/Themes.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.util;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.view.ContextThemeWrapper;
+
+/**
+ * Various utility methods associated with theming.
+ */
+public class Themes {
+
+    public static int getColorAccent(Context context) {
+        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);
+        ta.recycle();
+        return colorAccent;
+    }
+
+    /**
+     * Returns the alpha corresponding to the theme attribute {@param attr}, in the range [0, 255].
+     */
+    public static int getAlpha(Context context, int attr) {
+        TypedArray ta = context.obtainStyledAttributes(new int[]{attr});
+        float alpha = ta.getFloat(0, 0);
+        ta.recycle();
+        return (int) (255 * alpha + 0.5f);
+    }
+}
diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java
index c723f9e..6f4c286 100644
--- a/src/com/android/launcher3/widget/PendingItemDragHelper.java
+++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java
@@ -29,6 +29,7 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.PendingAddItemInfo;
+import com.android.launcher3.R;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.dragndrop.DragOptions;
 import com.android.launcher3.graphics.DragPreviewProvider;
@@ -112,6 +113,11 @@
             DeviceProfile dp = launcher.getDeviceProfile();
             int iconSize = dp.iconSizePx;
 
+            int padding = launcher.getResources()
+                    .getDimensionPixelSize(R.dimen.widget_preview_shortcut_padding);
+            previewBounds.left += padding;
+            previewBounds.top += padding;
+
             dragRegion = new Rect();
             dragRegion.left = (size[0] - iconSize) / 2;
             dragRegion.right = dragRegion.left + iconSize;
diff --git a/src/com/android/launcher3/widget/WidgetImageView.java b/src/com/android/launcher3/widget/WidgetImageView.java
index 1211c08..df2bcff 100644
--- a/src/com/android/launcher3/widget/WidgetImageView.java
+++ b/src/com/android/launcher3/widget/WidgetImageView.java
@@ -89,16 +89,25 @@
     }
 
     private void updateDstRectF() {
-        if (mBitmap.getWidth() > getWidth()) {
-            float scale = ((float) getWidth()) / mBitmap.getWidth();
-            mDstRectF.set(0, 0, getWidth(), scale * mBitmap.getHeight());
+        float myWidth = getWidth();
+        float myHeight = getHeight();
+        float bitmapWidth = mBitmap.getWidth();
+
+        final float scale = bitmapWidth > myWidth ? myWidth / bitmapWidth : 1;
+        float scaledWidth = bitmapWidth * scale;
+        float scaledHeight = mBitmap.getHeight() * scale;
+
+        mDstRectF.left = (myWidth - scaledWidth) / 2;
+        mDstRectF.right = (myWidth + scaledWidth) / 2;
+
+        if (scaledHeight > myHeight) {
+            mDstRectF.top = 0;
+            mDstRectF.bottom = scaledHeight;
         } else {
-            mDstRectF.set(
-                    (getWidth() - mBitmap.getWidth()) * 0.5f,
-                    0,
-                    (getWidth() + mBitmap.getWidth()) * 0.5f,
-                    mBitmap.getHeight());
+            mDstRectF.top = (myHeight - scaledHeight) / 2;
+            mDstRectF.bottom = (myHeight + scaledHeight) / 2;
         }
+
         if (mBadge != null) {
             Rect bounds = mBadge.getBounds();
             int left = Utilities.boundToRange(
diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml
index 763481a..24882aa 100644
--- a/tests/AndroidManifest-common.xml
+++ b/tests/AndroidManifest-common.xml
@@ -18,6 +18,8 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.android.launcher3.tests">
 
+    <uses-sdk android:targetSdkVersion="25" android:minSdkVersion="21"/>
+
     <application android:debuggable="true">
         <uses-library android:name="android.test.runner" />
 
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
index afe8952..43030ae 100644
--- a/tests/AndroidManifest.xml
+++ b/tests/AndroidManifest.xml
@@ -18,6 +18,7 @@
     xmlns:tools="http://schemas.android.com/tools"
     package="com.android.launcher3.tests">
 
+    <uses-sdk android:targetSdkVersion="25" android:minSdkVersion="21"/>
     <uses-sdk tools:overrideLibrary="android.support.test.uiautomator.v18"/>
 
     <application android:debuggable="true">
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
index 2071389..d0ba907 100644
--- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
+++ b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
@@ -53,14 +53,6 @@
         return new AddWorkspaceItemsTask(Provider.of(Arrays.asList(items))) {
 
             @Override
-            protected void addItemToDatabase(Context context, ItemInfo item,
-                    long screenId, int[] pos) {
-                item.screenId = screenId;
-                item.cellX = pos[0];
-                item.cellY = pos[1];
-            }
-
-            @Override
             protected void updateScreens(Context context, ArrayList<Long> workspaceScreens) { }
         };
     }
diff --git a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java b/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
index 9b7fc6e..b9944db 100644
--- a/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
+++ b/tests/src/com/android/launcher3/model/BaseModelUpdateTaskTestCase.java
@@ -37,6 +37,7 @@
 import java.util.HashMap;
 import java.util.List;
 
+import static org.mockito.Matchers.anyBoolean;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -54,6 +55,8 @@
 
     public InvariantDeviceProfile idp;
     public LauncherAppState appState;
+    public LauncherModel model;
+    public ModelWriter modelWriter;
     public MyIconCache iconCache;
 
     public BgDataModel bgDataModel;
@@ -70,6 +73,11 @@
 
         callbacks = mock(Callbacks.class);
         appState = mock(LauncherAppState.class);
+        model = mock(LauncherModel.class);
+        modelWriter = mock(ModelWriter.class);
+        when(appState.getModel()).thenReturn(model);
+        when(model.getWriter(anyBoolean())).thenReturn(modelWriter);
+
         myUser = Process.myUserHandle();
 
         bgDataModel = new BgDataModel();