[automerger] Fix bug where all apps items fade in. am: 48a4e91c73

Change-Id: I9ccd034f9d8606d3baae07da3464c659fd405831
diff --git a/Android.mk b/Android.mk
index c8a53d2..d41e184 100644
--- a/Android.mk
+++ b/Android.mk
@@ -17,7 +17,7 @@
 LOCAL_PATH := $(call my-dir)
 
 #
-# Build app code.
+# Build rule for Launcher3 app.
 #
 include $(CLEAR_VARS)
 
@@ -33,7 +33,8 @@
     $(call all-java-files-under, src) \
     $(call all-java-files-under, src_config) \
     $(call all-java-files-under, src_flags) \
-    $(call all-proto-files-under, protos)
+    $(call all-proto-files-under, protos) \
+    $(call all-proto-files-under, proto_overrides)
 
 LOCAL_RESOURCE_DIR := \
     $(LOCAL_PATH)/res \
@@ -42,7 +43,7 @@
 LOCAL_PROGUARD_FLAG_FILES := proguard.flags
 
 LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/
+LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ --proto_path=$(LOCAL_PATH)/proto_overrides/
 LOCAL_PROTO_JAVA_OUTPUT_PARAMS := enum_style=java
 
 LOCAL_AAPT_FLAGS := \
@@ -62,14 +63,65 @@
 include $(BUILD_PACKAGE)
 
 #
+# Build rule for Launcher3 Go app for Android Go devices.
+#
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_STATIC_JAVA_LIBRARIES := \
+    android-support-v4 \
+    android-support-v7-recyclerview \
+    android-support-v7-palette \
+    android-support-dynamic-animation
+
+LOCAL_SRC_FILES := \
+    $(call all-java-files-under, src) \
+    $(call all-java-files-under, src_config) \
+    $(call all-java-files-under, go/src_flags) \
+    $(call all-proto-files-under, protos) \
+    $(call all-proto-files-under, proto_overrides)
+
+LOCAL_RESOURCE_DIR := \
+    $(LOCAL_PATH)/go/res \
+    $(LOCAL_PATH)/res \
+    prebuilts/sdk/current/support/v7/recyclerview/res \
+
+LOCAL_PROGUARD_FLAG_FILES := proguard.flags
+
+LOCAL_PROTOC_OPTIMIZE_TYPE := nano
+LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ --proto_path=$(LOCAL_PATH)/proto_overrides/
+LOCAL_PROTO_JAVA_OUTPUT_PARAMS := enum_style=java
+
+LOCAL_AAPT_FLAGS := \
+    --auto-add-overlay \
+    --extra-packages android.support.v7.recyclerview \
+
+LOCAL_SDK_VERSION := current
+LOCAL_MIN_SDK_VERSION := 21
+LOCAL_PACKAGE_NAME := Launcher3Go
+LOCAL_PRIVILEGED_MODULE := true
+LOCAL_OVERRIDES_PACKAGES := Home Launcher2 Launcher3
+
+LOCAL_FULL_LIBS_MANIFEST_FILES := \
+    $(LOCAL_PATH)/AndroidManifest.xml \
+    $(LOCAL_PATH)/AndroidManifest-common.xml
+
+LOCAL_MANIFEST_FILE := go/AndroidManifest.xml
+
+LOCAL_JACK_COVERAGE_INCLUDE_FILTER := com.android.launcher3.*
+
+include $(BUILD_PACKAGE)
+
+#
 # Launcher proto buffer jar used for development
 #
 include $(CLEAR_VARS)
 
-LOCAL_SRC_FILES := $(call all-proto-files-under, protos)
+LOCAL_SRC_FILES := $(call all-proto-files-under, protos) $(call all-proto-files-under, proto_overrides)
 
 LOCAL_PROTOC_OPTIMIZE_TYPE := nano
-LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/
+LOCAL_PROTOC_FLAGS := --proto_path=$(LOCAL_PATH)/protos/ --proto_path=$(LOCAL_PATH)/proto_overrides/
 LOCAL_PROTO_JAVA_OUTPUT_PARAMS := enum_style=java
 
 LOCAL_MODULE_TAGS := optional
diff --git a/build.gradle b/build.gradle
index c23a299..886ccac 100644
--- a/build.gradle
+++ b/build.gradle
@@ -35,28 +35,49 @@
             applicationId 'com.android.launcher3'
             testApplicationId 'com.android.launcher3.tests'
         }
+
+        l3go {
+            applicationId 'com.android.launcher3'
+            testApplicationId 'com.android.launcher3.tests'
+        }
     }
     sourceSets {
         main {
             res.srcDirs = ['res']
-            java.srcDirs = ['src', 'src_flags']
+            java.srcDirs = ['src']
             manifest.srcFile 'AndroidManifest-common.xml'
-            proto.srcDirs 'protos/'
+            proto {
+                srcDir 'protos/'
+                srcDir 'proto_overrides/'
+            }
         }
 
         androidTest {
-            java.srcDirs = ['tests/src']
             res.srcDirs = ['tests/res']
+            java.srcDirs = ['tests/src']
             manifest.srcFile "tests/AndroidManifest-common.xml"
         }
 
         aosp {
+            java.srcDirs = ['src_flags']
             manifest.srcFile "AndroidManifest.xml"
         }
 
         aospAndroidTest {
             manifest.srcFile "tests/AndroidManifest.xml"
         }
+
+        l3go {
+            res.srcDirs = ['go/res']
+            java.srcDirs = ['go/src_flags']
+            // Note: we are using the Launcher3 manifest here because the gradle manifest-merger uses
+            // different attributes than the build system.
+            manifest.srcFile "AndroidManifest.xml"
+        }
+
+        l3goAndroidTest {
+            manifest.srcFile "tests/AndroidManifest.xml"
+        }
     }
 }
 
@@ -71,10 +92,10 @@
     compile "com.android.support:support-dynamic-animation:${SUPPORT_LIBS_VERSION}"
     compile "com.android.support:recyclerview-v7:${SUPPORT_LIBS_VERSION}"
     compile "com.android.support:palette-v7:${SUPPORT_LIBS_VERSION}"
-    compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-2'
+    compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7'
 
     testCompile 'junit:junit:4.12'
-    androidTestCompile "org.mockito:mockito-core:1.+"
+    androidTestCompile "org.mockito:mockito-core:1.9.5"
     androidTestCompile 'com.google.dexmaker:dexmaker:1.2'
     androidTestCompile 'com.google.dexmaker:dexmaker-mockito:1.2'
     androidTestCompile 'com.android.support.test:runner:0.5'
@@ -92,6 +113,7 @@
                 task.builtins {
                     remove java
                     javanano {
+                        option "java_package=launcher_log_extension.proto|com.android.launcher3.userevent.nano"
                         option "java_package=launcher_log.proto|com.android.launcher3.userevent.nano"
                         option "java_package=launcher_dump.proto|com.android.launcher3.model.nano"
                         option "enum_style=java"
diff --git a/go/AndroidManifest.xml b/go/AndroidManifest.xml
new file mode 100644
index 0000000..ed8e0ad
--- /dev/null
+++ b/go/AndroidManifest.xml
@@ -0,0 +1,53 @@
+<?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.
+*/
+-->
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    package="com.android.launcher3" >
+
+    <uses-sdk android:targetSdkVersion="23" android:minSdkVersion="21"/>
+
+    <application
+        android:backupAgent="com.android.launcher3.LauncherBackupAgent"
+        android:fullBackupOnly="true"
+        android:fullBackupContent="@xml/backupscheme"
+        android:hardwareAccelerated="true"
+        android:icon="@drawable/ic_launcher_home"
+        android:label="@string/derived_app_name"
+        android:theme="@style/LauncherTheme"
+        android:largeHeap="@bool/config_largeHeap"
+        android:restoreAnyVersion="true"
+        android:supportsRtl="true" >
+
+        <!-- Activity for handling PinItemRequest. Only supports shortcuts -->
+        <activity android:name="com.android.launcher3.dragndrop.AddItemActivity"
+            android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert"
+            android:excludeFromRecents="true"
+            android:autoRemoveFromRecents="true"
+            android:label="@string/action_add_to_workspace"
+            tools:merge="override" >
+            <intent-filter>
+                <action android:name="android.content.pm.action.CONFIRM_PIN_SHORTCUT" />
+            </intent-filter>
+        </activity>
+
+    </application>
+
+</manifest>
diff --git a/go/res/drawable/ic_widget.xml b/go/res/drawable/ic_widget.xml
new file mode 100644
index 0000000..5336876
--- /dev/null
+++ b/go/res/drawable/ic_widget.xml
@@ -0,0 +1,25 @@
+<!--
+Copyright (C) 2017 The Android Open Source Project
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+         http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="48dp"
+        android:height="48dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M3.9,18.35c2.5-2.49,5.78-3.64,10.14-3.64v3.05c0,0.47,0.57,0.71,0.9,0.37l5.74-5.74c0.41-0.41,0.41-1.08,0-1.49l-5.74-5.74
+        c-0.33-0.33-0.9-0.1-0.9,0.37v2.95c-6.32,0.9-9.56,4.9-11.02,9.34C2.86,18.34,3.51,18.74,3.9,18.35z"/>
+</vector>
diff --git a/go/res/layout/widget_cell_content.xml b/go/res/layout/widget_cell_content.xml
new file mode 100644
index 0000000..49506d9
--- /dev/null
+++ b/go/res/layout/widget_cell_content.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content">
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:paddingTop="@dimen/widget_preview_label_vertical_padding"
+        android:paddingBottom="@dimen/widget_preview_label_vertical_padding"
+        android:paddingLeft="@dimen/widget_preview_label_horizontal_padding"
+        android:paddingRight="@dimen/widget_preview_label_horizontal_padding"
+        android:orientation="horizontal">
+
+        <!-- The name of the widget. -->
+        <TextView
+            android:id="@+id/widget_name"
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            android:layout_weight="1"
+            android:ellipsize="end"
+            android:fadingEdge="horizontal"
+            android:fontFamily="sans-serif-condensed"
+            android:gravity="center"
+            android:singleLine="true"
+            android:maxLines="1"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="14sp" />
+
+        <!-- The original dimensions of the widget (can't be the same text as above due to different
+             style. -->
+        <TextView
+            android:id="@+id/widget_dims"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="5dp"
+            android:layout_marginLeft="5dp"
+            android:visibility="gone"
+            android:textColor="?android:attr/textColorSecondary"
+            android:textSize="14sp"
+            android:fontFamily="sans-serif-condensed"
+            android:alpha="0.8" />
+    </LinearLayout>
+
+    <!-- The image of the widget. This view does not support padding. Any placement adjustment
+         should be done using margins. -->
+    <com.android.launcher3.widget.WidgetImageView
+        android:id="@+id/widget_preview"
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1" />
+</merge>
\ No newline at end of file
diff --git a/go/res/values-af/strings.xml b/go/res/values-af/strings.xml
new file mode 100644
index 0000000..10ac473
--- /dev/null
+++ b/go/res/values-af/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Raak en hou om \'n kortpad op te tel."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dubbeltik en hou om \'n kortpad op te tel of gebruik gepasmaakte handelinge."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Kortpaaie"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-kortpaaie"</string>
+</resources>
diff --git a/go/res/values-am/strings.xml b/go/res/values-am/strings.xml
new file mode 100644
index 0000000..b3b253f
--- /dev/null
+++ b/go/res/values-am/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"አንድ አቋራጭ ለመውሰድ ነክተው ይያዙ"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"አንድ አቋራጭ ለመውሰድ ወይም ብጁ እርምጃዎችን ለመጠቀም ሁለቴ መታ አድርገው ይያዙ።"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"አቋራጮች"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> አቋራጮች"</string>
+</resources>
diff --git a/go/res/values-ar/strings.xml b/go/res/values-ar/strings.xml
new file mode 100644
index 0000000..2b3b807
--- /dev/null
+++ b/go/res/values-ar/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"المس مع الاستمرار لاختيار اختصار."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"يمكنك النقر نقرًا مزدوجًا مع الاستمرار لاختيار اختصار أو استخدام الإجراءات المخصصة."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"الاختصارات"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"اختصارات <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-az-rAZ/strings.xml b/go/res/values-az-rAZ/strings.xml
new file mode 100644
index 0000000..c4b8cb7
--- /dev/null
+++ b/go/res/values-az-rAZ/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Qısayolu seçmək üçün toxunub saxlayın."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Qısayollar"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> qısayolları"</string>
+</resources>
diff --git a/go/res/values-az/strings.xml b/go/res/values-az/strings.xml
new file mode 100644
index 0000000..c4b8cb7
--- /dev/null
+++ b/go/res/values-az/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Qısayolu seçmək üçün toxunub saxlayın."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Qısayolu seçmək üçün iki dəfə basıb saxlayın və ya fərdi əməliyyatlardan istifadə edin."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Qısayollar"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> qısayolları"</string>
+</resources>
diff --git a/go/res/values-b+sr+Latn/strings.xml b/go/res/values-b+sr+Latn/strings.xml
new file mode 100644
index 0000000..0da5699
--- /dev/null
+++ b/go/res/values-b+sr+Latn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dodirnite i zadržite da biste izabrali prečicu."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i zadržite da biste izabrali prečicu ili koristite prilagođene radnje."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Prečice"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečice za <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-be/strings.xml b/go/res/values-be/strings.xml
new file mode 100644
index 0000000..4189e35
--- /dev/null
+++ b/go/res/values-be/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Дакраніцеся і ўтрымлiвайце ярлык, каб дадаць яго."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Дакраніцеся двойчы і ўтрымлівайце, каб выбраць ярлык або выкарыстоўваць спецыяльныя дзеянні."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Ярлыкі"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Ярлыкі <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-bg/strings.xml b/go/res/values-bg/strings.xml
new file mode 100644
index 0000000..1b85992
--- /dev/null
+++ b/go/res/values-bg/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Докоснете и задръжте за избор на пряк път."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Докоснете двукратно и задръжте за избор на пряк път или използвайте персонализирани действия."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Преки пътища"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Преки пътища за <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-bn/strings.xml b/go/res/values-bn/strings.xml
new file mode 100644
index 0000000..c56c925
--- /dev/null
+++ b/go/res/values-bn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"কোনও শর্টকাট বেছে নিতে টাচ করে ধরে রাখুন।"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"কোনও শর্টকাট বেছে নিতে ডাবল ট্যাপ করে ধরে রাখুন অথবা কাস্টম ক্রিয়াগুলি ব্যবহার করুন।"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"শর্টকাট"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> এর শর্টকাট"</string>
+</resources>
diff --git a/go/res/values-bs-rBA/strings.xml b/go/res/values-bs-rBA/strings.xml
new file mode 100644
index 0000000..7042468
--- /dev/null
+++ b/go/res/values-bs-rBA/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dodirnite i držite da uzmete prečicu."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i držite da uzmete prečicu ili koristite prilagođene akcije."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Prečice"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečice aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-bs/strings.xml b/go/res/values-bs/strings.xml
new file mode 100644
index 0000000..7042468
--- /dev/null
+++ b/go/res/values-bs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dodirnite i držite da uzmete prečicu."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i držite da uzmete prečicu ili koristite prilagođene akcije."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Prečice"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečice aplikacije <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-ca/strings.xml b/go/res/values-ca/strings.xml
new file mode 100644
index 0000000..3b5c3f7
--- /dev/null
+++ b/go/res/values-ca/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Mantén premuda una drecera per seleccionar-la."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Fes doble toc i mantén premut per seleccionar una drecera o per utilitzar accions personalitzades."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Dreceres"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Dreceres de l\'aplicació <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-cs/strings.xml b/go/res/values-cs/strings.xml
new file mode 100644
index 0000000..e4018f2
--- /dev/null
+++ b/go/res/values-cs/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Zkratku vyberete podržením."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvojitým klepnutím a podržením vyberte zkratku, případně použijte vlastní akce."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Zkratky"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Zkratky aplikace <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-da/strings.xml b/go/res/values-da/strings.xml
new file mode 100644
index 0000000..821d36a
--- /dev/null
+++ b/go/res/values-da/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Hold en genvej nede for at samle den op."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tryk to gange, og hold en genvej nede for at samle den op og bruge tilpassede handlinger."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Genveje"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-genveje"</string>
+</resources>
diff --git a/go/res/values-de/strings.xml b/go/res/values-de/strings.xml
new file mode 100644
index 0000000..43a1b3a
--- /dev/null
+++ b/go/res/values-de/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Doppeltippen und halten, um eine Verknüpfung auszuwählen."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Doppeltippen und halten, um eine Verknüpfung auszuwählen oder benutzerdefinierte Aktionen zu nutzen."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Verknüpfungen"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-Verknüpfungen"</string>
+</resources>
diff --git a/go/res/values-el/strings.xml b/go/res/values-el/strings.xml
new file mode 100644
index 0000000..ae59907
--- /dev/null
+++ b/go/res/values-el/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Αγγίξτε παρατεταμένα για να σηκώσετε μια συντόμευση."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Πατήσετε δύο φορές παρατεταμένα για να σηκώσετε μια συντόμευση ή για να χρησιμοποιήσετε προσαρμοσμένες ενέργειες."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Συντομεύσεις"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Συντομεύσεις <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-en-rAU/strings.xml b/go/res/values-en-rAU/strings.xml
new file mode 100644
index 0000000..2ee2c26
--- /dev/null
+++ b/go/res/values-en-rAU/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Touch &amp; hold to pick up a shortcut."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Shortcuts"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shortcuts"</string>
+</resources>
diff --git a/go/res/values-en-rGB/strings.xml b/go/res/values-en-rGB/strings.xml
new file mode 100644
index 0000000..2ee2c26
--- /dev/null
+++ b/go/res/values-en-rGB/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Touch &amp; hold to pick up a shortcut."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Shortcuts"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shortcuts"</string>
+</resources>
diff --git a/go/res/values-en-rIN/strings.xml b/go/res/values-en-rIN/strings.xml
new file mode 100644
index 0000000..2ee2c26
--- /dev/null
+++ b/go/res/values-en-rIN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Touch &amp; hold to pick up a shortcut."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Double-tap &amp; hold to pick up a shortcut or use custom actions."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Shortcuts"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shortcuts"</string>
+</resources>
diff --git a/go/res/values-es-rUS/strings.xml b/go/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..5212c03
--- /dev/null
+++ b/go/res/values-es-rUS/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Mantén presionado para elegir un acceso directo."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Presiona dos veces y mantén presionado para elegir un acceso directo o usar acciones personalizadas."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Accesos directos"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Accesos directos de <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-es/strings.xml b/go/res/values-es/strings.xml
new file mode 100644
index 0000000..3ae4588
--- /dev/null
+++ b/go/res/values-es/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Mantén pulsado el acceso directo que quieras."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toca dos veces y mantén pulsado el acceso directo o utiliza acciones personalizadas."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Accesos directos"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Accesos directos de <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-et/strings.xml b/go/res/values-et/strings.xml
new file mode 100644
index 0000000..2513e65
--- /dev/null
+++ b/go/res/values-et/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Otsetee valimiseks puudutage seda pikalt."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Topeltpuudutage ja hoidke otsetee valimiseks või kohandatud toimingute kasutamiseks."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Otseteed"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Rakenduse <xliff:g id="NAME">%1$s</xliff:g> otseteed"</string>
+</resources>
diff --git a/go/res/values-eu/strings.xml b/go/res/values-eu/strings.xml
new file mode 100644
index 0000000..9949ef0
--- /dev/null
+++ b/go/res/values-eu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Eduki sakatuta lasterbide bat aukeratzeko."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Sakatu birritan eta eduki sakatuta lasterbide bat aukeratzeko edo ekintza pertsonalizatuak erabiltzeko."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Lasterbideak"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> aplikazioaren lasterbidea"</string>
+</resources>
diff --git a/go/res/values-fa/strings.xml b/go/res/values-fa/strings.xml
new file mode 100644
index 0000000..8bc5256
--- /dev/null
+++ b/go/res/values-fa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"برای انتخاب یک میان‌بر، لمس کنید و نگه‌دارید."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"برای انتخاب یک میان‌بر، دو ضربه سریع بزنید و نگه‌دارید یا از اقدام‌های سفارشی استفاده کنید."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"میان‌برها"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"میان‌برهای <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-fi/strings.xml b/go/res/values-fi/strings.xml
new file mode 100644
index 0000000..da9b0e1
--- /dev/null
+++ b/go/res/values-fi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Valitse pikakuvake painamalla sitä pitkään."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Valitse pikakuvake tai käytä muokattuja toimintoja kaksoisnapauttamalla ja painamalla pitkään."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Pikakuvakkeet"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Kohteen <xliff:g id="NAME">%1$s</xliff:g> pikakuvakkeet"</string>
+</resources>
diff --git a/go/res/values-fr-rCA/strings.xml b/go/res/values-fr-rCA/strings.xml
new file mode 100644
index 0000000..c7fd6d6
--- /dev/null
+++ b/go/res/values-fr-rCA/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Maintenez un doigt sur le raccourci pour l\'ajouter"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Touchez 2x un raccourci et maintenez doigt dessus pour l’aj. ou utiliser des actions personnalisées."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Raccourcis"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Raccourcis : <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-fr/strings.xml b/go/res/values-fr/strings.xml
new file mode 100644
index 0000000..238fe73
--- /dev/null
+++ b/go/res/values-fr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Appui prolongé pour sélectionner raccourci."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Appuyez 2 fois et maintenez pression pour sélectionner raccourci ou utilisez actions personnalisées."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Raccourcis"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Raccourcis <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-gl/strings.xml b/go/res/values-gl/strings.xml
new file mode 100644
index 0000000..31621d5
--- /dev/null
+++ b/go/res/values-gl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Mantén premido un atallo para seleccionalo."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toca dúas veces e mantén premido para seleccionar un atallo ou utiliza accións personalizadas."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Atallos"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Atallos da aplicación <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-gu/strings.xml b/go/res/values-gu/strings.xml
new file mode 100644
index 0000000..bdb549f
--- /dev/null
+++ b/go/res/values-gu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"એક શૉર્ટકટ ચૂંટવા ટૅપ કરી રાખો."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"એક શૉર્ટકટ ચૂંટવા અથવા કોઈ કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટૅપ કરી રાખો."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"શૉર્ટકટ"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> શૉર્ટકટ"</string>
+</resources>
diff --git a/go/res/values-hi/strings.xml b/go/res/values-hi/strings.xml
new file mode 100644
index 0000000..bc05776
--- /dev/null
+++ b/go/res/values-hi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"शॉर्टकट चुनने के लिए छूकर रखें."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"शॉर्टकट चुनने के लिए डबल टैप करके रखें या कस्टम कार्रवाइयों का उपयोग करें."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"शॉर्टकट"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> शॉर्टकट"</string>
+</resources>
diff --git a/go/res/values-hr/strings.xml b/go/res/values-hr/strings.xml
new file mode 100644
index 0000000..fccdeb5
--- /dev/null
+++ b/go/res/values-hr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dodirnite i zadržite kako biste podigli prečac."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvaput dodirnite i zadržite pritisak kako biste podigli prečac ili pokušajte prilagođenim radnjama."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Prečaci"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Prečaci za aplikaciju <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-hu/strings.xml b/go/res/values-hu/strings.xml
new file mode 100644
index 0000000..369c227
--- /dev/null
+++ b/go/res/values-hu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Felvételhez tartsa nyomva a parancsikont."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Parancsikon felvételéhez koppintson rá duplán és tartsa nyomva, vagy használjon egyéni műveleteket."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Parancsikonok"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-parancsikonok"</string>
+</resources>
diff --git a/go/res/values-hy/strings.xml b/go/res/values-hy/strings.xml
new file mode 100644
index 0000000..4747f6d
--- /dev/null
+++ b/go/res/values-hy/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար։"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Կրկնակի հպեք և պահեք՝ դյուրանցում ընտրելու համար կամ օգտվեք հարմարեցրած գործողություններից:"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Դյուրանցումներ"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> դյուրանցումներ"</string>
+</resources>
diff --git a/go/res/values-in/strings.xml b/go/res/values-in/strings.xml
new file mode 100644
index 0000000..c8b9da3
--- /dev/null
+++ b/go/res/values-in/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Tap lama untuk memilih pintasan."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tap dua kali &amp; tahan untuk memilih pintasan atau menggunakan tindakan khusus."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Pintasan"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Pintasan <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-is/strings.xml b/go/res/values-is/strings.xml
new file mode 100644
index 0000000..b8bb923
--- /dev/null
+++ b/go/res/values-is/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Haltu fingri á flýtileið til að grípa hana."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ýttu tvisvar og haltu fingri á flýtileið til að grípa hana eða notaðu sérsniðnar aðgerðir."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Flýtileiðir"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> flýtileiðir"</string>
+</resources>
diff --git a/go/res/values-it/strings.xml b/go/res/values-it/strings.xml
new file mode 100644
index 0000000..bc5d998
--- /dev/null
+++ b/go/res/values-it/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Tocca e tieni premuto per scegliere la scorciatoia"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tocca due volte e tieni premuto per scegliere una scorciatoia o per usare azioni personalizzate."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Scorciatoie"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Scorciatoie di <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-iw/strings.xml b/go/res/values-iw/strings.xml
new file mode 100644
index 0000000..f541d4d
--- /dev/null
+++ b/go/res/values-iw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"כדי להוסיף קיצור דרך, מקישים עליו פעמיים ומחזיקים."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"כדי להוסיף קיצור דרך או להשתמש בפעולות מותאמות אישית, מקישים על קיצור הדרך פעמיים ומחזיקים."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"קיצורי דרך"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"קיצורי דרך לאפליקציה <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-ja/strings.xml b/go/res/values-ja/strings.xml
new file mode 100644
index 0000000..8f02d7f
--- /dev/null
+++ b/go/res/values-ja/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"ショートカットを追加するには押し続けます。"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ダブルタップ後に押し続けてショートカットを選択するか、カスタム操作を使用してください。"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"ショートカット"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"「<xliff:g id="NAME">%1$s</xliff:g>」のショートカット"</string>
+</resources>
diff --git a/go/res/values-ka-rGE/strings.xml b/go/res/values-ka-rGE/strings.xml
new file mode 100644
index 0000000..1b46534
--- /dev/null
+++ b/go/res/values-ka-rGE/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"შეეხეთ და დააყოვნეთ მალსახმობის ასარჩევად."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ორმაგად შეეხეთ და გეჭიროთ მალსახმობის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"მალსახმობები"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-ის მალსახმობები"</string>
+</resources>
diff --git a/go/res/values-ka/strings.xml b/go/res/values-ka/strings.xml
new file mode 100644
index 0000000..1b46534
--- /dev/null
+++ b/go/res/values-ka/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"შეეხეთ და დააყოვნეთ მალსახმობის ასარჩევად."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ორმაგად შეეხეთ და გეჭიროთ მალსახმობის ასარჩევად ან მორგებული მოქმედებების გამოსაყენებლად."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"მალსახმობები"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-ის მალსახმობები"</string>
+</resources>
diff --git a/go/res/values-kk/strings.xml b/go/res/values-kk/strings.xml
new file mode 100644
index 0000000..e909818
--- /dev/null
+++ b/go/res/values-kk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Таңбашаны таңдау үшін оны түртіп, ұстап тұрыңыз."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Таңбашаны таңдау немесе арнаулы әрекеттерді пайдалану үшін екі рет түртіп, ұстап тұрыңыз."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Таңбашалар"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> таңбаша"</string>
+</resources>
diff --git a/go/res/values-km/strings.xml b/go/res/values-km/strings.xml
new file mode 100644
index 0000000..40082a4
--- /dev/null
+++ b/go/res/values-km/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"ប៉ះ ហើយចុចឲ្យជាប់ដើម្បីរើសផ្លូវកាត់មួយ។"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ប៉ះពីរដង ហើយចុចឱ្យជាប់ដើម្បីរើសផ្លូវកាត់មួយ ឬប្រើសកម្មភាពផ្ទាល់ខ្លួន។"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"ផ្លូវកាត់"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"ផ្លូវកាត់សម្រាប់ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-kn/strings.xml b/go/res/values-kn/strings.xml
new file mode 100644
index 0000000..9c121fd
--- /dev/null
+++ b/go/res/values-kn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್ ಆರಿಸಲು ಹೋಲ್ಡ್ ಮಾಡಿ."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ಡಬಲ್ ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್ ಆರಿಸಿಕೊಳ್ಳಲು ಹೋಲ್ಡ್ ಮಾಡಿ ಅಥವಾ ಕಸ್ಟಮ್ ಕ್ರಿಯೆಗಳನ್ನು ಬಳಸಿ."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ಶಾರ್ಟ್‌ಕಟ್‌ಗಳು"</string>
+</resources>
diff --git a/go/res/values-ko/strings.xml b/go/res/values-ko/strings.xml
new file mode 100644
index 0000000..60f925e
--- /dev/null
+++ b/go/res/values-ko/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"바로가기를 선택하려면 길게 터치하세요."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"바로가기를 선택하려면 두 번 탭한 다음 길게 터치하거나 맞춤 액션을 사용합니다."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"바로가기"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> 바로가기"</string>
+</resources>
diff --git a/go/res/values-ky-rKG/strings.xml b/go/res/values-ky-rKG/strings.xml
new file mode 100644
index 0000000..4c7e973
--- /dev/null
+++ b/go/res/values-ky-rKG/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Кыска жолду тандоо үчүн басып туруңуз."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Кыска жолду тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Кыска жолдор"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> кыска жол"</string>
+</resources>
diff --git a/go/res/values-ky/strings.xml b/go/res/values-ky/strings.xml
new file mode 100644
index 0000000..4c7e973
--- /dev/null
+++ b/go/res/values-ky/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Кыска жолду тандоо үчүн басып туруңуз."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Кыска жолду тандоо үчүн эки жолу таптап, кармап туруңуз же ыңгайлаштырылган аракеттерди колдонуңуз."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Кыска жолдор"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> кыска жол"</string>
+</resources>
diff --git a/go/res/values-lo-rLA/strings.xml b/go/res/values-lo-rLA/strings.xml
new file mode 100644
index 0000000..7864884
--- /dev/null
+++ b/go/res/values-lo-rLA/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"ແຕະຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ ຫຼື ໃຊ້ຄຳສັ່ງແບບກຳນົດເອງ."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"ປຸ່ມລັດ"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"ປຸ່ມລັດ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-lo/strings.xml b/go/res/values-lo/strings.xml
new file mode 100644
index 0000000..7864884
--- /dev/null
+++ b/go/res/values-lo/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"ແຕະຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ແຕະສອງເທື່ອຄ້າງໄວ້ເພື່ອຮັບປຸ່ມລັດ ຫຼື ໃຊ້ຄຳສັ່ງແບບກຳນົດເອງ."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"ປຸ່ມລັດ"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"ປຸ່ມລັດ <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-lt/strings.xml b/go/res/values-lt/strings.xml
new file mode 100644
index 0000000..8f49032
--- /dev/null
+++ b/go/res/values-lt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Dukart pal. ir palaik., kad pasir. spart. klav."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dukart palieskite ir palaikykite, kad pasirinkt. spartųjį klavišą ar naudotumėte tinkintus veiksmus."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Spartieji klavišai"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"„<xliff:g id="NAME">%1$s</xliff:g>“ spartieji klavišai"</string>
+</resources>
diff --git a/go/res/values-lv/strings.xml b/go/res/values-lv/strings.xml
new file mode 100644
index 0000000..04315eb
--- /dev/null
+++ b/go/res/values-lv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Lai izvēlētos saīsni, pieskarieties un turiet to."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Lai atlasītu saīsni, veiciet dubultskārienu uz tās un turiet to vai arī veiciet pielāgotas darbības."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Saīsnes"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Lietotnes <xliff:g id="NAME">%1$s</xliff:g> saīsnes"</string>
+</resources>
diff --git a/go/res/values-mk/strings.xml b/go/res/values-mk/strings.xml
new file mode 100644
index 0000000..52d66b5
--- /dev/null
+++ b/go/res/values-mk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Допрете двапати и задржете за да изберете кратенка."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Допрете двапати и задржете за да изберете кратенка или да користите приспособени дејства."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Кратенки"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Кратенки за <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-ml/strings.xml b/go/res/values-ml/strings.xml
new file mode 100644
index 0000000..b3c12e1
--- /dev/null
+++ b/go/res/values-ml/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"ഒരു കുറുക്കുവഴി ചേർക്കുന്നതിന് അത് സ്‌പർശിച്ച് പിടിക്കുക."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ഒരു കുറുക്കുവഴി തിരഞ്ഞെടുക്കാനോ ഇഷ്ടാനുസൃത പ്രവർത്തനങ്ങൾ ഉപയോഗിക്കാനോ രണ്ടുതവണ ടാപ്പുചെയ്ത് പിടിക്കുക."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"കുറുക്കുവഴികൾ"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> കുറുക്കുവഴികൾ"</string>
+</resources>
diff --git a/go/res/values-mn/strings.xml b/go/res/values-mn/strings.xml
new file mode 100644
index 0000000..c89dfd1
--- /dev/null
+++ b/go/res/values-mn/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Товчлол авах бол удаан дарна уу."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Товчлол авах болон тохируулсан үйлдлийг ашиглахын тулд хоёр товшоод хүлээнэ үү."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Товчлол"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-н товчлол"</string>
+</resources>
diff --git a/go/res/values-mr/strings.xml b/go/res/values-mr/strings.xml
new file mode 100644
index 0000000..2c767b4
--- /dev/null
+++ b/go/res/values-mr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"शॉर्टकट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"शॉर्टकट निवडण्यासाठी किंवा कस्टम क्रिया वापरण्यासाठी दोनदा टॅप करा आणि धरून ठेवा."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"शॉर्टकट"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> शॉर्टकट"</string>
+</resources>
diff --git a/go/res/values-ms/strings.xml b/go/res/values-ms/strings.xml
new file mode 100644
index 0000000..42add9a
--- /dev/null
+++ b/go/res/values-ms/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Sentuh &amp; tahan untuk mengambil pintasan."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ketik dua kali &amp; tahan untuk mengambil pintasan atau menggunakan tindakan tersuai."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Pintasan"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Pintasan <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-my/strings.xml b/go/res/values-my/strings.xml
new file mode 100644
index 0000000..5784df6
--- /dev/null
+++ b/go/res/values-my/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"လက်ကွက်ဖြတ်လမ်းတစ်ခုကို ရွေးရန် ထိပြီး ဖိထားပါ"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"လက်ကွက်ဖြတ်လမ်းကို ရွေးရန် (သို့) စိတ်ကြိုက်လုပ်ဆောင်ချက်များကို သုံးရန်နှစ်ချက်တို့ပြီး ဖိထားပါ။"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"ဖြတ်လမ်းလင့်ခ်များ"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ဖြတ်လမ်းလင့်ခ်များ"</string>
+</resources>
diff --git a/go/res/values-nb/strings.xml b/go/res/values-nb/strings.xml
new file mode 100644
index 0000000..2a5ffb6
--- /dev/null
+++ b/go/res/values-nb/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Trykk og hold for å velge en snarvei."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dobbelttrykk og hold for å velge en snarvei eller bruke tilpassede handlinger."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Snarveier"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-snarveier"</string>
+</resources>
diff --git a/go/res/values-ne/strings.xml b/go/res/values-ne/strings.xml
new file mode 100644
index 0000000..0be0375
--- /dev/null
+++ b/go/res/values-ne/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"कुनै सटकर्ट छनौट गर्न छोइराख्नुहोस्।"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"कुनै सर्टकट छनौट गर्न दुईपटक ट्याप गरेर होल्ड गर्नुहोस् वा रोजेका कारबाहीहरू प्रयोग गर्नुहोस्।"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"सर्टकटहरू"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> सर्टकटहरू"</string>
+</resources>
diff --git a/go/res/values-nl/strings.xml b/go/res/values-nl/strings.xml
new file mode 100644
index 0000000..5bcd016
--- /dev/null
+++ b/go/res/values-nl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Tik en houd vast om snelkoppeling toe te voegen."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dubbeltik en houd vast om een snelkoppeling toe te voegen of aangepaste acties te gebruiken."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Snelkoppelingen"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>-snelkoppelingen"</string>
+</resources>
diff --git a/go/res/values-pa/strings.xml b/go/res/values-pa/strings.xml
new file mode 100644
index 0000000..f3982ab
--- /dev/null
+++ b/go/res/values-pa/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ।"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"ਕੋਈ ਸ਼ਾਰਟਕੱਟ ਚੁਣਨ ਲਈ ਡਬਲ-ਟੈਪ ਕਰੋ ਅਤੇ ਦਬਾ ਕੇ ਰੱਖੋ ਜਾਂ ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਾਰਵਾਈਆਂ ਵਰਤੋ।"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"ਸ਼ਾਰਟਕੱਟ"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ਸ਼ਾਰਟਕੱਟ"</string>
+</resources>
diff --git a/go/res/values-pl/strings.xml b/go/res/values-pl/strings.xml
new file mode 100644
index 0000000..45a1dc2
--- /dev/null
+++ b/go/res/values-pl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Kliknij i przytrzymaj, by wybrać skrót."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Kliknij dwukrotnie i przytrzymaj, by wybrać skrót lub użyć działań niestandardowych."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Skróty"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> – skróty"</string>
+</resources>
diff --git a/go/res/values-pt-rPT/strings.xml b/go/res/values-pt-rPT/strings.xml
new file mode 100644
index 0000000..7a75a05
--- /dev/null
+++ b/go/res/values-pt-rPT/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Toque sem soltar para escolher um atalho."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toque duas vezes sem soltar para escolher um atalho ou utilize ações personalizadas."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Atalhos"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Atalhos da aplicação <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-pt/strings.xml b/go/res/values-pt/strings.xml
new file mode 100644
index 0000000..53bbfc4
--- /dev/null
+++ b/go/res/values-pt/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Toque e segure para selecionar um atalho."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Toque duas vezes na tela e segure para selecionar um atalho ou usar ações personalizadas."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Atalhos"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Atalhos do app <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-ro/strings.xml b/go/res/values-ro/strings.xml
new file mode 100644
index 0000000..75d1796
--- /dev/null
+++ b/go/res/values-ro/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Atingeți și țineți apăsat pentru a selecta o comandă rapidă."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Atingeți de două ori și țineți apăsat pentru comandă rapidă sau folosiți acțiuni personalizate."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Comenzi rapide"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Comenzi rapide pentru <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-ru/strings.xml b/go/res/values-ru/strings.xml
new file mode 100644
index 0000000..9c5c8cd
--- /dev/null
+++ b/go/res/values-ru/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Чтобы выбрать ярлык, нажмите на него и удерживайте."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Чтобы выбрать ярлык или использовать специальные действия, нажмите на него дважды и не отпускайте."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Ярлыки"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>: ярлыки"</string>
+</resources>
diff --git a/go/res/values-si-rLK/strings.xml b/go/res/values-si-rLK/strings.xml
new file mode 100644
index 0000000..4b25c90
--- /dev/null
+++ b/go/res/values-si-rLK/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"කෙටි මගක් තෝරා ගැනීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"විජට් එකක් තෝරා ගැනීමට හෝ අභිරුචි භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"කෙටි මං"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"කෙටි මං <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-si/strings.xml b/go/res/values-si/strings.xml
new file mode 100644
index 0000000..4b25c90
--- /dev/null
+++ b/go/res/values-si/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"කෙටි මගක් තෝරා ගැනීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"විජට් එකක් තෝරා ගැනීමට හෝ අභිරුචි භාවිත කිරීමට දෙවරක් තට්ටු කර අල්ලා ගෙන සිටින්න."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"කෙටි මං"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"කෙටි මං <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-sk/strings.xml b/go/res/values-sk/strings.xml
new file mode 100644
index 0000000..fc02933
--- /dev/null
+++ b/go/res/values-sk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Skratku pridáte pridržaním."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Skratku pridáte dvojitým klepnutím a pridržaním alebo pomocou vlastných akcií."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Skratky"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Skratky aplikácie <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-sl/strings.xml b/go/res/values-sl/strings.xml
new file mode 100644
index 0000000..6ecedfb
--- /dev/null
+++ b/go/res/values-sl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Pridržite bližnjico, da jo izberete."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Dvakrat se dotaknite bližnjice in jo pridržite, da jo izberete, ali pa uporabite dejanja po meri."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Bližnjice"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Bližnjice za <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-sq/strings.xml b/go/res/values-sq/strings.xml
new file mode 100644
index 0000000..bb74db6
--- /dev/null
+++ b/go/res/values-sq/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Prek dhe mbaj prekur për të zgjedhur një shkurtore."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Prek dy herë dhe mbaj prekur për të zgjedhur një shkurtore ose për të përdorur veprimet e personalizuara."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Shkurtoret"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> shkurtore"</string>
+</resources>
diff --git a/go/res/values-sr/strings.xml b/go/res/values-sr/strings.xml
new file mode 100644
index 0000000..0b9aea2
--- /dev/null
+++ b/go/res/values-sr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Додирните и задржите да бисте изабрали пречицу."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Двапут додирните и задржите да бисте изабрали пречицу или користите прилагођене радње."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Пречице"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Пречице за <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-sv/strings.xml b/go/res/values-sv/strings.xml
new file mode 100644
index 0000000..c3f434c
--- /dev/null
+++ b/go/res/values-sv/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Tryck länge om du vill ta upp en genväg."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Tryck snabbt två gånger och håll kvar om du vill ta upp en genväg eller använda anpassade åtgärder."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Genvägar"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Genvägar för <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-sw/strings.xml b/go/res/values-sw/strings.xml
new file mode 100644
index 0000000..0379ed0
--- /dev/null
+++ b/go/res/values-sw/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Gusa na ushikilie ili uchague njia ya mkato."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Gonga mara mbili na ushikilie ile uchague njia ya mkato au utumie vitendo maalum."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Njia za mkato"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Njia za mkato za <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-ta/strings.xml b/go/res/values-ta/strings.xml
new file mode 100644
index 0000000..50059b6
--- /dev/null
+++ b/go/res/values-ta/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"குறுக்குவழியைச் சேர்க்க, தொட்டு பிடித்திருக்கவும்."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"குறுக்குவழியை சேர்க்க, இருமுறை தட்டிப் பிடித்திருக்கவும் அல்லது தனிப்பயன் செயல்களைப் பயன்படுத்தவும்."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"குறுக்குவழிகள்"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> குறுக்குவழிகள்"</string>
+</resources>
diff --git a/go/res/values-te/strings.xml b/go/res/values-te/strings.xml
new file mode 100644
index 0000000..0bdf743
--- /dev/null
+++ b/go/res/values-te/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"సత్వరమార్గాన్ని ఎంచుకోవడానికి తాకి &amp; నొక్కి ఉంచండి."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"సత్వరమార్గాన్ని ఎంచుకోవడానికి లేదా అనుకూల చర్యలను ఉపయోగించడానికి రెండుసార్లు నొక్కి &amp;ఉంచండి."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"సత్వరమార్గాలు"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> సత్వరమార్గాలు"</string>
+</resources>
diff --git a/go/res/values-th/strings.xml b/go/res/values-th/strings.xml
new file mode 100644
index 0000000..e73d89f
--- /dev/null
+++ b/go/res/values-th/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"แตะค้างไว้เพื่อเลือกทางลัด"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"แตะสองครั้งค้างไว้เพื่อเลือกทางลัดหรือใช้การกระทำที่กำหนดเอง"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"ทางลัด"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"ทางลัด <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-tl/strings.xml b/go/res/values-tl/strings.xml
new file mode 100644
index 0000000..8f44ec5
--- /dev/null
+++ b/go/res/values-tl/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Pindutin nang matagal upang kumuha ng shortcut."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"I-double tap nang matagal upang kumuha ng shortcut o gumamit ng mga custom na pagkilos."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Mga Shortcut"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Mga shortcut sa <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-tr/strings.xml b/go/res/values-tr/strings.xml
new file mode 100644
index 0000000..f0f3cce
--- /dev/null
+++ b/go/res/values-tr/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Kısayol seçmek için dokunun ve basılı tutun."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Bir kısayolu seçmek veya özel işlemleri kullanmak için iki kez dokunun ve basılı tutun."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Kısayollar"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> kısayolları"</string>
+</resources>
diff --git a/go/res/values-uk/strings.xml b/go/res/values-uk/strings.xml
new file mode 100644
index 0000000..8d1f583
--- /dev/null
+++ b/go/res/values-uk/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Натисніть і утримуйте, щоб вибрати ярлик."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Двічі натисніть і утримуйте, щоб вибрати ярлик, або виконайте іншу дію."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Ярлики"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Ярлики додатка <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-ur/strings.xml b/go/res/values-ur/strings.xml
new file mode 100644
index 0000000..46bd823
--- /dev/null
+++ b/go/res/values-ur/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"کوئی شارٹ کٹ منتخب کرنے کیلئے ٹچ کریں اور دبائے رکھیں۔"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"کوئی شارٹ کٹ منتخب کرنے یا حسب ضرورت کاروائیاں استعمال کرنے کیلئے دو بار تھپتھپائیں اور دبائے رکھیں۔"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"شارٹ کٹس"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> شارٹ کٹس"</string>
+</resources>
diff --git a/go/res/values-uz-rUZ/strings.xml b/go/res/values-uz-rUZ/strings.xml
new file mode 100644
index 0000000..318bc15
--- /dev/null
+++ b/go/res/values-uz-rUZ/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Yorliqni tanlab olish uchun bosib turing."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Yorliqlar"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi yorliqlari"</string>
+</resources>
diff --git a/go/res/values-uz/strings.xml b/go/res/values-uz/strings.xml
new file mode 100644
index 0000000..318bc15
--- /dev/null
+++ b/go/res/values-uz/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Yorliqni tanlab olish uchun bosib turing."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Ikki marta bosib va bosib turgan holatda yorliqni tanlang yoki maxsus amaldan foydalaning."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Yorliqlar"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> ilovasi yorliqlari"</string>
+</resources>
diff --git a/go/res/values-vi/strings.xml b/go/res/values-vi/strings.xml
new file mode 100644
index 0000000..1197619
--- /dev/null
+++ b/go/res/values-vi/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Chạm và giữ để chọn lối tắt."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Nhấn đúp và giữ để chọn lối tắt hoặc sử dụng hành động tùy chỉnh."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Lối tắt"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"Lối tắt <xliff:g id="NAME">%1$s</xliff:g>"</string>
+</resources>
diff --git a/go/res/values-zh-rCN/strings.xml b/go/res/values-zh-rCN/strings.xml
new file mode 100644
index 0000000..57351d3
--- /dev/null
+++ b/go/res/values-zh-rCN/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"触摸并按住快捷方式即可选择快捷方式。"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"点按两次并按住快捷方式即可选择快捷方式,您也可以使用自定义操作。"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"快捷方式"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g>快捷方式"</string>
+</resources>
diff --git a/go/res/values-zh-rHK/strings.xml b/go/res/values-zh-rHK/strings.xml
new file mode 100644
index 0000000..dea7749
--- /dev/null
+++ b/go/res/values-zh-rHK/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"按住捷徑即可選取捷徑。"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"扲兩下然後扲住就可以揀選捷徑,或者用自訂嘅操作。"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"捷徑"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> 捷徑"</string>
+</resources>
diff --git a/go/res/values-zh-rTW/strings.xml b/go/res/values-zh-rTW/strings.xml
new file mode 100644
index 0000000..07ae2ed
--- /dev/null
+++ b/go/res/values-zh-rTW/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"按住捷徑即可選取。"</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"輕觸兩下並按住捷徑即可選取,你也可以使用自訂動作。"</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"捷徑"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"「<xliff:g id="NAME">%1$s</xliff:g>」捷徑"</string>
+</resources>
diff --git a/go/res/values-zu/strings.xml b/go/res/values-zu/strings.xml
new file mode 100644
index 0000000..e5051df
--- /dev/null
+++ b/go/res/values-zu/strings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="long_press_widget_to_add" msgid="4001616142797446267">"Thinta futhi ubambe ukuze ukhethe isinqamuleli."</string>
+    <string name="long_accessible_way_to_add" msgid="2725225828389948328">"Thepha kabulu futhi ubambe ukuze ukhethe isinqamuleli noma usebenzise izenzo zangokwezifiso."</string>
+    <string name="widget_button_text" msgid="4221900832360456858">"Izinqamuleli"</string>
+    <string name="widgets_bottom_sheet_title" msgid="3949835990909395998">"<xliff:g id="NAME">%1$s</xliff:g> izinqamuleli"</string>
+</resources>
diff --git a/go/res/values/strings.xml b/go/res/values/strings.xml
new file mode 100644
index 0000000..8ef2e62
--- /dev/null
+++ b/go/res/values/strings.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+* Copyright (C) 2017 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+
+    <!-- Message to tell the user to press and hold on a shortcut to add it [CHAR_LIMIT=50] -->
+    <string name="long_press_widget_to_add">Touch &amp; hold to pick up a shortcut.</string>
+    <!-- Accessibility spoken hint message in widget picker, which allows user to add a shortcut. Custom action is the label for additional accessibility actions available in this mode [CHAR_LIMIT=100] -->
+    <string name="long_accessible_way_to_add">Double-tap &amp; hold to pick up a shortcut or use custom actions.</string>
+    <!-- Text for shortcut add button -->
+    <string name="widget_button_text">Shortcuts</string>
+
+    <!-- Strings for widgets & more in the popup container/bottom sheet -->
+    <!-- Title for a bottom sheet that shows shortcuts for a particular app -->
+    <string name="widgets_bottom_sheet_title"><xliff:g id="name" example="Messenger">%1$s</xliff:g> shortcuts</string>
+
+</resources>
diff --git a/go/res/xml/device_profiles.xml b/go/res/xml/device_profiles.xml
new file mode 100644
index 0000000..094fc74
--- /dev/null
+++ b/go/res/xml/device_profiles.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2017 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<profiles xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3" >
+
+    <profile
+        launcher:name="Go Device"
+        launcher:minWidthDps="296"
+        launcher:minHeightDps="491.33"
+        launcher:numRows="4"
+        launcher:numColumns="4"
+        launcher:numFolderRows="4"
+        launcher:numFolderColumns="4"
+        launcher:iconSize="56"
+        launcher:iconTextSize="14.0"
+        launcher:defaultLayoutId="@xml/default_workspace_4x4"
+        />
+
+</profiles>
\ No newline at end of file
diff --git a/go/src_flags/com/android/launcher3/config/FeatureFlags.java b/go/src_flags/com/android/launcher3/config/FeatureFlags.java
new file mode 100644
index 0000000..b11bb7c
--- /dev/null
+++ b/go/src_flags/com/android/launcher3/config/FeatureFlags.java
@@ -0,0 +1,29 @@
+/*
+ * 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.config;
+
+/**
+ * Defines a set of flags used to control various launcher behaviors
+ */
+public final class FeatureFlags extends BaseFlags {
+
+    private FeatureFlags() {}
+
+    // Features to control Launcher3Go behavior
+    public static final boolean GO_DISABLE_WIDGETS = true;
+    public static final boolean LAUNCHER3_SPRING_ICONS = false;
+}
diff --git a/proto_overrides/launcher_log_extension.proto b/proto_overrides/launcher_log_extension.proto
new file mode 100644
index 0000000..2995aa2
--- /dev/null
+++ b/proto_overrides/launcher_log_extension.proto
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+syntax = "proto2";
+
+option java_package = "com.android.launcher3.userevent";
+option java_outer_classname = "LauncherLogExtensions";
+
+package userevent;
+
+//
+// Use this to add any app specific extensions to the proto.
+//
+message LauncherEventExtension {
+}
+
+message TargetExtension {
+}
diff --git a/protos/launcher_log.proto b/protos/launcher_log.proto
index 93e09ae..0bbec18 100644
--- a/protos/launcher_log.proto
+++ b/protos/launcher_log.proto
@@ -15,6 +15,8 @@
  */
 syntax = "proto2";
 
+import "launcher_log_extension.proto";
+
 option java_package = "com.android.launcher3.userevent";
 option java_outer_classname = "LauncherLogProto";
 
@@ -52,6 +54,7 @@
   optional int32 span_x = 13 [default = 1];// Used for ItemType.WIDGET
   optional int32 span_y = 14 [default = 1];// Used for ItemType.WIDGET
   optional int32 predictedRank = 15;
+  optional TargetExtension extension = 16;
 }
 
 // Used to define what type of item a Target would represent.
@@ -144,7 +147,6 @@
 //         Action (Touch) + Target + Target
 //
 message LauncherEvent {
-
   required Action action = 1;
 
   // List of targets that touch actions can be operated on.
@@ -157,4 +159,6 @@
 
   optional bool is_in_multi_window_mode = 7;
   optional bool is_in_landscape_mode = 8;
+
+  optional LauncherEventExtension extension = 9;
 }
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 4acc49d..d71b4c7 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed by %2$d hoog"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Raak en hou om self te plaas"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Voeg outomaties by"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Deursoek programme"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Laai tans programme …"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Kon geen programme kry wat by \"<xliff:g id="QUERY">%1$s</xliff:g>\" pas nie"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Soek meer programme"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Kennisgewings"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Niks meer spasie op die tuisskerm nie."</string>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 0f795b3..293b452 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ስፋት በ%2$d ከፍታ"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ራስዎ ለማስቀመጥ ነክተው ይያዙት"</string>
     <string name="place_automatically" msgid="8064208734425456485">"በራስ-ሰር አክል"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"መተግበሪያዎችን ይፈልጉ"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"መተግበሪያዎችን በመጫን ላይ..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"ከ«<xliff:g id="QUERY">%1$s</xliff:g>» ጋር የሚዛመዱ ምንም መተግበሪያዎች አልተገኙም"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"መተግበሪያዎችን ፈልግ"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"መተግበሪያዎችን በመጫን ላይ…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"ከ«<xliff:g id="QUERY">%1$s</xliff:g>» ጋር የሚዛመዱ ምንም መተግበሪያዎች አልተገኙም"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ተጨማሪ መተግበሪያዎች ይፈልጉ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ማሳወቂያዎች"</string>
     <string name="out_of_space" msgid="4691004494942118364">"በዚህ መነሻ ማያ ገጽ ላይ ምንም ቦታ የለም።"</string>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 0177166..6447bf0 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏العرض %1$d الطول %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"المس مع الاستمرار للإضافة يدويًا"</string>
     <string name="place_automatically" msgid="8064208734425456485">"إضافة تلقائيًا"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"البحث في التطبيقات"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"جارٍ تحميل التطبيقات…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"لم يتم العثور على أية تطبيقات تتطابق مع \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"بحث في التطبيقات"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"جارٍ تحميل التطبيقات…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"لم يتم العثور على أي تطبيقات تتطابق مع \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"البحث عن مزيد من التطبيقات"</string>
     <string name="notifications_header" msgid="1404149926117359025">"الإشعارات"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ليس هناك مساحة أخرى في هذه الشاشة الرئيسية."</string>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 6b50e4d..18f87bc 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d hündürlük %1$d enində"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Manual olaraq yerləşdirmək üçün toxunaraq basıb saxlayın"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Avtomatik əlavə edin"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Tətbiq Axtarın"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Tətbiqlər endirilir..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" sorğusuna uyğun Tətbiqlər tapılmadı"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tətbiqləri axtarın"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Tətbiqlər yüklənir…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> sorğusuna uyğun tətbiq tapılmadı"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Daha çox tətbiq üçün axtarış edin"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Bildirişlər"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Bu Əsas ekranda boş yer yoxdur."</string>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index d73b86f..777512a 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"širina od %1$d i visina od %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i zadržite da biste postavili ručno"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Automatski dodaj"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži još aplikacija"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obaveštenja"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Nema više prostora na ovom početnom ekranu."</string>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index b2ec143..0a31ddf 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Шырына: %1$d, вышыня: %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Каб размясціць уручную, дакраніцеся і ўтрымлівайце"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Дадаць аўтаматычна"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Пошук у Праграмах"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Ідзе загрузка праграм…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Праграм, якія адпавядаюць запыту \"<xliff:g id="QUERY">%1$s</xliff:g>\", не знойдзена"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук праграм"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Праграмы загружаюцца…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Праграм, якія адпавядаюць запыту \"<xliff:g id="QUERY">%1$s</xliff:g>\", не знойдзена"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукаць іншыя праграмы"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Апавяшчэнні"</string>
     <string name="out_of_space" msgid="4691004494942118364">"На гэтым Галоўным экране больш няма месца."</string>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 89feb35..3e05e0b 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d и височина %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Докоснете и задръжте, за да поставите ръчно"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Автоматично добавяне"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Търсене в приложенията"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Приложенията се зареждат…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Няма намерени приложения, съответстващи на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Търсене в приложенията"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Приложенията се зареждат…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Няма намерени приложения, съответстващи на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Търсене на още приложения"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Известия"</string>
     <string name="out_of_space" msgid="4691004494942118364">"На този начален екран няма повече място."</string>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 02a95f2..471602f 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -27,7 +27,7 @@
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"ডাউনলোড করা অ্যাপ্লিকেশান নিরাপদ মোডে অক্ষম রয়েছে"</string>
     <string name="safemode_widget_error" msgid="4863470563535682004">"সুরক্ষিত মোডে উইজেট নিষ্ক্রিয় থাকে"</string>
     <string name="shortcut_not_available" msgid="2536503539825726397">"শর্টকাটগুলি অনুপলব্ধ"</string>
-    <string name="home_screen" msgid="806512411299847073">"হোম স্ক্রীন"</string>
+    <string name="home_screen" msgid="806512411299847073">"হোম স্ক্রিন"</string>
     <string name="custom_actions" msgid="3747508247759093328">"কাস্টম অ্যাকশন"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"একটি উইজেট তুলতে তা স্পর্শ করে ধরে রাখুন৷"</string>
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"কোনো উইজেট বেছে নিতে দুবার-আলতো চেপে ধরে থাকুন অথবা কাস্টম ক্রিয়াগুলি ব্যবহার করুন৷"</string>
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%2$d উচ্চতা অনুযায়ী %1$d প্রস্থ"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"নিজে যোগ করতে টাচ করে ধরে রাখুন"</string>
     <string name="place_automatically" msgid="8064208734425456485">"স্বয়ংক্রিয়ভাবে যোগ করুন"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"অ্যাপ্লিকেশানগুলি অনুসন্ধান করুন"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"অ্যাপ্লিকেশানগুলি লোড হচ্ছে..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" এর সাথে মেলে এমন কোনো অ্যাপ্লিকেশান পাওয়া যায়নি"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"অ্যাপ অনুসন্ধান করুন"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"অ্যাপ লোড হচ্ছে…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" এর সাথে মেলে এমন কোনো অ্যাপ পাওয়া যায়নি"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"আরো অ্যাপ্লিকেশানের জন্য অনুসন্ধান করুন"</string>
     <string name="notifications_header" msgid="1404149926117359025">"বিজ্ঞপ্তি"</string>
     <string name="out_of_space" msgid="4691004494942118364">"এই হোম স্ক্রীনে আর কোনো জায়গা নেই৷"</string>
@@ -60,7 +60,7 @@
     <string name="folder_hint_text" msgid="6617836969016293992">"নামবিহীন ফোল্ডার"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> অক্ষম করা হয়েছে"</string>
     <string name="default_scroll_format" msgid="7475544710230993317">"%2$dটির মধ্যে %1$dটি পৃষ্ঠা"</string>
-    <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dটির %1$d নম্বর হোম স্ক্রীন"</string>
+    <string name="workspace_scroll_format" msgid="8458889198184077399">"%2$dটির %1$d নম্বর হোম স্ক্রিন"</string>
     <string name="workspace_new_page" msgid="257366611030256142">"নতুন হোম স্ক্রীনের পৃষ্ঠা"</string>
     <string name="folder_opened" msgid="94695026776264709">"ফোল্ডার খোলা হয়েছে, <xliff:g id="WIDTH">%1$d</xliff:g> বাই <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
     <string name="folder_tap_to_close" msgid="4625795376335528256">"ফোল্ডার বন্ধ করতে আলতো চাপ দিন"</string>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index 10cf2f9..49c862a 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, visina %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i držite da postavite ručno"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatski"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pretraži aplikacije"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Aplikacije se učitavaju…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nije pronađena nijedna aplikacija koja odgovara upitu \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretražite aplikacije"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikacije se učitavaju…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nije pronađena nijedna aplikacija za upit \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pretraži više aplikacija"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obavještenja"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Na ovom početnom ekranu nema više prostora."</string>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 6a4fbc2..b1a1f85 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d d\'amplada per %2$d d\'alçada"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toca i mantén premut l\'element per col·locar-lo manualment"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Afegeix automàticament"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca aplicacions"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"S\'estan carregant les aplicacions…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"No s\'ha trobat cap aplicació que coincideixi amb \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca més aplicacions"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificacions"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Ja no queda espai en aquesta pantalla d\'inici."</string>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index c1daed9..e6dee3c 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"šířka %1$d, výška %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Chcete-li položku umístit ručně, klepněte na ni a podržte ji"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Přidat automaticky"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hledat v aplikacích"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Načítání aplikací…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Dotazu „<xliff:g id="QUERY">%1$s</xliff:g>“ neodpovídají žádné aplikace"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Vyhledat další aplikace"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Oznámení"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Na této ploše již není místo."</string>
@@ -76,11 +76,11 @@
     <string name="allow_rotation_title" msgid="7728578836261442095">"Povolit otáčení plochy"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"Při otočení telefonu"</string>
     <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"Aktuální nastavení displeje neumožňuje otáčení"</string>
-    <string name="icon_badging_title" msgid="874121399231955394">"Puntíky s oznámeními"</string>
+    <string name="icon_badging_title" msgid="874121399231955394">"Puntíky s oznámením"</string>
     <string name="icon_badging_desc_on" msgid="2627952638544674079">"Zapnuto"</string>
     <string name="icon_badging_desc_off" msgid="5503319969924580241">"Vypnuto"</string>
     <string name="title_missing_notification_access" msgid="7503287056163941064">"Je třeba udělit přístup k oznámením"</string>
-    <string name="msg_missing_notification_access" msgid="281113995110910548">"Chcete-li zobrazovat puntíky s oznámeními, zapněte oznámení z aplikace <xliff:g id="NAME">%1$s</xliff:g>"</string>
+    <string name="msg_missing_notification_access" msgid="281113995110910548">"Chcete-li zobrazovat puntíky s oznámením, zapněte oznámení z aplikace <xliff:g id="NAME">%1$s</xliff:g>"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"Změnit nastavení"</string>
     <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"Přidat ikonu na plochu"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"Pro nové aplikace"</string>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 2e62009..653105e 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i bredden og %2$d i højden"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tryk, og hold fingeren nede for at placere manuelt"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Tilføj automatisk"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søg efter apps"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Indlæser apps…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Der blev ikke fundet nogen apps, som matcher \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søg efter flere apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Underretninger"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Der er ikke mere plads på denne startskærm."</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index ec94408..1c4cd7a 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breit und %2$d hoch"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Zum manuellen Hinzufügen gedrückt halten"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Automatisch hinzufügen"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps finden"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Apps werden geladen…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Keine Apps für \"<xliff:g id="QUERY">%1$s</xliff:g>\" gefunden"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Weitere Apps suchen"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Benachrichtigungen"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Auf diesem Startbildschirm ist kein Platz mehr vorhanden."</string>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 49c0fc6..25c8866 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Πλάτος %1$d επί ύψος %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Αγγίξτε παρατεταμένα για μη αυτόματη τοποθέτηση"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Αυτόματη προσθήκη"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Αναζήτηση εφαρμογών"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Φόρτωση εφαρμογών…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Δεν βρέθηκαν εφαρμογές για το ερώτημα \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Αναζήτηση εφαρμογών"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Φόρτωση εφαρμογών…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Δεν βρέθηκαν εφαρμογές αντιστοίχισης για \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Αναζήτηση περισσότερων εφαρμογών"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Ειδοποιήσεις"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Δεν υπάρχει χώρος σε αυτήν την αρχική οθόνη."</string>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 2077912..f3f10cc 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch &amp; hold to place manually"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 2077912..f3f10cc 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch &amp; hold to place manually"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 2077912..f3f10cc 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d wide by %2$d high"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Touch &amp; hold to place manually"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Add automatically"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Search apps"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Loading apps…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"No apps found matching \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Search for more apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="out_of_space" msgid="4691004494942118364">"No more room on this Home screen."</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 4054a42..f60e186 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén presionado para ubicarlo manualmente"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Agregar automáticamente"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar apps"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando apps…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"No hay apps que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
     <string name="out_of_space" msgid="4691004494942118364">"No hay más espacio en esta pantalla principal."</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 70addf7..3ab41ca 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de ancho por %2$d de alto"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantenlo pulsado para añadirlo manualmente"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Añadir automáticamente"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicaciones"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicaciones…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"No se han encontrado aplicaciones que contengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar más aplicaciones"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificaciones"</string>
     <string name="out_of_space" msgid="4691004494942118364">"No queda espacio en la pantalla de inicio."</string>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 28daf6c..9d9991d 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lai ja %2$d kõrge"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Puudutage pikalt, et käsitsi asetada"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Lisa automaatselt"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Otsige rakendustest"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Rakenduste laadimine ..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Päringule „<xliff:g id="QUERY">%1$s</xliff:g>” ei vastanud ükski rakendus"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Otsige rakendusi"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Rakenduste laadimine …"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Päringule „<xliff:g id="QUERY">%1$s</xliff:g>” ei vastanud ükski rakendus"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Otsi rohkem rakendusi"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Märguanded"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Sellel avaekraanil pole enam ruumi."</string>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 09a5f84..b6082fad 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d zabal eta %2$d luze"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Eduki sakatuta eskuz gehitzeko"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Gehitu automatikoki"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Bilatu aplikazioetan"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Aplikazioak kargatzen…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketarekin bat datorren aplikaziorik"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Bilatu aplikazioetan"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Aplikazioak kargatzen…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ez da aurkitu \"<xliff:g id="QUERY">%1$s</xliff:g>\" bilaketaren emaitzarik"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Bilatu aplikazio gehiago"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Jakinarazpenak"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Hasierako pantaila honetan ez dago toki gehiago."</string>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 4d116a2..8fe874b 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏%1$d عرض در %2$d طول"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"برای قرار دادن به‌صورت دستی لمس کنید و بکشید"</string>
     <string name="place_automatically" msgid="8064208734425456485">"افزودن خودکار"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"جستجوی برنامه‌ها"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"در حال بارگیری برنامه‌ها..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"هیچ برنامه‌ای مطابق با «<xliff:g id="QUERY">%1$s</xliff:g>» پیدا نشد"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"جستجوی برنامه‌ها"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"درحال بارگیری برنامه‌‌ها…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"هیچ برنامه‌ای در مطابقت با «<xliff:g id="QUERY">%1$s</xliff:g>» پیدا نشد"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"جستجوی برنامه‌های بیشتر"</string>
     <string name="notifications_header" msgid="1404149926117359025">"اعلان‌ها"</string>
     <string name="out_of_space" msgid="4691004494942118364">"فضای بیشتری در این صفحه اصلی موجود نیست."</string>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index d44e886..016dbbc 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Leveys: %1$d, korkeus: %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sijoita manuaalisesti koskettamalla pitkään."</string>
     <string name="place_automatically" msgid="8064208734425456485">"Lisää automaattisesti"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hae sovelluksia"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Ladataan sovelluksia…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"<xliff:g id="QUERY">%1$s</xliff:g> ei palauttanut sovelluksia."</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hae lisää sovelluksia"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Ilmoitukset"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Tässä aloitusruudussa ei ole enää tilaa."</string>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index e76954c..e57433d 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur sur %2$d de hauteur"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Maintenez le doigt sur l\'élément pour le placer manuellement"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Ajouter automatiquement"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications en cours…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application trouvée correspondant à « <xliff:g id="QUERY">%1$s</xliff:g> »"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Pas d\'espace libre sur l\'écran d\'accueil."</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index b82d7fc..dde4392 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largeur et %2$d de hauteur"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Appuyez de manière prolongée pour placer l\'élément manuellement"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Ajouter automatiquement"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Rechercher dans les applications"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Chargement des applications…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Aucune application ne correspond à la requête \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Rechercher plus d\'applications"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifications"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Pas d\'espace libre sur cet écran d\'accueil."</string>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index 4be3203..d55514d 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largo por %2$d de alto"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Mantén premido o elemento para colocalo manualmente"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Engadir automaticamente"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Aplicacións de busca"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Cargando aplicacións..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Non se atoparon aplicacións que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Buscar aplicacións"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Cargando aplicacións…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Non se atoparon aplicacións que coincidan con \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Buscar máis aplicacións"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificacións"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Non hai máis espazo nesta pantalla de inicio."</string>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 587d16e..7096a3e 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -29,15 +29,15 @@
     <string name="shortcut_not_available" msgid="2536503539825726397">"શૉર્ટકટ ઉપલબ્ધ નથી"</string>
     <string name="home_screen" msgid="806512411299847073">"હોમ સ્ક્રીન"</string>
     <string name="custom_actions" msgid="3747508247759093328">"કસ્ટમ ક્રિયાઓ"</string>
-    <string name="long_press_widget_to_add" msgid="7699152356777458215">"વિજેટ ચૂંટવા માટે ટચ કરો અને પકડી રાખો."</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"વિજેટ ચૂંટવા માટે સ્પર્શ કરો અને પકડી રાખો."</string>
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"વિજેટ ચૂંટવા અથવા કસ્ટમ ક્રિયાઓનો ઉપયોગ કરવા માટે બે વાર ટેપ કરો અને પકડી રાખો."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d પહોળાઈ X %2$d ઊંચાઈ"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"મેન્યુઅલી મૂકવા માટે ટચ કરી દબાવી રાખો"</string>
     <string name="place_automatically" msgid="8064208734425456485">"આપમેળે ઉમેરો"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"શોધ ઍપ્લિકેશનો"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"શોધ ઍપ્લિકેશનો"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"ઍપ્લિકેશનો લોડ કરી રહ્યું છે…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"થી મેળ ખાતી કોઈ ઍપ્લિકેશનો મળી નથી"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"વધુ ઍપ્લિકેશનો શોધો"</string>
     <string name="notifications_header" msgid="1404149926117359025">"સૂચનાઓ"</string>
     <string name="out_of_space" msgid="4691004494942118364">"આ હોમ સ્ક્રીન પર વધુ જગ્યા નથી."</string>
@@ -72,7 +72,7 @@
     <string name="wallpaper_button_text" msgid="8404103075899945851">"વૉલપેપર્સ"</string>
     <string name="settings_button_text" msgid="8873672322605444408">"હોમ સેટિંગ્સ"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"તમારા વ્યવસ્થાપક દ્વારા અક્ષમ કરેલ"</string>
-    <string name="accessibility_action_overview" msgid="6257665857640347026">"વિહંગાવલોકન"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"ઝલક"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"હોમ સ્ક્રીનને ફેરવવાની મંજૂરી આપો"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"જ્યારે ફોન ફેરવવામાં આવે ત્યારે"</string>
     <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"વર્તમાન પ્રદર્શન સેટિંગ ફેરવવાની પરવાનગી આપતી નથી"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 16eefa7..f1ee0f2 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौड़ाई गुणा %2$d ऊंचाई"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"मैन्युअल रूप से जोड़ने के लिए स्पर्श करके रखें"</string>
     <string name="place_automatically" msgid="8064208734425456485">"अपने आप जोड़ें"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ऐप्‍स खोजें"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"ऐप्स लोड हो रहे हैं..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" से मिलान करने वाला कोई ऐप नहीं मिला"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ऐप्लिकेशन खोजें"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"ऐप्लिकेशन लोड हो रहे हैं…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" से मिलता-जुलता कोई ऐप्लिकेशन नहीं मिला"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक ऐप्लिकेशन खोजें"</string>
     <string name="notifications_header" msgid="1404149926117359025">"नोटिफ़िकेशन"</string>
     <string name="out_of_space" msgid="4691004494942118364">"इस होम स्‍क्रीन पर स्थान शेष नहीं है."</string>
@@ -72,7 +72,7 @@
     <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
     <string name="settings_button_text" msgid="8873672322605444408">"होम सेटिंग"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपके व्यवस्थापक द्वारा अक्षम"</string>
-    <string name="accessibility_action_overview" msgid="6257665857640347026">"अवलोकन"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"खास जानकारी"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"होमस्क्रीन घुमाने की अनुमति दें"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"फ़ोन घुुमाए जाने पर"</string>
     <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"वर्तमान प्रदर्शन सेटिंग घुमाने की अनुमति नहीं देती"</string>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 01b28f1..aaae258 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d širine i %2$d visine"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dodirnite i zadržite stavku da biste je postavili ručno"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatski"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Pretraži aplikacije"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pretraži aplikacije"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Učitavanje aplikacija…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nema aplikacija podudarnih s upitom \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Traži više aplikacija"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obavijesti"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Na ovom početnom zaslonu više nema mjesta."</string>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 68c2a6c..2da64b0 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d széles és %2$d magas"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tartsa lenyomva a manuális hozzáadáshoz"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Automatikus hozzáadás"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Alkalmazások keresése"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Alkalmazások betöltése…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nem található alkalmazás a(z) „<xliff:g id="QUERY">%1$s</xliff:g>” lekérdezésre"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"További alkalmazások keresése"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Értesítések"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Nincs több hely ezen a kezdőképernyőn."</string>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index 413f51f..2b55e96 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Լայնությունը՝ %1$d, բարձրությունը՝ %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Հպեք և պահեք՝ ձեռքով տեղադրելու համար"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Ավելացնել ավտոմատ կերպով"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Հավելվածների որոնում"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Հավելվածների բեռնում…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"«<xliff:g id="QUERY">%1$s</xliff:g>» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Որոնել հավելվածներ"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Հավելվածների բեռնում…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"«<xliff:g id="QUERY">%1$s</xliff:g>» հարցմանը համապատասխանող հավելվածներ չեն գտնվել"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Որոնել այլ հավելվածներ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Ծանուցումներ"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Այլևս տեղ չկա այս հիմնական էկրանին:"</string>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index af84cfc..379a960 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"lebar %1$d x tinggi %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh &amp; tahan untuk menempatkan secara manual"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Tambahkan otomatis"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Telusuri aplikasi"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Memuat aplikasi…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Tidak ditemukan aplikasi yang cocok dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Telusuri aplikasi lainnya"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifikasi"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Tidak ada ruang lagi pada layar Utama ini."</string>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index 3c54fc2..cf178a5 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d á breidd og %2$d á hæð"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Haltu inni til að staðsetja handvirkt"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Bæta sjálfkrafa við"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Leita í forritum"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Hleður forrit…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Ekki fundust forrit sem samsvara „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Leita í forritum"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Hleður forrit…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ekki fundust forrit sem samsvara „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Leita að fleiri forritum"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Tilkynningar"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Ekki meira pláss á þessum heimaskjá."</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 7e062f3..a52aee4 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d di larghezza per %2$d di altezza"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tieni premuto per posizionare l\'elemento manualmente"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Aggiungi automaticamente"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cerca nelle app"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Caricamento delle app…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nessuna app trovata corrispondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cerca altre app"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notifiche"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Spazio nella schermata Home esaurito."</string>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index eb00846..650a90d 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏רוחב %1$d על גובה %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"גע והחזק כדי להוסיף ידנית"</string>
     <string name="place_automatically" msgid="8064208734425456485">"הוסף באופן אוטומטי"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"חפש אפליקציות"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"טוען אפליקציות…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"לא נמצאו אפליקציות התואמות ל-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"חיפוש אפליקציות"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"טוען אפליקציות…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"לא נמצאו אפליקציות התואמות ל-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"חפש אפליקציות נוספות"</string>
     <string name="notifications_header" msgid="1404149926117359025">"הודעות"</string>
     <string name="out_of_space" msgid="4691004494942118364">"אין עוד מקום במסך דף הבית הזה."</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 2859ca8..4071a6c 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"幅 %1$d、高さ %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"押し続けると、手動で追加できます"</string>
     <string name="place_automatically" msgid="8064208734425456485">"自動的に追加"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"アプリを検索"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"アプリを読み込んでいます…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"「<xliff:g id="QUERY">%1$s</xliff:g>」に一致するアプリは見つかりませんでした"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"アプリを検索"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"アプリを読み込んでいます…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"「<xliff:g id="QUERY">%1$s</xliff:g>」に一致するアプリは見つかりませんでした"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"他のアプリを検索"</string>
     <string name="notifications_header" msgid="1404149926117359025">"通知"</string>
     <string name="out_of_space" msgid="4691004494942118364">"このホーム画面に空きスペースがありません。"</string>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 1217108..7e8b46c 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"სიგრძე: %1$d, სიგანე: %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ხანგრძლივად შეეხეთ ხელით განსათავსებლად"</string>
     <string name="place_automatically" msgid="8064208734425456485">"ავტომატურად დამატება"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"აპების ძიება"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"აპები იტვირთება..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"„<xliff:g id="QUERY">%1$s</xliff:g>“-ის თანხვედრი აპები არ მოიძებნა"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"აპების ძიება"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"აპები იტვირთება…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"„<xliff:g id="QUERY">%1$s</xliff:g>“-ის თანხვედრი აპები არ მოიძებნა"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"მეტი აპის პოვნა"</string>
     <string name="notifications_header" msgid="1404149926117359025">"შეტყობინებები"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ამ მთავარ ეკრანზე ადგილი აღარ არის."</string>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 6cb4fa7..50ed9aa 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ені: %1$d, биіктігі: %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Қолмен қою үшін басып тұрыңыз"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Автоматты енгізу"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Қолданбаларды іздеу"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Қолданбалар жүктелуде…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"«<xliff:g id="QUERY">%1$s</xliff:g>» сұрауына сәйкес келетін қолданбалар жоқ"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Қолданбаларды іздеу"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Қолданбалар жүктелуде…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сұрауына сәйкес келетін қолданбалар жоқ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Қосымша қолданбалар іздеу"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Хабарландырулар"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Бұл Негізгі экранда орын қалмады."</string>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 8782230..7028f7e 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"ទទឺង %1$d គុណនឹងកម្ពស់ %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ចុច​ឲ្យជាប់​ដើម្បី​បញ្ចូលវា​ដោយផ្ទាល់"</string>
     <string name="place_automatically" msgid="8064208734425456485">"បញ្ចូល​ដោយ​ស្វ័យ​ប្រវត្តិ"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ស្វែងរកកម្មវិធី"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"កំពុងដំណើរការកម្មវិធី..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"គ្មានកម្មវិធីដែលត្រូវជាមួយ \"<xliff:g id="QUERY">%1$s</xliff:g>\" ទេ"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ស្វែងរក​កម្មវិធី"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"កំពុងផ្ទុកកម្មវិធី…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"រកមិនឃើញកម្មវិធី​ដែលត្រូវគ្នាជាមួយ \"<xliff:g id="QUERY">%1$s</xliff:g>\" ទេ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ស្វែងរកកម្មវិធីច្រើនទៀត"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ការ​ជូនដំណឹង"</string>
     <string name="out_of_space" msgid="4691004494942118364">"គ្មាន​បន្ទប់​នៅ​លើ​អេក្រង់​ដើម​នេះ​ទៀត​ទេ។"</string>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index 7566503..9a31649 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ಅಗಲ ಮತ್ತು %2$d ಎತ್ತರ"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ಹಸ್ತಚಾಲಿತವಾಗಿ ಸೇರಿಸಲು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹೋಲ್ಡ್ ಮಾಡಿ"</string>
     <string name="place_automatically" msgid="8064208734425456485">"ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಸೇರಿಸಿ"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ಅಪ್ಲಿಕೇಷನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಲೋಡ್ ಮಾಡಲಾಗುತ್ತಿದೆ..."</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ಹೊಂದಿಕೆಯ ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್‌ಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ಮತ್ತಷ್ಟು ಅಪ್ಲಿಕೇಶನ್‌ಗಳನ್ನು ಹುಡುಕಿ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ಅಧಿಸೂಚನೆಗಳು"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ಈ ಮುಖಪುಟದ ಪರದೆಯಲ್ಲಿ ಹೆಚ್ಚು ಸ್ಥಳಾವಕಾಶವಿಲ್ಲ."</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 9926d4f..e3511d4 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"너비 %1$d, 높이 %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"길게 터치하여 직접 장소 추가"</string>
     <string name="place_automatically" msgid="8064208734425456485">"자동으로 추가"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"앱 검색"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"앱 로드 중..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\'<xliff:g id="QUERY">%1$s</xliff:g>\'와(과) 일치하는 앱이 없습니다."</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"앱 검색"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"앱 로드 중…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\'<xliff:g id="QUERY">%1$s</xliff:g>\'과(와) 일치하는 앱이 없습니다."</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"더 많은 앱 검색"</string>
     <string name="notifications_header" msgid="1404149926117359025">"알림"</string>
     <string name="out_of_space" msgid="4691004494942118364">"홈 화면에 더 이상 공간이 없습니다."</string>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 7d19b30..85ba8be 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Туурасы: %1$d, бийиктиги: %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Кол менен жайгаштыруу үчүн басып туруп, таштаңыз"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Автоматтык түрдө кошуу"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Колдонмолорду издөө"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Колдонмолор жүктөлүүдө…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" дал келген колдонмолор табылган жок"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Колдонмолорду издөө"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Колдонмолор жүктөлүүдө…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" сурамына дал келген колдонмолор табылган жок"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Көбүрөөк колдонмолорду издөө"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Эскертмелер"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Бул Үй экранында бош орун жок."</string>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index e31584d..9a50c4b 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"ກວ້າງ %1$d ຄູນສູງ %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ແຕະຄ້າງໄວ້ເພື່ອວາງດ້ວຍຕົນເອງ"</string>
     <string name="place_automatically" msgid="8064208734425456485">"ເພີ່ມໂດຍອັດຕະໂນມັດ"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ຊອກຫາແອັບ"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"​ກຳ​ລັງ​ໂຫລດ​ແອັບ..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"ບໍ່​ພົບ​ແອັບ​ໃດ​ທີ່​ກົງ​ກັນ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ຊອກຫາແອັບ"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"ກໍາລັງໂຫຼດແອັບ…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"ບໍ່ພົບແອັບທີ່ກົງກັບ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ຊອກຫາແອັບເພີ່ມເຕີມ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ການແຈ້ງເຕືອນ"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ບໍ່ມີຫ້ອງເຫຼືອໃນໜ້າຈໍຫຼັກນີ້."</string>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index cbd6048..d415e4d 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plotis ir %2$d aukštis"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Palieskite ir palaikykite, kad padėtumėte patys"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Pridėti automatiškai"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Paieškos programos"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Įkeliamos programos…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nerasta jokių užklausą „<xliff:g id="QUERY">%1$s</xliff:g>“ atitinkančių programų"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Ieškoti daugiau programų"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Pranešimai"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Šiame pagrindiniame ekrane vietos nebėra."</string>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 6411dc8..2d8bfd8 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d plats un %2$d augsts"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Pieskarieties un turiet, lai manuāli pievienotu"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Pievienot automātiski"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Meklēt lietotnes"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Notiek lietotņu ielāde…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Vaicājumam “<xliff:g id="QUERY">%1$s</xliff:g>” neatbilda neviena lietotne"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Meklēt citas lietotnes"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Paziņojumi"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Šajā sākuma ekrānā vairs nav vietas."</string>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index 1061ebf..7d95a23 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d широк на %2$d висок"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Допрете и задржете за рачно поставување"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Додај автоматски"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Пребарување апликации"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Се вчитуваат апликации…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Не се најдени апликации што одговараат на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пребарувајте апликации"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Се вчитуваат апликации…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Не се најдени апликации што одговараат на „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Пребарај други апликации"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Известувања"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Нема повеќе простор на овој екран на почетната страница."</string>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 62bcc8c..0cc7aa0 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d വീതിയും %2$d ഉയരവും"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"സ്വമേധയാ സ്ഥാപിക്കുന്നതിന് സ്‌പർശിച്ചുപിടിക്കുക"</string>
     <string name="place_automatically" msgid="8064208734425456485">"സ്വയമേവ ചേർക്കുക"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ആപ്പുകളെ തിരയുക"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"ആപ്പുകൾ ലോഡുചെയ്യുന്നു..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പ്‌സൊന്നും കണ്ടെത്തിയില്ല"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ആപ്പുകൾ തിരയുക"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"ആപ്പുകൾ ലോഡുചെയ്യുന്നു..."</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" എന്നതുമായി പൊരുത്തപ്പെടുന്ന ആപ്പുകളൊന്നും കണ്ടെത്തിയില്ല"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"കൂടുതൽ ആപ്പുകൾക്ക് തിരയുക"</string>
     <string name="notifications_header" msgid="1404149926117359025">"അറിയിപ്പുകൾ"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ഈ ഹോം സ്‌ക്രീനിൽ ഒഴിവൊന്നുമില്ല."</string>
@@ -72,7 +72,7 @@
     <string name="wallpaper_button_text" msgid="8404103075899945851">"വാൾപേപ്പർ"</string>
     <string name="settings_button_text" msgid="8873672322605444408">"ഹോം ക്രമീകരണം"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"അഡ്മിൻ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു"</string>
-    <string name="accessibility_action_overview" msgid="6257665857640347026">"കാഴ്ച"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"അവലോകനം"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"ഹോം സ്ക്രീൻ തിരിക്കൽ അനുവദിക്കുക"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"ഫോൺ തിരിച്ച നിലയിലായിരിക്കുമ്പോൾ"</string>
     <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"നിലവിലെ ഡിസ്പ്ലേ ക്രമീകരണം തിരിക്കൽ അനുവദിക്കുന്നില്ല"</string>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index b350570..22479cc 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d өргөн %2$d өндөр"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Гараар байршуулахын тулд дараад хүлээнэ үү"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Автоматаар нэмэх"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Апп хайх"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Аппликейшныг ачаалж байна..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"-д нийцэх апп олдсонгүй"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Апп хайх"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Аппыг ачааллаж байна..."</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"-д тохирох апп олдсонгүй"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Бусад апп-г хайх"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Мэдэгдэл"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Энэ Нүүр дэлгэц зайгүй."</string>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 3435061..751ad22 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -27,31 +27,31 @@
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"डाउनलोड केलेला अ‍ॅप सुरक्षित मोड मध्‍ये अक्षम केला"</string>
     <string name="safemode_widget_error" msgid="4863470563535682004">"विजेट सुरक्षित मोडमध्ये अक्षम झाले"</string>
     <string name="shortcut_not_available" msgid="2536503539825726397">"शॉर्टकट उपलब्ध नाही"</string>
-    <string name="home_screen" msgid="806512411299847073">"मुख्यपृष्ठ"</string>
+    <string name="home_screen" msgid="806512411299847073">"होम स्क्रीन"</string>
     <string name="custom_actions" msgid="3747508247759093328">"सानुकूल क्रिया"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"विजेट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
     <string name="long_accessible_way_to_add" msgid="4289502106628154155">"एक विजेट निवडण्यासाठी दोनदा टॅप करा आणि धरून ठेवा किंवा सानुकूल क्रिया वापरा."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d रूंद बाय %2$d उंच"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"स्वतः ठेवण्यासाठी स्पर्श करा आणि धरून ठेवा"</string>
-    <string name="place_automatically" msgid="8064208734425456485">"स्वयंचलितपणे जोडा"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"अॅप्स शोधा"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"अॅप्स लोड करीत आहे..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत"</string>
+    <string name="place_automatically" msgid="8064208734425456485">"अापोआप जोडा"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"अॅप्स शोधा"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"अॅप्स लोड करत आहे…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" शी जुळणारे कोणतेही अॅप्स आढळले नाहीत"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"अधिक अॅप्स शोधा"</string>
     <string name="notifications_header" msgid="1404149926117359025">"सूचना"</string>
     <string name="out_of_space" msgid="4691004494942118364">"या मुख्य स्क्रीनवर आणखी जागा नाही."</string>
     <string name="hotseat_out_of_space" msgid="7448809638125333693">"आवडीच्या ट्रे मध्ये आणखी जागा नाही"</string>
     <string name="all_apps_button_label" msgid="8130441508702294465">"अॅप्स सूची"</string>
-    <string name="all_apps_home_button_label" msgid="252062713717058851">"मुख्‍यपृष्‍ठ"</string>
+    <string name="all_apps_home_button_label" msgid="252062713717058851">"होम"</string>
     <string name="remove_drop_target_label" msgid="7812859488053230776">"काढा"</string>
     <string name="uninstall_drop_target_label" msgid="4722034217958379417">"विस्थापित करा"</string>
     <string name="app_info_drop_target_label" msgid="692894985365717661">"अॅप माहिती"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"शॉर्टकट स्‍थापित करा"</string>
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"वापरकर्ता हस्तक्षेपाशिवाय शॉर्टकट जोडण्यास अॅप ला अनुमती देते."</string>
-    <string name="permlab_read_settings" msgid="1941457408239617576">"मुख्यपृष्ठ सेटिंग्ज आणि शॉर्टकट वाचा"</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"होम सेटिग्ज आणि शॉर्टकट वाचा"</string>
     <string name="permdesc_read_settings" msgid="5833423719057558387">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट वाचण्यास अॅप ला अनुमती देते."</string>
-    <string name="permlab_write_settings" msgid="3574213698004620587">"मुख्यपृष्ठ सेटिंग्ज आणि शॉर्टकट लिहा"</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"होम स्क्रीन सेटिंग्ज आणि शॉर्टकट लिहा"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अॅप ला अनुमती देते."</string>
     <string name="msg_no_phone_permission" msgid="9208659281529857371">"<xliff:g id="APP_NAME">%1$s</xliff:g> ला फोन कॉल करण्याची अनुमती नाही"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"विजेट लोड करण्यात समस्या"</string>
@@ -72,7 +72,7 @@
     <string name="wallpaper_button_text" msgid="8404103075899945851">"वॉलपेपर"</string>
     <string name="settings_button_text" msgid="8873672322605444408">"होम सेटिंग्‍ज"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"आपल्या प्रशासकाने अक्षम केले"</string>
-    <string name="accessibility_action_overview" msgid="6257665857640347026">"विहंगावलोकन"</string>
+    <string name="accessibility_action_overview" msgid="6257665857640347026">"अवलोकन"</string>
     <string name="allow_rotation_title" msgid="7728578836261442095">"मुख्यस्क्रीन फिरविण्‍यास अनुमती द्या"</string>
     <string name="allow_rotation_desc" msgid="8662546029078692509">"फोन फिरविला जातो तेव्हा"</string>
     <string name="allow_rotation_blocked_desc" msgid="3212602545192996253">"वर्तमान प्रदर्शन सेटिंग फिरविण्यास परवानगी देत नाही"</string>
@@ -82,7 +82,7 @@
     <string name="title_missing_notification_access" msgid="7503287056163941064">"सूचनांच्या अ‍ॅक्सेसची आवश्यकता आहे"</string>
     <string name="msg_missing_notification_access" msgid="281113995110910548">"सूचना बिंदू दाखवण्यासाठी, <xliff:g id="NAME">%1$s</xliff:g> साठी अ‍ॅप सूचना चालू करा"</string>
     <string name="title_change_settings" msgid="1376365968844349552">"सेटिंग्ज बदला"</string>
-    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"मुख्य स्क्रीनवर चिन्ह जोडा"</string>
+    <string name="auto_add_shortcuts_label" msgid="8222286205987725611">"होम स्क्रीनवर आयकन जोडा"</string>
     <string name="auto_add_shortcuts_description" msgid="7117251166066978730">"नवीन अॅप्ससाठी"</string>
     <string name="icon_shape_override_label" msgid="2977264953998281004">"चिन्हाचा आकार बदला"</string>
     <string name="icon_shape_system_default" msgid="1709762974822753030">"सिस्‍टमचे डीफॉल्‍ट वापरा"</string>
@@ -99,7 +99,7 @@
     <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> डाउनलोड होत आहे , <xliff:g id="PROGRESS">%2$s</xliff:g> पूर्ण झाले"</string>
     <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> स्थापित करण्याची प्रतिक्षा करीत आहे"</string>
     <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> विजेट"</string>
-    <string name="action_add_to_workspace" msgid="8902165848117513641">"मुख्य स्क्रीनवर जोडा"</string>
+    <string name="action_add_to_workspace" msgid="8902165848117513641">"होम स्क्रीनवर जोडा"</string>
     <string name="action_move_here" msgid="2170188780612570250">"आयटम येथे हलवा"</string>
     <string name="item_added_to_workspace" msgid="4211073925752213539">"आयटम मुख्य स्क्रीनवर जोडला"</string>
     <string name="item_removed" msgid="851119963877842327">"आयटम काढला"</string>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 0dfe81a..f94b167 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Lebar %1$d kali tinggi %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Sentuh &amp; tahan untuk meletakkan widget/ikon secara manual"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Tambahkan secara automatik"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Cari Apl"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Memuatkan Apl…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Tiada Apl yang ditemui sepadan dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Cari apl"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Memuatkan apl…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Tiada apl yang ditemui sepadan dengan \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Cari lagi apl"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Pemberitahuan"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Tiada lagi ruang pada skrin Laman Utama ini."</string>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 3d1311f..74574b9 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"အလျား %1$d နှင့် အမြင့် %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ကိုယ်တိုင်ထည့်ရန် ထိထားပါ"</string>
     <string name="place_automatically" msgid="8064208734425456485">"အလိုအလျောက် ထည့်ရန်"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ရှာဖွေမှု အက်ပ်များ"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"အက်ပ်များ ရယူနေစဉ်..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" နှင့်ကိုက်ညီသည့် အပ်ဖ်များမတွေ့ပါ"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ရှာဖွေမှု အက်ပ်များ"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"အက်ပ်များကို ဖွင့်နေသည်…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" နှင့်ကိုက်ညီသည့် အပ်ပ်များကို မတွေ့ပါ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"နောက်ထပ် အက်ပ်များကို ရှာပါ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"အကြောင်းကြားချက်များ"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ဤပင်မမျက်နှာစာတွင် နေရာလွတ် မကျန်တော့ပါ"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 5503451..65247c1 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bredde x %2$d høyde"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Trykk og hold for å plassere manuelt"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Legg til automatisk"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Søk etter apper"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Laster inn appene …"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Fant ingen apper som samsvarer med «<xliff:g id="QUERY">%1$s</xliff:g>»"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Søk etter flere apper"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Varsler"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Denne startsiden er full."</string>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index b28e0e2..904dad4 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d चौडाइ गुणा %2$d उचाइ"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"म्यानुअल तरिकाले थप्न छुनुहोस् र थिची राख्नुहोस्‌"</string>
     <string name="place_automatically" msgid="8064208734425456485">"स्वतः थप्नुहोस्"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"अनुप्रयोगहरू खोज्नुहोस्"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"अनुप्रयोगहरू लोड गरिँदै..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै अनुप्रयोगहरू फेला परेनन्"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"खोजसम्बन्धी अनुप्रयोगहरू"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"अनुप्रयोगहरू लोड गर्दै…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" सँग मिल्दो कुनै अनुप्रयोग भेटिएन"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"थप अनुप्रयोगहरू खोज्नुहोस्"</string>
     <string name="notifications_header" msgid="1404149926117359025">"सूचनाहरू"</string>
     <string name="out_of_space" msgid="4691004494942118364">"यो गृह स्क्रिनमा कुनै थप ठाउँ छैन।"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 42871ab..7e8def4 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d breed en %2$d hoog"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Tik op een item en houd dit vast om het handmatig te plaatsen"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Automatisch toevoegen"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps zoeken"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Apps laden…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Er zijn geen apps gevonden die overeenkomen met \'<xliff:g id="QUERY">%1$s</xliff:g>\'"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Zoeken naar meer apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Meldingen"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Er is geen ruimte meer op dit startscherm."</string>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index aaf4c92..cf5351c 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -25,7 +25,7 @@
     <string name="activity_not_found" msgid="8071924732094499514">"ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ।"</string>
     <string name="activity_not_available" msgid="7456344436509528827">"ਐਪ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"ਡਾਊਨਲੋਡ ਕੀਤਾ ਐਪ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"</string>
-    <string name="safemode_widget_error" msgid="4863470563535682004">"ਵਿਜਿਟ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"ਵਿਜੇਟ ਸੁਰੱਖਿਅਤ ਮੋਡ ਵਿੱਚ ਅਸਮਰਥਿਤ"</string>
     <string name="shortcut_not_available" msgid="2536503539825726397">"ਸ਼ਾਰਟਕੱਟ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="home_screen" msgid="806512411299847073">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string>
     <string name="custom_actions" msgid="3747508247759093328">"ਵਿਸ਼ੇਸ਼-ਵਿਉਂਤਬੱਧ ਕਾਰਵਾਈਆਂ"</string>
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ਚੌੜਾਈ ਅਤੇ %2$d ਲੰਬਾਈ"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"ਹੱਥੀਂ ਰੱਖਣ ਲਈ ਸਪੱਰਸ਼ ਕਰੋ ਅਤੇ ਦਬਾਈ ਰੱਖੋ"</string>
     <string name="place_automatically" msgid="8064208734425456485">"ਸਵੈਚਲਿਤ ਤਰੀਕੇ ਨਾਲ ਸ਼ਾਮਲ ਕਰੋ"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ਐਪਸ ਖੋਜੋ"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ਨਾਲ ਮਿਲਦੀਆਂ ਕੋਈ ਵੀ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ਐਪਾਂ ਖੋਜੋ"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"ਐਪਾਂ ਨੂੰ ਲੋਡ ਕੀਤਾ ਜਾ ਰਿਹਾ ਹੈ..."</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ਨਾਲ ਮੇਲ ਖਾਂਦੀਆਂ ਕੋਈ ਐਪਾਂ ਨਹੀਂ ਮਿਲੀਆਂ"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ਹੋਰ ਐਪਾਂ ਖੋਜੋ"</string>
     <string name="notifications_header" msgid="1404149926117359025">"ਸੂਚਨਾਵਾਂ"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ਇਸ ਹੋਮ ਸਕ੍ਰੀਨ ਲਈ ਹੋਰ ਖਾਲੀ ਸਥਾਨ ਨਹੀਂ ਹੈ।"</string>
@@ -68,7 +68,7 @@
     <string name="folder_closed" msgid="4100806530910930934">"ਫੋਲਡਰ ਬੰਦ ਕੀਤਾ"</string>
     <string name="folder_renamed" msgid="1794088362165669656">"ਫੋਲਡਰ ਨੂੰ <xliff:g id="NAME">%1$s</xliff:g> ਮੁੜ ਨਾਮ ਦਿੱਤਾ ਗਿਆ"</string>
     <string name="folder_name_format" msgid="6629239338071103179">"ਫੋਲਡਰ: <xliff:g id="NAME">%1$s</xliff:g>"</string>
-    <string name="widget_button_text" msgid="2880537293434387943">"ਵਿਜਿਟ"</string>
+    <string name="widget_button_text" msgid="2880537293434387943">"ਵਿਜੇਟ"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"ਵਾਲਪੇਪਰ"</string>
     <string name="settings_button_text" msgid="8873672322605444408">"ਹੋਮ ਸੈਟਿੰਗਾਂ"</string>
     <string name="msg_disabled_by_admin" msgid="6898038085516271325">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਦੁਆਰਾ ਅਯੋਗ ਬਣਾਈ ਗਈ"</string>
@@ -98,7 +98,7 @@
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ਇਸ ਆਈਕਨ ਲਈ ਐਪ ਇੰਸਟੌਲ ਨਹੀਂ ਕੀਤਾ ਹੋਇਆ ਹੈ। ਤੁਸੀਂ ਇਸਨੂੰ ਹਟਾ ਸਕਦੇ ਹੋ ਜਾਂ ਐਪ ਖੋਜ ਸਕਦੇ ਹੋ ਅਤੇ ਇਸਨੂੰ ਮੈਨੂਅਲੀ ਇੰਸਟੌਲ ਕਰ ਸਕਦੇ ਹੋ।"</string>
     <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> ਡਾਉਨਲੋਡ ਹੋਰ ਰਿਹਾ ਹੈ, <xliff:g id="PROGRESS">%2$s</xliff:g> ਸੰਪੂਰਣ"</string>
     <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ਸਥਾਪਿਤ ਕਰਨ ਦੀ ਉਡੀਕ ਕਰ ਰਿਹਾ ਹੈ"</string>
-    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ਵਿਜਿਟ"</string>
+    <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> ਵਿਜੇਟ"</string>
     <string name="action_add_to_workspace" msgid="8902165848117513641">"ਹੋਮ ਸਕ੍ਰੀਨ ਵਿੱਚ ਜੋੜੋ"</string>
     <string name="action_move_here" msgid="2170188780612570250">"ਆਈਟਮ ਨੂੰ ਇੱਥੇ ਮੂਵ ਕਰੋ"</string>
     <string name="item_added_to_workspace" msgid="4211073925752213539">"ਆਈਟਮ ਨੂੰ ਮੁੱਖ ਸਕ੍ਰੀਨ ਵਿੱਚ ਜੋੜਿਆ ਗਿਆ"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 8edcd99..c07f7de 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Szerokość %1$d, wysokość %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Kliknij i przytrzymaj, by umieścić ręcznie"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Dodaj automatycznie"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Wyszukaj aplikacje"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Ładuję aplikacje…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nie znaleziono aplikacji pasujących do zapytania „<xliff:g id="QUERY">%1$s</xliff:g>”"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Wyszukaj więcej aplikacji"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Powiadomienia"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Brak miejsca na tym ekranie głównym."</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index f6ca7b4..100f07b 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toque sem soltar para colocar manualmente"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Adicionar automaticamente"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Pesquisar aplicações"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"A carregar aplicações…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhuma aplicação correspondente a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais aplicações"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Sem espaço suficiente neste Ecrã principal."</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 11bfc02..d75159f 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d de largura por %2$d de altura"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Toque e mantenha pressionado para posicionar manualmente"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Adicionar automaticamente"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Apps de pesquisa"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Carregando apps…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenhum app encontrado que corresponda a \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Pesquisar mais apps"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificações"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Não há mais espaço na tela inicial."</string>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 27e23b2..512d96d 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d lățime și %2$d înălțime"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Atingeți lung pentru a plasa manual"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Adăugați automat"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Căutați aplicații"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Se încarcă aplicații…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nu s-a găsit nicio aplicație pentru „<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Căutați mai multe aplicații"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Notificări"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Nu mai este loc pe acest Ecran de pornire."</string>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 0627892..923f357 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина %1$d, высота %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Нажмите и удерживайте, чтобы добавить вручную"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Добавить автоматически"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Поиск приложений"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Загрузка…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"По запросу \"<xliff:g id="QUERY">%1$s</xliff:g>\" ничего не найдено"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Поиск приложений"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Загрузка приложений…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"По запросу \"<xliff:g id="QUERY">%1$s</xliff:g>\" ничего не найдено"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Искать другие приложения"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Уведомления"</string>
     <string name="out_of_space" msgid="4691004494942118364">"На этом экране все занято"</string>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index fcb3bc0..f6c42b2 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"පළල %1$d උස %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"අතින් ස්ථානගත කිරීමට ස්පර්ශ කර අල්ලාගෙන සිටින්න"</string>
     <string name="place_automatically" msgid="8064208734425456485">"ස්වයංක්‍රියව එක් කරන්න"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"යෙදුම් සෙවීම"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"යෙදුම් පූරණය වෙමින්…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"යෙදුම් සොයන්න"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"යෙදුම් පූරණය වෙමින්…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" සමග ගැළපෙන යෙදුම් හමු නොවිණි"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"තව යෙදුම් සඳහා සොයන්න"</string>
     <string name="notifications_header" msgid="1404149926117359025">"දැනුම්දීම්"</string>
     <string name="out_of_space" msgid="4691004494942118364">"මෙම මුල් පිටු තිරය මත තවත් අවසර නැත."</string>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 7df18cb..4dbc407 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"šírka %1$d, výška %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Položku umiestnite ručne klepnutím a podržaním"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Pridať automaticky"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Hľadať aplikácie"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Načítavajú sa aplikácie…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nenašli sa žiadne aplikácie zodpovedajúce dopytu <xliff:g id="QUERY">%1$s</xliff:g>"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Hľadať ďalšie aplikácie"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Upozornenia"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Na tejto ploche už nie je miesto"</string>
@@ -58,7 +58,7 @@
     <string name="gadget_setup_text" msgid="8274003207686040488">"Nastavenie"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Toto je systémová aplikácia a nedá sa odinštalovať."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Nepomenovaný priečinok"</string>
-    <string name="disabled_app_label" msgid="6673129024321402780">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je zakázaná"</string>
+    <string name="disabled_app_label" msgid="6673129024321402780">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> je deaktivovaná"</string>
     <string name="default_scroll_format" msgid="7475544710230993317">"Stránka %1$d z %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Plocha %1$d z %2$d"</string>
     <string name="workspace_new_page" msgid="257366611030256142">"Nová stránka plochy"</string>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 06e761e..0b7d36e 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Širina %1$d, višina %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Dotaknite se elementa in ga pridržite, da ga ročno dodate"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Samodejno dodaj"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Iskanje programov"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Nalaganje aplikacij …"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Ni aplikacij, ki bi ustrezale poizvedbi »<xliff:g id="QUERY">%1$s</xliff:g>«"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Iskanje več aplikacij"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Obvestila"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Na tem začetnem zaslonu ni več prostora."</string>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 4ec5dc1..3e6afee 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d i gjerë me %2$d i lartë"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Prek dhe mbaj të shtypur për të vendosur në mënyrë manuale"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Shto automatikisht"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Kërko për aplikacione"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Po ngarkon aplikacionet..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Nuk u gjet asnjë aplikacion që përputhet me \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Kërko për aplikacione"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Po ngarkon aplikacionet..."</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Nuk u gjet asnjë aplikacion që përputhet me \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Kërko për më shumë aplikacione"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Njoftimet"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Nuk ka më hapësirë në këtë ekran bazë."</string>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index aa907eb..f41e02d 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"ширина од %1$d и висина од %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Додирните и задржите да бисте поставили ручно"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Аутоматски додај"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Претражите апликације"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Апликације се учитавају..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Није пронађена ниједна апликација за „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Претражите апликације"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Апликације се учитавају…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Није пронађена ниједна апликација за „<xliff:g id="QUERY">%1$s</xliff:g>“"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Претражи још апликација"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Обавештења"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Нема више простора на овом почетном екрану."</string>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 5eb7914..6c598ff 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d bred gånger %2$d hög"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Placera manuellt genom att trycka länge"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Lägg till automatiskt"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sök efter appar"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Läser in appar …"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Inga appar som matchar <xliff:g id="QUERY">%1$s</xliff:g> hittades"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sök efter fler appar"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Aviseringar"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Det finns inte plats för mer på den här startskärmen."</string>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index a773600..3de28e0 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Upana wa %1$d na kimo cha %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Gusa na ushikilie ili uweke mwenyewe"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Ongeza kiotomatiki"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tafuta programu"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Inapakia programu..."</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Haikupata programu zozote zinazolingana na \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tafuta programu zaidi"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Arifa"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Hakuna nafasi katika skrini hii ya Mwanzo."</string>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 156a49e..1d92581 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d அகலத்திற்கு %2$d உயரம்"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"நீங்களே சேர்க்க, தொட்டுப் பிடித்திருக்கவும்"</string>
     <string name="place_automatically" msgid="8064208734425456485">"தானாகவே சேர்"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"பயன்பாடுகளில் தேடுக"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"பயன்பாடுகளை ஏற்றுகிறது..."</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் பயன்பாடுகள் இல்லை"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"பயன்பாடுகளில் தேடுக"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"பயன்பாடுகளை ஏற்றுகிறது…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" உடன் பொருந்தும் பயன்பாடுகள் இல்லை"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"கூடுதல் பயன்பாடுகளைத் தேடு"</string>
     <string name="notifications_header" msgid="1404149926117359025">"அறிவிப்புகள்"</string>
     <string name="out_of_space" msgid="4691004494942118364">"முகப்புத் திரையில் இடமில்லை."</string>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 94e09d8..6c66699 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -22,9 +22,9 @@
     <string name="app_name" msgid="649227358658669779">"Launcher3"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="work_folder_name" msgid="3753320833950115786">"కార్యాలయం"</string>
-    <string name="activity_not_found" msgid="8071924732094499514">"అనువర్తనం ఇన్‌స్టాల్ చేయబడలేదు."</string>
-    <string name="activity_not_available" msgid="7456344436509528827">"అనువర్తనం అందుబాటులో లేదు"</string>
-    <string name="safemode_shortcut_error" msgid="9160126848219158407">"డౌన్‌లోడ్ చేసిన అనువర్తనం సురక్షిత మోడ్‌లో నిలిపివేయబడింది"</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"యాప్ ఇన్‌స్టాల్ చేయబడలేదు."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"యాప్ అందుబాటులో లేదు"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"డౌన్‌లోడ్ చేసిన యాప్ సురక్షిత మోడ్‌లో నిలిపివేయబడింది"</string>
     <string name="safemode_widget_error" msgid="4863470563535682004">"సురక్షిత మోడ్‌లో విడ్జెట్‌లు నిలిపివేయబడ్డాయి"</string>
     <string name="shortcut_not_available" msgid="2536503539825726397">"సత్వరమార్గం అందుబాటులో లేదు"</string>
     <string name="home_screen" msgid="806512411299847073">"హోమ్ స్క్రీన్"</string>
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d వెడల్పు X %2$d ఎత్తు"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"మాన్యువల్‌గా ఉంచడానికి నొక్కి &amp;amp పట్టుకోండి"</string>
     <string name="place_automatically" msgid="8064208734425456485">"స్వయంచాలకంగా జోడించు"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"అనువర్తనాలను శోధించండి"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"అనువర్తనాలను లోడ్ చేస్తోంది…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అనువర్తనాలేవీ కనుగొనబడలేదు"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"అప్లికేషన్‌లను శోధించండి"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"అప్లికేషన్‌లను లోడ్ చేస్తోంది…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"మరిన్ని అనువర్తనాల కోసం శోధించు"</string>
     <string name="notifications_header" msgid="1404149926117359025">"నోటిఫికేషన్‌లు"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ఈ హోమ్ స్క్రీన్‌లో ఖాళీ లేదు."</string>
@@ -56,7 +56,7 @@
     <string name="msg_no_phone_permission" msgid="9208659281529857371">"ఫోన్ కాల్‌లను చేసేందుకు <xliff:g id="APP_NAME">%1$s</xliff:g>కి అనుమతి లేదు"</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"విడ్జెట్‌ను లోడ్ చేయడంలో సమస్య"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"సెటప్ చేయి"</string>
-    <string name="uninstall_system_app_text" msgid="4172046090762920660">"ఇది సిస్టమ్ అనువర్తనం మరియు దీన్ని అన్‌ఇన్‌స్టాల్ చేయడం సాధ్యపడదు."</string>
+    <string name="uninstall_system_app_text" msgid="4172046090762920660">"ఇది సిస్టమ్ యాప్ మరియు దీన్ని అన్‌ఇన్‌స్టాల్ చేయడం సాధ్యపడదు."</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"పేరు లేని ఫోల్డర్"</string>
     <string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> నిలిపివేయబడింది"</string>
     <string name="default_scroll_format" msgid="7475544710230993317">"%2$dలో %1$dవ పేజీ"</string>
@@ -94,8 +94,8 @@
     <string name="package_state_unknown" msgid="7592128424511031410">"తెలియదు"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"తీసివేయి"</string>
     <string name="abandoned_search" msgid="891119232568284442">"శోధించు"</string>
-    <string name="abandoned_promises_title" msgid="7096178467971716750">"ఈ అనువర్తనం ఇన్‌స్టాల్ చేయబడలేదు"</string>
-    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ఈ చిహ్నం యొక్క అనువర్తనం ఇన్‌స్టాల్ చేయబడలేదు. మీరు దీన్ని తీసివేయవచ్చు లేదా ఆ అనువర్తనం కోసం శోధించి దాన్ని మాన్యువల్‌గా ఇన్‌స్టాల్ చేయవచ్చు."</string>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"ఈ యాప్ ఇన్‌స్టాల్ చేయబడలేదు"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"ఈ చిహ్నం యొక్క యాప్ ఇన్‌స్టాల్ చేయబడలేదు. మీరు దీన్ని తీసివేయవచ్చు లేదా ఆ యాప్ కోసం శోధించి దాన్ని మాన్యువల్‌గా ఇన్‌స్టాల్ చేయవచ్చు."</string>
     <string name="app_downloading_title" msgid="8336702962104482644">"<xliff:g id="NAME">%1$s</xliff:g> డౌన్‌లోడ్ అవుతోంది, <xliff:g id="PROGRESS">%2$s</xliff:g> పూర్తయింది"</string>
     <string name="app_waiting_download_title" msgid="7053938513995617849">"<xliff:g id="NAME">%1$s</xliff:g> ఇన్‌స్టాల్ కావడానికి వేచి ఉంది"</string>
     <string name="widgets_bottom_sheet_title" msgid="2904559530954183366">"<xliff:g id="NAME">%1$s</xliff:g> విడ్జెట్‌లు"</string>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 4eb342f..b370099 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"กว้าง %1$d x สูง %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"แตะค้างไว้เพื่อวางด้วยตัวเอง"</string>
     <string name="place_automatically" msgid="8064208734425456485">"เพิ่มโดยอัตโนมัติ"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ค้นหาแอป"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"กำลังโหลดแอป…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"ไม่พบแอปที่ตรงกับ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ค้นหาแอป"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"กำลังโหลดแอป…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"ไม่พบแอปที่ตรงกับ \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"ค้นหาแอปเพิ่มเติม"</string>
     <string name="notifications_header" msgid="1404149926117359025">"การแจ้งเตือน"</string>
     <string name="out_of_space" msgid="4691004494942118364">"ไม่มีที่ว่างในหน้าจอหลักนี้"</string>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 0a26793..54135c9 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ang lapad at %2$d ang taas"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Pindutin nang matagal upang manual na ilagay"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Awtomatikong idagdag"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Maghanap ng mga app"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Naglo-load ng mga app…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Walang nahanap na app na tumutugma sa \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Maghanap ng higit pang mga app"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Mga Notification"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Wala nang lugar sa Home screen na ito."</string>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 1b6a2a0..cb8b50a 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"genişlik: %1$d, yükseklik: %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Manuel olarak yerleştirmek için dokunun ve basılı tutun"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Otomatik olarak ekle"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Uygulamalarda ara"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Uygulamalar yükleniyor…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" ile eşleşen uygulama bulunamadı"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Başka uygulamalar ara"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Bildirimler"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Bu Ana ekranda yer kalmadı."</string>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 52224f3..a9e0109 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Ширина – %1$d, висота – %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Натисніть і утримуйте, щоб додати вручну"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Додати автоматично"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Пошук додатків"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Завантаження додатків…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"Немає додатків для запиту \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Пошук додатків"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Завантаження додатків…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Немає додатків для запиту \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Шукати ще додатки"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Сповіщення"</string>
     <string name="out_of_space" msgid="4691004494942118364">"На цьому головному екрані більше немає місця."</string>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index f3d6d3f..a704fab 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"‏%1$d چوڑا اور ‎%2$d اونچا"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"‏دستی طور پر رکھنے کیلئے ‎&amp; ٹچ کرکے ہولڈ کریں"</string>
     <string name="place_automatically" msgid="8064208734425456485">"خود کار طور پر شامل کریں"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"ایپس تلاش کریں"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"ایپس لوڈ ہو رہی ہیں…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" سے مماثل کوئی ایپس نہیں ملیں"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"ایپس تلاش کریں"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"ایپس لوڈ کی جا رہی ہیں…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"\"<xliff:g id="QUERY">%1$s</xliff:g>\" سے مماثل کوئی ایپس نہیں ملیں"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"مزید ایپس تلاش کریں"</string>
     <string name="notifications_header" msgid="1404149926117359025">"اطلاعات"</string>
     <string name="out_of_space" msgid="4691004494942118364">"اس ہوم اسکرین پر مزید کوئی گنجائش نہیں ہے۔"</string>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index aa28856..7e31889 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Eni %1$d, bo‘yi %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Qo‘lda joylashtirish uchun bosib turing"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Avtomatik chiqarish"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"Ilovalar ichidan qidirish"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"Ilovalar yuklanmoqda…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"“<xliff:g id="QUERY">%1$s</xliff:g>” so‘rovi bo‘yicha hech narsa topilmadi"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Ilovalarni qidirish"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Ilovalar yuklanmoqda…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"“<xliff:g id="QUERY">%1$s</xliff:g>” bilan mos hech qanday ilova topilmadi"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Boshqa ilovalarni qidirish"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Bildirishnomalar"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Uy ekranida bitta ham xona yo‘q."</string>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 93f96c3..83e1cea 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"Rộng %1$d x cao %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Chạm và giữ để đặt theo cách thủ công"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Tự động thêm"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Tìm kiếm ứng dụng"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Đang tải ứng dụng…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Không tìm thấy ứng dụng nào phù hợp với \"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Tìm kiếm thêm ứng dụng"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Thông báo"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Không còn chỗ trên Màn hình chính này."</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 00f0b16..bef12fb 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"宽 %1$d,高 %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"触摸并按住即可手动放置"</string>
     <string name="place_automatically" msgid="8064208734425456485">"自动添加"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"搜索应用"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"正在加载应用…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"未找到与“<xliff:g id="QUERY">%1$s</xliff:g>”相符的应用"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜索应用"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"正在加载应用…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"未找到与“<xliff:g id="QUERY">%1$s</xliff:g>”相符的应用"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜索更多应用"</string>
     <string name="notifications_header" msgid="1404149926117359025">"通知"</string>
     <string name="out_of_space" msgid="4691004494942118364">"此主屏幕上已没有空间。"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index b8ebf8f..7ac5553 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d 闊,%2$d 高"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"按住即可手動新增"</string>
     <string name="place_automatically" msgid="8064208734425456485">"自動新增"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"搜尋應用程式"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"正在載入應用程式…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"無法找到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
     <string name="notifications_header" msgid="1404149926117359025">"通知"</string>
     <string name="out_of_space" msgid="4691004494942118364">"主畫面已無空間。"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 9640fb8..e0c4c99 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"寬度為 %1$d,高度為 %2$d"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"按住即可手動放置"</string>
     <string name="place_automatically" msgid="8064208734425456485">"自動新增"</string>
-    <string name="all_apps_search_bar_hint" msgid="7084713969757597256">"搜尋應用程式"</string>
-    <string name="all_apps_loading_message" msgid="7557140873644765180">"正在載入應用程式…"</string>
-    <string name="all_apps_no_search_results" msgid="6332185285860416787">"找不到符合「<xliff:g id="QUERY">%1$s</xliff:g>」的應用程式"</string>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"搜尋應用程式"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"正在載入應用程式…"</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"找不到與「<xliff:g id="QUERY">%1$s</xliff:g>」相符的應用程式"</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"搜尋更多應用程式"</string>
     <string name="notifications_header" msgid="1404149926117359025">"通知"</string>
     <string name="out_of_space" msgid="4691004494942118364">"這個主螢幕已無空間。"</string>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index f1ea49e..ef6fdeb 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -35,9 +35,9 @@
     <string name="widget_accessible_dims_format" msgid="3640149169885301790">"%1$d ububanzi ngokungu-%2$d ukuya phezulu"</string>
     <string name="add_item_request_drag_hint" msgid="5899764264480397019">"Thinta futhi ubambe ukuze ubeke ngokwenza"</string>
     <string name="place_automatically" msgid="8064208734425456485">"Engeza ngokuzenzakalelayo"</string>
-    <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>
+    <string name="all_apps_search_bar_hint" msgid="1390553134053255246">"Sesha izinhlelo zokusebenza"</string>
+    <string name="all_apps_loading_message" msgid="5813968043155271636">"Ilayisha izinhlelo zokusebenza..."</string>
+    <string name="all_apps_no_search_results" msgid="3200346862396363786">"Azikho izinhlelo zokusebenza ezitholiwe ezifana ne-\"<xliff:g id="QUERY">%1$s</xliff:g>\""</string>
     <string name="all_apps_search_market_message" msgid="1366263386197059176">"Sesha izinhlelo zokusebenza eziningi"</string>
     <string name="notifications_header" msgid="1404149926117359025">"Izaziso"</string>
     <string name="out_of_space" msgid="4691004494942118364">"Asisekho isikhala kulesi sikrini Sasekhaya."</string>
diff --git a/res/values/config.xml b/res/values/config.xml
index e9c62a7..e7ec0a0 100644
--- a/res/values/config.xml
+++ b/res/values/config.xml
@@ -9,6 +9,8 @@
     <bool name="is_large_tablet">false</bool>
     <bool name="allow_rotation">false</bool>
 
+    <integer name="extracted_color_gradient_alpha">191</integer>
+
     <!-- A string pointer to the original app name string. This allows derived projects to
      easily override the app name without providing all translations -->
     <string name="derived_app_name" translatable="false">@string/app_name</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 9929671..1197b1c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -59,11 +59,11 @@
 
     <!-- All Apps -->
     <!-- Search bar text in the apps view. [CHAR_LIMIT=50] -->
-    <string name="all_apps_search_bar_hint">Search Apps</string>
+    <string name="all_apps_search_bar_hint">Search apps</string>
     <!-- Loading apps text. [CHAR_LIMIT=50] -->
-    <string name="all_apps_loading_message">Loading Apps&#8230;</string>
+    <string name="all_apps_loading_message">Loading apps&#8230;</string>
     <!-- No-search-results text. [CHAR_LIMIT=50] -->
-    <string name="all_apps_no_search_results">No Apps found matching \"<xliff:g id="query" example="Android">%1$s</xliff:g>\"</string>
+    <string name="all_apps_no_search_results">No apps found matching \"<xliff:g id="query" example="Android">%1$s</xliff:g>\"</string>
     <!-- Label for the button which allows the user to get app search results. [CHAR_LIMIT=50] -->
     <string name="all_apps_search_market_message">Search for more apps</string>
 
diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
index 6e33d2a..b249c95 100644
--- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
+++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java
@@ -13,6 +13,7 @@
 import android.util.Log;
 
 import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.model.LoaderTask;
 import com.android.launcher3.provider.RestoreDbTask;
 import com.android.launcher3.util.ContentWriter;
@@ -26,7 +27,7 @@
         if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) {
             int hostId = intent.getIntExtra(AppWidgetManager.EXTRA_HOST_ID, 0);
             Log.d(TAG, "Widget ID map received for host:" + hostId);
-            if (hostId != Launcher.APPWIDGET_HOST_ID) {
+            if (hostId != LauncherAppWidgetHost.APPWIDGET_HOST_ID) {
                 return;
             }
 
@@ -38,7 +39,8 @@
                         .postAtFrontOfQueue(new Runnable() {
                             @Override
                             public void run() {
-                                restoreAppWidgetIds(context, asyncResult, oldIds, newIds);
+                                restoreAppWidgetIds(context, oldIds, newIds);
+                                asyncResult.finish();
                             }
                         });
             } else {
@@ -51,9 +53,13 @@
      * Updates the app widgets whose id has changed during the restore process.
      */
     @WorkerThread
-    static void restoreAppWidgetIds(Context context, PendingResult asyncResult,
-            int[] oldWidgetIds, int[] newWidgetIds) {
-        AppWidgetHost appWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID);
+    static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) {
+        AppWidgetHost appWidgetHost = new LauncherAppWidgetHost(context);
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            Log.e(TAG, "Skipping widget ID remap as widgets not supported");
+            appWidgetHost.deleteHost();
+            return;
+        }
         if (!RestoreDbTask.isPending(context)) {
             // Someone has already gone through our DB once, probably LoaderTask. Skip any further
             // modifications of the DB.
@@ -62,7 +68,6 @@
                 Log.d(TAG, "Deleting widgetId: " + widgetId);
                 appWidgetHost.deleteAppWidgetId(widgetId);
             }
-            asyncResult.finish();
             return;
         }
         final ContentResolver cr = context.getContentResolver();
@@ -106,6 +111,5 @@
         if (app != null) {
             app.getModel().forceReload();
         }
-        asyncResult.finish();
     }
 }
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 2b59ede..e496495 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.ContextWrapper;
+import android.content.Intent;
 import android.view.View.AccessibilityDelegate;
 
 import com.android.launcher3.logging.UserEventDispatcher;
@@ -63,4 +64,9 @@
         }
         return mSystemUiController;
     }
+
+    @Override
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        super.onActivityResult(requestCode, resultCode, data);
+    }
 }
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index aac8005..3ebccda 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -780,7 +780,7 @@
         return mCellWidth;
     }
 
-    int getCellHeight() {
+    public int getCellHeight() {
         return mCellHeight;
     }
 
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 60c19bc..150bc53 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -365,7 +365,7 @@
         if (isVerticalBarLayout()) {
             hotseatBarSizePx = iconSizePx;
         }
-        hotseatCellHeightPx = iconSizePx + iconDrawablePaddingPx;
+        hotseatCellHeightPx = iconSizePx;
 
         if (!isVerticalBarLayout()) {
             int expectedWorkspaceHeight = availableHeightPx - hotseatBarSizePx
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 3ae4316..615ec47 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -144,6 +144,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.concurrent.Executor;
 
 /**
  * Default launcher application.
@@ -209,10 +210,8 @@
 
     private boolean mIsSafeModeEnabled;
 
-    public static final int APPWIDGET_HOST_ID = 1024;
     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 500;
     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
-    private static final int ACTIVITY_START_DELAY = 1000;
 
     // How long to wait before the new-shortcut animation automatically pans the workspace
     private static final int NEW_APPS_PAGE_MOVE_DELAY = 500;
@@ -397,7 +396,10 @@
 
         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
 
-        mAppWidgetHost = new LauncherAppWidgetHost(this, APPWIDGET_HOST_ID);
+        mAppWidgetHost = new LauncherAppWidgetHost(this);
+        if (Utilities.ATLEAST_MARSHMALLOW) {
+            mAppWidgetHost.addProviderChangeListener(this);
+        }
         mAppWidgetHost.startListening();
 
         // If we are getting an onCreate, we can actually preempt onResume and unset mPaused here,
@@ -789,7 +791,7 @@
     }
 
     @Override
-    protected void onActivityResult(
+    public void onActivityResult(
             final int requestCode, final int resultCode, final Intent data) {
         handleActivityResult(requestCode, resultCode, data);
         if (mLauncherCallbacks != null) {
@@ -1468,23 +1470,25 @@
             mWorkspace.addInScreen(view, info);
         } else {
             // Adding a shortcut to a Folder.
-            final long folderIconId = container;
-            FolderIcon folderIcon = (FolderIcon) mWorkspace.getFirstMatch(new ItemOperator() {
-                @Override
-                public boolean evaluate(ItemInfo info, View view) {
-                    return info != null && info.id == folderIconId;
-                }
-            });
-
+            FolderIcon folderIcon = findFolderIcon(container);
             if (folderIcon != null) {
                 FolderInfo folderInfo = (FolderInfo) folderIcon.getTag();
                 folderInfo.add(info, args.rank, false);
             } else {
-                Log.e(TAG, "Could not find folder with id " + folderIconId + " to add shortcut.");
+                Log.e(TAG, "Could not find folder with id " + container + " to add shortcut.");
             }
         }
     }
 
+    public FolderIcon findFolderIcon(final long folderIconId) {
+        return (FolderIcon) mWorkspace.getFirstMatch(new ItemOperator() {
+            @Override
+            public boolean evaluate(ItemInfo info, View view) {
+                return info != null && info.id == folderIconId;
+            }
+        });
+    }
+
     /**
      * Add a widget to the workspace.
      *
@@ -1852,6 +1856,8 @@
 
         LauncherAnimUtils.onDestroyActivity();
 
+        clearPendingBinds();
+
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onDestroy();
         }
@@ -3702,6 +3708,13 @@
         }
 
         if (mAppsView != null) {
+            Executor pendingExecutor = getPendingExecutor();
+            if (pendingExecutor != null && mState != State.APPS) {
+                // Wait until the fade in animation has finished before setting all apps list.
+                mTmpAppsList = apps;
+                pendingExecutor.execute(mBindAllApplicationsRunnable);
+                return;
+            }
             mAppsView.setApps(apps);
         }
         if (mLauncherCallbacks != null) {
@@ -3710,6 +3723,14 @@
     }
 
     /**
+     * Returns an Executor that will run after the launcher is first drawn (including after the
+     * initial fade in animation). Returns null if the first draw has already occurred.
+     */
+    public @Nullable Executor getPendingExecutor() {
+        return mPendingExecutor != null && mPendingExecutor.canQueue() ? mPendingExecutor : null;
+    }
+
+    /**
      * Copies LauncherModel's map of activities to shortcut ids to Launcher's. This is necessary
      * because LauncherModel's map is updated in the background, while Launcher runs on the UI.
      */
@@ -3901,6 +3922,12 @@
         }
 
         if (mWidgetsView != null && allWidgets != null) {
+            Executor pendingExecutor = getPendingExecutor();
+            if (pendingExecutor != null && mState != State.WIDGETS) {
+                mAllWidgets = allWidgets;
+                pendingExecutor.execute(mBindAllWidgetsRunnable);
+                return;
+            }
             mWidgetsView.setWidgets(allWidgets);
             mAllWidgets = null;
         }
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index cf20feb..1ffe41b 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import android.content.ComponentName;
 import android.content.ContentProviderClient;
 import android.content.Context;
 import android.content.Intent;
@@ -28,13 +29,17 @@
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.dynamicui.ExtractionUtils;
+import com.android.launcher3.notification.NotificationListener;
 import com.android.launcher3.util.ConfigMonitor;
 import com.android.launcher3.util.Preconditions;
+import com.android.launcher3.util.SettingsObserver;
 import com.android.launcher3.util.TestingUtils;
 
 import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 
+import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;
+
 public class LauncherAppState {
 
     public static final boolean PROFILE_STARTUP = FeatureFlags.IS_DOGFOOD_BUILD;
@@ -47,7 +52,7 @@
     private final IconCache mIconCache;
     private final WidgetPreviewLoader mWidgetCache;
     private final InvariantDeviceProfile mInvariantDeviceProfile;
-
+    private final SettingsObserver mNotificationBadgingObserver;
 
     public static LauncherAppState getInstance(final Context context) {
         if (INSTANCE == null) {
@@ -117,6 +122,23 @@
         new ConfigMonitor(mContext).register();
 
         ExtractionUtils.startColorExtractionServiceIfNecessary(mContext);
+
+        if (!mContext.getResources().getBoolean(R.bool.notification_badging_enabled)) {
+            mNotificationBadgingObserver = null;
+        } else {
+            // Register an observer to rebind the notification listener when badging is re-enabled.
+            mNotificationBadgingObserver = new SettingsObserver.Secure(
+                    mContext.getContentResolver()) {
+                @Override
+                public void onSettingChanged(boolean isNotificationBadgingEnabled) {
+                    if (isNotificationBadgingEnabled) {
+                        NotificationListener.requestRebind(new ComponentName(
+                                mContext, NotificationListener.class));
+                    }
+                }
+            };
+            mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
+        }
     }
 
     /**
@@ -127,6 +149,9 @@
         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(mContext);
         launcherApps.removeOnAppsChangedCallback(mModel);
         PackageInstallerCompat.getInstance(mContext).onStop();
+        if (mNotificationBadgingObserver != null) {
+            mNotificationBadgingObserver.unregister();
+        }
     }
 
     LauncherModel setLauncher(Launcher launcher) {
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index 6e8c59b..5573c5c 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -16,12 +16,20 @@
 
 package com.android.launcher3;
 
+import android.app.Activity;
 import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
+import android.content.ActivityNotFoundException;
 import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
 import android.util.SparseArray;
 import android.view.LayoutInflater;
+import android.widget.Toast;
+
+import com.android.launcher3.config.FeatureFlags;
 
 import java.util.ArrayList;
 
@@ -33,14 +41,16 @@
  */
 public class LauncherAppWidgetHost extends AppWidgetHost {
 
-    private final ArrayList<Runnable> mProviderChangeListeners = new ArrayList<Runnable>();
+    public static final int APPWIDGET_HOST_ID = 1024;
+
+    private final ArrayList<ProviderChangedListener> mProviderChangeListeners = new ArrayList<>();
     private final SparseArray<LauncherAppWidgetHostView> mViews = new SparseArray<>();
 
-    private Launcher mLauncher;
+    private final Context mContext;
 
-    public LauncherAppWidgetHost(Launcher launcher, int hostId) {
-        super(launcher, hostId);
-        mLauncher = launcher;
+    public LauncherAppWidgetHost(Context context) {
+        super(context, APPWIDGET_HOST_ID);
+        mContext = context;
     }
 
     @Override
@@ -53,6 +63,10 @@
 
     @Override
     public void startListening() {
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            return;
+        }
+
         try {
             super.startListening();
         } catch (Exception e) {
@@ -66,24 +80,38 @@
         }
     }
 
-    public void addProviderChangeListener(Runnable callback) {
+    @Override
+    public void stopListening() {
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            return;
+        }
+
+        super.stopListening();
+    }
+
+    @Override
+    public int allocateAppWidgetId() {
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            return AppWidgetManager.INVALID_APPWIDGET_ID;
+        }
+
+        return super.allocateAppWidgetId();
+    }
+
+    public void addProviderChangeListener(ProviderChangedListener callback) {
         mProviderChangeListeners.add(callback);
     }
 
-    public void removeProviderChangeListener(Runnable callback) {
+    public void removeProviderChangeListener(ProviderChangedListener callback) {
         mProviderChangeListeners.remove(callback);
     }
 
     protected void onProvidersChanged() {
         if (!mProviderChangeListeners.isEmpty()) {
-            for (Runnable callback : new ArrayList<>(mProviderChangeListeners)) {
-                callback.run();
+            for (ProviderChangedListener callback : new ArrayList<>(mProviderChangeListeners)) {
+                callback.notifyWidgetProvidersChanged();
             }
         }
-
-        if (Utilities.ATLEAST_MARSHMALLOW) {
-            mLauncher.notifyWidgetProvidersChanged();
-        }
     }
 
     public AppWidgetHostView createView(Context context, int appWidgetId,
@@ -109,7 +137,7 @@
                 // will update.
                 LauncherAppWidgetHostView view = mViews.get(appWidgetId);
                 if (view == null) {
-                    view = onCreateView(mLauncher, appWidgetId, appWidget);
+                    view = onCreateView(mContext, appWidgetId, appWidget);
                 }
                 view.setAppWidget(appWidgetId, appWidget);
                 view.switchToErrorView();
@@ -124,11 +152,11 @@
     @Override
     protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) {
         LauncherAppWidgetProviderInfo info = LauncherAppWidgetProviderInfo.fromProviderInfo(
-                mLauncher, appWidget);
+                mContext, appWidget);
         super.onProviderChanged(appWidgetId, info);
         // The super method updates the dimensions of the providerInfo. Update the
         // launcher spans accordingly.
-        info.initSpans(mLauncher);
+        info.initSpans(mContext);
     }
 
     @Override
@@ -142,4 +170,53 @@
         super.clearViews();
         mViews.clear();
     }
+
+    public void startBindFlow(BaseActivity activity,
+            int appWidgetId, AppWidgetProviderInfo info, int requestCode) {
+
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            sendActionCancelled(activity, requestCode);
+            return;
+        }
+
+        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND)
+                .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
+                .putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.provider)
+                .putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, info.getProfile());
+        // TODO: we need to make sure that this accounts for the options bundle.
+        // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
+        activity.startActivityForResult(intent, requestCode);
+    }
+
+
+    public void startConfigActivity(BaseActivity activity, int widgetId, int requestCode) {
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            sendActionCancelled(activity, requestCode);
+            return;
+        }
+
+        try {
+            startAppWidgetConfigureActivityForResult(activity, widgetId, 0, requestCode, null);
+        } catch (ActivityNotFoundException | SecurityException e) {
+            Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
+            sendActionCancelled(activity, requestCode);
+        }
+    }
+
+    private void sendActionCancelled(final BaseActivity activity, final int requestCode) {
+        new Handler().post(new Runnable() {
+            @Override
+            public void run() {
+                activity.onActivityResult(requestCode, Activity.RESULT_CANCELED, null);
+            }
+        });
+    }
+
+    /**
+     * Listener for getting notifications on provider changes.
+     */
+    public interface ProviderChangedListener {
+
+        void notifyWidgetProvidersChanged();
+    }
 }
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 82bee0e..1007748 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -133,7 +133,7 @@
         }
     };
 
-    public interface Callbacks {
+    public interface Callbacks extends LauncherAppWidgetHost.ProviderChangedListener {
         public boolean setLoadOnResume();
         public int getCurrentWorkspaceScreen();
         public void clearPendingBinds();
@@ -159,7 +159,6 @@
                 HashSet<String> packageNames, HashSet<ComponentName> components,
                 UserHandle user);
         public void bindAppInfosRemoved(ArrayList<AppInfo> appInfos);
-        public void notifyWidgetProvidersChanged();
         public void bindAllWidgets(MultiHashMap<PackageItemInfo, WidgetItem> widgets);
         public void onPageBoundSynchronously(int page);
         public void executeOnNextDraw(ViewOnDrawExecutor executor);
@@ -690,4 +689,8 @@
     public static Looper getWorkerLooper() {
         return sWorkerThread.getLooper();
     }
+
+    public static void setWorkerPriority(final int priority) {
+        Process.setThreadPriority(sWorkerThread.getThreadId(), priority);
+    }
 }
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 4813571..dc83f36 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -1031,7 +1031,7 @@
         }
 
         public AppWidgetHost newLauncherWidgetHost() {
-            return new AppWidgetHost(mContext, Launcher.APPWIDGET_HOST_ID);
+            return new LauncherAppWidgetHost(mContext);
         }
 
         @Override
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 185c887..87f3dda 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -48,6 +48,7 @@
 
 import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.pageindicators.PageIndicator;
+import com.android.launcher3.touch.OverScroll;
 import com.android.launcher3.util.Themes;
 import com.android.launcher3.util.Thunk;
 
@@ -68,10 +69,8 @@
     public static final int PAGE_SNAP_ANIMATION_DURATION = 750;
     protected static final int SLOW_PAGE_SNAP_ANIMATION_DURATION = 950;
 
-    // Overscroll constants
+    // OverScroll constants
     private final static int OVERSCROLL_PAGE_SNAP_ANIMATION_DURATION = 270;
-    private static final float OVERSCROLL_ACCELERATE_FACTOR = 2;
-    private static final float OVERSCROLL_DAMP_FACTOR = 0.07f;
 
     private static final float RETURN_TO_ORIGINAL_PAGE_THRESHOLD = 0.33f;
     // The page is moved more than halfway, automatically move to the next page on touch up.
@@ -188,7 +187,6 @@
     // Convenience/caching
     private static final Matrix sTmpInvMatrix = new Matrix();
     private static final float[] sTmpPoint = new float[2];
-    private static final int[] sTmpIntPoint = new int[2];
     private static final Rect sTmpRect = new Rect();
 
     protected final Rect mInsets = new Rect();
@@ -233,8 +231,6 @@
         mMinSnapVelocity = (int) (MIN_SNAP_VELOCITY * density);
         setOnHierarchyChangeListener(this);
         setWillNotDraw(false);
-
-        int edgeEffectColor = Themes.getAttrColor(getContext(), android.R.attr.colorEdgeEffect);
     }
 
     protected void setDefaultInterpolator(Interpolator interpolator) {
@@ -1305,29 +1301,6 @@
         }
     }
 
-    // This curve determines how the effect of scrolling over the limits of the page dimishes
-    // as the user pulls further and further from the bounds
-    private float overScrollInfluenceCurve(float f) {
-        f -= 1.0f;
-        return f * f * f + 1.0f;
-    }
-
-    protected float acceleratedOverFactor(float amount) {
-        int screenSize = getViewportWidth();
-
-        // We want to reach the max over scroll effect when the user has
-        // over scrolled half the size of the screen
-        float f = OVERSCROLL_ACCELERATE_FACTOR * (amount / screenSize);
-
-        if (Float.compare(f, 0f) == 0) return 0;
-
-        // Clamp this factor, f, to -1 < f < 1
-        if (Math.abs(f) >= 1) {
-            f /= Math.abs(f);
-        }
-        return f;
-    }
-
     // While layout transitions are occurring, a child's position may stray from its baseline
     // position. This method returns the magnitude of this stray at any given time.
     public int getLayoutTransitionOffsetForPage(int index) {
@@ -1348,20 +1321,9 @@
     }
 
     protected void dampedOverScroll(float amount) {
-        int screenSize = getViewportWidth();
+        if (Float.compare(amount, 0f) == 0) return;
 
-        float f = (amount / screenSize);
-
-        if (Float.compare(f, 0f) == 0) return;
-
-        f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
-
-        // Clamp this factor, f, to -1 < f < 1
-        if (Math.abs(f) >= 1) {
-            f /= Math.abs(f);
-        }
-
-        int overScrollAmount = (int) Math.round(OVERSCROLL_DAMP_FACTOR * f * screenSize);
+        int overScrollAmount = OverScroll.dampedScroll(amount, getViewportWidth());
         if (amount < 0) {
             mOverScrollX = overScrollAmount;
             super.scrollTo(mOverScrollX, getScrollY());
@@ -1376,14 +1338,6 @@
         dampedOverScroll(amount);
     }
 
-    protected float maxOverScroll() {
-        // Using the formula in overScroll, assuming that f = 1.0 (which it should generally not
-        // exceed). Used to find out how much extra wallpaper we need for the over scroll effect
-        float f = 1.0f;
-        f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
-        return OVERSCROLL_DAMP_FACTOR * f;
-    }
-
     /**
      * return true if freescroll has been enabled, false otherwise
      */
diff --git a/src/com/android/launcher3/SettingsActivity.java b/src/com/android/launcher3/SettingsActivity.java
index fa7769e..9046372 100644
--- a/src/com/android/launcher3/SettingsActivity.java
+++ b/src/com/android/launcher3/SettingsActivity.java
@@ -26,17 +26,15 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
-import android.database.ContentObserver;
 import android.os.Bundle;
-import android.os.Handler;
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceFragment;
 import android.provider.Settings;
-import android.provider.Settings.System;
 
 import com.android.launcher3.graphics.IconShapeOverride;
 import com.android.launcher3.notification.NotificationListener;
+import com.android.launcher3.util.SettingsObserver;
 import com.android.launcher3.views.ButtonPreference;
 
 /**
@@ -45,8 +43,8 @@
 public class SettingsActivity extends Activity {
 
     private static final String ICON_BADGING_PREFERENCE_KEY = "pref_icon_badging";
-    // TODO: use Settings.Secure.NOTIFICATION_BADGING
-    private static final String NOTIFICATION_BADGING = "notification_badging";
+    /** Hidden field Settings.Secure.NOTIFICATION_BADGING */
+    public static final String NOTIFICATION_BADGING = "notification_badging";
     /** Hidden field Settings.Secure.ENABLED_NOTIFICATION_LISTENERS */
     private static final String NOTIFICATION_ENABLED_LISTENERS = "enabled_notification_listeners";
 
@@ -88,12 +86,9 @@
 
                 // Register a content observer to listen for system setting changes while
                 // this UI is active.
-                resolver.registerContentObserver(
-                        Settings.System.getUriFor(System.ACCELEROMETER_ROTATION),
-                        false, mRotationLockObserver);
+                mRotationLockObserver.register(Settings.System.ACCELEROMETER_ROTATION);
 
                 // Initialize the UI once
-                mRotationLockObserver.onChange(true);
                 rotationPref.setDefaultValue(Utilities.getAllowRotationDefaultValue(getActivity()));
             }
 
@@ -107,13 +102,7 @@
                 // Listen to system notification badge settings while this UI is active.
                 mIconBadgingObserver = new IconBadgingObserver(
                         iconBadgingPref, resolver, getFragmentManager());
-                resolver.registerContentObserver(
-                        Settings.Secure.getUriFor(NOTIFICATION_BADGING),
-                        false, mIconBadgingObserver);
-                resolver.registerContentObserver(
-                        Settings.Secure.getUriFor(NOTIFICATION_ENABLED_LISTENERS),
-                        false, mIconBadgingObserver);
-                mIconBadgingObserver.onChange(true);
+                mIconBadgingObserver.register(NOTIFICATION_BADGING, NOTIFICATION_ENABLED_LISTENERS);
             }
 
             Preference iconShapeOverride = findPreference(IconShapeOverride.KEY_PREFERENCE);
@@ -129,11 +118,11 @@
         @Override
         public void onDestroy() {
             if (mRotationLockObserver != null) {
-                getActivity().getContentResolver().unregisterContentObserver(mRotationLockObserver);
+                mRotationLockObserver.unregister();
                 mRotationLockObserver = null;
             }
             if (mIconBadgingObserver != null) {
-                getActivity().getContentResolver().unregisterContentObserver(mIconBadgingObserver);
+                mIconBadgingObserver.unregister();
                 mIconBadgingObserver = null;
             }
             super.onDestroy();
@@ -144,22 +133,18 @@
      * Content observer which listens for system auto-rotate setting changes, and enables/disables
      * the launcher rotation setting accordingly.
      */
-    private static class SystemDisplayRotationLockObserver extends ContentObserver {
+    private static class SystemDisplayRotationLockObserver extends SettingsObserver.System {
 
         private final Preference mRotationPref;
-        private final ContentResolver mResolver;
 
         public SystemDisplayRotationLockObserver(
                 Preference rotationPref, ContentResolver resolver) {
-            super(new Handler());
+            super(resolver);
             mRotationPref = rotationPref;
-            mResolver = resolver;
         }
 
         @Override
-        public void onChange(boolean selfChange) {
-            boolean enabled = Settings.System.getInt(mResolver,
-                    Settings.System.ACCELEROMETER_ROTATION, 1) == 1;
+        public void onSettingChanged(boolean enabled) {
             mRotationPref.setEnabled(enabled);
             mRotationPref.setSummary(enabled
                     ? R.string.allow_rotation_desc : R.string.allow_rotation_blocked_desc);
@@ -170,7 +155,7 @@
      * Content observer which listens for system badging setting changes,
      * and updates the launcher badging setting subtext accordingly.
      */
-    private static class IconBadgingObserver extends ContentObserver
+    private static class IconBadgingObserver extends SettingsObserver.Secure
             implements Preference.OnPreferenceClickListener {
 
         private final ButtonPreference mBadgingPref;
@@ -179,15 +164,14 @@
 
         public IconBadgingObserver(ButtonPreference badgingPref, ContentResolver resolver,
                 FragmentManager fragmentManager) {
-            super(new Handler());
+            super(resolver);
             mBadgingPref = badgingPref;
             mResolver = resolver;
             mFragmentManager = fragmentManager;
         }
 
         @Override
-        public void onChange(boolean selfChange) {
-            boolean enabled = Settings.Secure.getInt(mResolver, NOTIFICATION_BADGING, 1) == 1;
+        public void onSettingChanged(boolean enabled) {
             int summary = enabled ? R.string.icon_badging_desc_on : R.string.icon_badging_desc_off;
 
             boolean serviceEnabled = true;
diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
index fd708c0..a7e68ff 100644
--- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java
+++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java
@@ -101,7 +101,7 @@
         mInvertIfRtl = invert;
     }
 
-    int getCellContentHeight() {
+    public int getCellContentHeight() {
         return Math.min(getMeasuredHeight(),
                 mLauncher.getDeviceProfile().getCellHeight(mContainerType));
     }
diff --git a/src/com/android/launcher3/UninstallDropTarget.java b/src/com/android/launcher3/UninstallDropTarget.java
index 45c14d6..e15cf9f 100644
--- a/src/com/android/launcher3/UninstallDropTarget.java
+++ b/src/com/android/launcher3/UninstallDropTarget.java
@@ -42,7 +42,7 @@
         return supportsDrop(getContext(), info);
     }
 
-    public static boolean supportsDrop(Context context, Object info) {
+    public static boolean supportsDrop(Context context, ItemInfo info) {
         UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
         Bundle restrictions = userManager.getUserRestrictions();
         if (restrictions.getBoolean(UserManager.DISALLOW_APPS_CONTROL, false)
@@ -56,21 +56,13 @@
     /**
      * @return the component name that should be uninstalled or null.
      */
-    private static ComponentName getUninstallTarget(Context context, Object item) {
+    private static ComponentName getUninstallTarget(Context context, ItemInfo item) {
         Intent intent = null;
         UserHandle user = null;
-        if (item instanceof AppInfo) {
-            AppInfo info = (AppInfo) item;
-            intent = info.intent;
-            user = info.user;
-        } else if (item instanceof ShortcutInfo) {
-            ShortcutInfo info = (ShortcutInfo) item;
-            if (info.itemType == LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION) {
-                // Do not use restore/target intent here as we cannot uninstall an app which is
-                // being installed/restored.
-                intent = info.intent;
-                user = info.user;
-            }
+        if (item != null &&
+                item.itemType == LauncherSettings.BaseLauncherColumns.ITEM_TYPE_APPLICATION) {
+            intent = item.getIntent();
+            user = item.user;
         }
         if (intent != null) {
             LauncherActivityInfo info = LauncherAppsCompat.getInstance(context)
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index f781a3d..f8d6498 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -52,8 +52,10 @@
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.Interpolator;
 import android.widget.Toast;
+
 import com.android.launcher3.Launcher.CustomContentCallbacks;
 import com.android.launcher3.Launcher.LauncherOverlay;
+import com.android.launcher3.LauncherAppWidgetHost.ProviderChangedListener;
 import com.android.launcher3.UninstallDropTarget.DropTargetSource;
 import com.android.launcher3.accessibility.AccessibleDragListenerAdapter;
 import com.android.launcher3.accessibility.OverviewAccessibilityDelegate;
@@ -86,6 +88,7 @@
 import com.android.launcher3.util.WallpaperOffsetInterpolator;
 import com.android.launcher3.widget.PendingAddShortcutInfo;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
+
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Set;
@@ -668,7 +671,8 @@
         newScreen.setSoundEffectsEnabled(false);
 
         int paddingLeftRight = mLauncher.getDeviceProfile().cellLayoutPaddingLeftRightPx;
-        newScreen.setPadding(paddingLeftRight, 0, paddingLeftRight, 0);
+        int paddingBottom = mLauncher.getDeviceProfile().cellLayoutBottomPaddingPx;
+        newScreen.setPadding(paddingLeftRight, 0, paddingLeftRight, paddingBottom);
 
         mWorkspaceScreens.put(screenId, newScreen);
         mScreenOrder.add(insertIndex, screenId);
@@ -4079,7 +4083,7 @@
      * Used as a workaround to ensure that the AppWidgetService receives the
      * PACKAGE_ADDED broadcast before updating widgets.
      */
-    private class DeferredWidgetRefresh implements Runnable {
+    private class DeferredWidgetRefresh implements Runnable, ProviderChangedListener {
         private final ArrayList<LauncherAppWidgetInfo> mInfos;
         private final LauncherAppWidgetHost mHost;
         private final Handler mHandler;
@@ -4122,6 +4126,11 @@
                 }
             });
         }
+
+        @Override
+        public void notifyWidgetProvidersChanged() {
+            run();
+        }
     }
 
     private class StateTransitionListener extends AnimatorListenerAdapter
diff --git a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
index 8161219..b7c500f 100644
--- a/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/ShortcutMenuAccessibilityDelegate.java
@@ -50,8 +50,7 @@
         if ((host.getParent() instanceof DeepShortcutView)) {
             info.addAction(mActions.get(ADD_TO_WORKSPACE));
         } else if (host instanceof NotificationMainView) {
-            NotificationMainView notificationView = (NotificationMainView) host;
-            if (notificationView.canChildBeDismissed(notificationView)) {
+            if (((NotificationMainView) host).canChildBeDismissed()) {
                 info.addAction(mActions.get(DISMISS_NOTIFICATION));
             }
         }
@@ -88,8 +87,7 @@
             if (!(host instanceof NotificationMainView)) {
                 return false;
             }
-            NotificationMainView notificationView = (NotificationMainView) host;
-            notificationView.onChildDismissed(notificationView);
+            ((NotificationMainView) host).onChildDismissed();
             announceConfirmation(R.string.notification_dismissed);
             return true;
         }
diff --git a/src/com/android/launcher3/allapps/AllAppsCaretController.java b/src/com/android/launcher3/allapps/AllAppsCaretController.java
index 622322b..583b49f 100644
--- a/src/com/android/launcher3/allapps/AllAppsCaretController.java
+++ b/src/com/android/launcher3/allapps/AllAppsCaretController.java
@@ -22,13 +22,14 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
 import com.android.launcher3.pageindicators.CaretDrawable;
+import com.android.launcher3.touch.SwipeDetector;
 
 public class AllAppsCaretController {
     // Determines when the caret should flip. Should be accessed via getThreshold()
     private static final float CARET_THRESHOLD = 0.015f;
     private static final float CARET_THRESHOLD_LAND = 0.5f;
     // The velocity at which the caret will peak (i.e. exhibit a 90 degree bend)
-    private static final float PEAK_VELOCITY = VerticalPullDetector.RELEASE_VELOCITY_PX_MS * .7f;
+    private static final float PEAK_VELOCITY = SwipeDetector.RELEASE_VELOCITY_PX_MS * .7f;
 
     private Launcher mLauncher;
 
diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
index 657af15..494cd5a 100644
--- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java
@@ -36,6 +36,8 @@
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.graphics.DrawableFactory;
 import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
+import com.android.launcher3.touch.OverScroll;
+import com.android.launcher3.touch.SwipeDetector;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
 
@@ -60,7 +62,7 @@
 
     private SpringAnimationHandler mSpringAnimationHandler;
     private OverScrollHelper mOverScrollHelper;
-    private VerticalPullDetector mPullDetector;
+    private SwipeDetector mPullDetector;
 
     private float mContentTranslationY = 0;
     public static final Property<AllAppsRecyclerView, Float> CONTENT_TRANS_Y =
@@ -97,9 +99,8 @@
                 R.dimen.all_apps_empty_search_bg_top_offset);
 
         mOverScrollHelper = new OverScrollHelper();
-        mPullDetector = new VerticalPullDetector(getContext());
-        mPullDetector.setListener(mOverScrollHelper);
-        mPullDetector.setDetectableScrollConditions(VerticalPullDetector.DIRECTION_BOTH, true);
+        mPullDetector = new SwipeDetector(getContext(), mOverScrollHelper, SwipeDetector.VERTICAL);
+        mPullDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, true);
     }
 
     public void setSpringAnimationHandler(SpringAnimationHandler springAnimationHandler) {
@@ -198,8 +199,6 @@
 
     @Override
     public void onDraw(Canvas c) {
-        c.translate(0, mContentTranslationY);
-
         // Draw the background
         if (mEmptySearchBackground != null && mEmptySearchBackground.getAlpha() > 0) {
             mEmptySearchBackground.draw(c);
@@ -208,6 +207,13 @@
         super.onDraw(c);
     }
 
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        canvas.translate(0, mContentTranslationY);
+        super.dispatchDraw(canvas);
+        canvas.translate(0, -mContentTranslationY);
+    }
+
     public float getContentTranslationY() {
         return mContentTranslationY;
     }
@@ -333,6 +339,22 @@
         mFastScrollHelper.onSetAdapter((AllAppsGridAdapter) adapter);
     }
 
+    @Override
+    protected float getBottomFadingEdgeStrength() {
+        // No bottom fading edge.
+        return 0;
+    }
+
+    @Override
+    protected boolean isPaddingOffsetRequired() {
+        return true;
+    }
+
+    @Override
+    protected int getTopPaddingOffset() {
+        return -getPaddingTop();
+    }
+
     /**
      * Updates the bounds for the scrollbar.
      */
@@ -502,7 +524,7 @@
         }
     }
 
-    private class OverScrollHelper implements VerticalPullDetector.Listener {
+    private class OverScrollHelper implements SwipeDetector.Listener {
 
         private static final float MAX_RELEASE_VELOCITY = 5000; // px / s
         private static final float MAX_OVERSCROLL_PERCENTAGE = 0.07f;
@@ -589,37 +611,7 @@
         }
 
         private float getDampedOverScroll(float y) {
-            return dampedOverScroll(y, getHeight()) * MAX_OVERSCROLL_PERCENTAGE;
-        }
-
-        /**
-         * This curve determines how the effect of scrolling over the limits of the page diminishes
-         * as the user pulls further and further from the bounds
-         *
-         * @param f The percentage of how much the user has overscrolled.
-         * @return A transformed percentage based on the influence curve.
-         */
-        private float overScrollInfluenceCurve(float f) {
-            f -= 1.0f;
-            return f * f * f + 1.0f;
-        }
-
-        /**
-         * @param amount The original amount overscrolled.
-         * @param max The maximum amount that the View can overscroll.
-         * @return The dampened overscroll amount.
-         */
-        private float dampedOverScroll(float amount, float max) {
-            float f = amount / max;
-            if (Float.compare(f, 0) == 0) return 0;
-            f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
-
-            // Clamp this factor, f, to -1 < f < 1
-            if (Math.abs(f) >= 1) {
-                f /= Math.abs(f);
-            }
-
-            return Math.round(f * max);
+            return OverScroll.dampedScroll(y, getHeight());
         }
     }
 }
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index b85321e..edfe0c1 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -25,6 +25,7 @@
 import com.android.launcher3.anim.SpringAnimationHandler;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.graphics.GradientView;
+import com.android.launcher3.touch.SwipeDetector;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.util.SystemUiController;
@@ -41,7 +42,7 @@
  * If release velocity < THRES1, snap according to either top or bottom depending on whether it's
  * closer to top or closer to the page indicator.
  */
-public class AllAppsTransitionController implements TouchController, VerticalPullDetector.Listener,
+public class AllAppsTransitionController implements TouchController, SwipeDetector.Listener,
          SearchUiManager.OnScrollRangeChangeListener {
 
     private static final String TAG = "AllAppsTrans";
@@ -51,8 +52,8 @@
     private final Interpolator mHotseatAccelInterpolator = new AccelerateInterpolator(1.5f);
     private final Interpolator mDecelInterpolator = new DecelerateInterpolator(3f);
     private final Interpolator mFastOutSlowInInterpolator = new FastOutSlowInInterpolator();
-    private final VerticalPullDetector.ScrollInterpolator mScrollInterpolator
-            = new VerticalPullDetector.ScrollInterpolator();
+    private final SwipeDetector.ScrollInterpolator mScrollInterpolator
+            = new SwipeDetector.ScrollInterpolator();
 
     private static final float PARALLAX_COEFFICIENT = .125f;
     private static final int SINGLE_FRAME_MS = 16;
@@ -68,7 +69,7 @@
     private float mStatusBarHeight;
 
     private final Launcher mLauncher;
-    private final VerticalPullDetector mDetector;
+    private final SwipeDetector mDetector;
     private final ArgbEvaluator mEvaluator;
     private final boolean mIsDarkTheme;
 
@@ -104,8 +105,7 @@
 
     public AllAppsTransitionController(Launcher l) {
         mLauncher = l;
-        mDetector = new VerticalPullDetector(l);
-        mDetector.setListener(this);
+        mDetector = new SwipeDetector(l, this, SwipeDetector.VERTICAL);
         mShiftRange = DEFAULT_SHIFT_RANGE;
         mProgress = 1f;
 
@@ -134,17 +134,17 @@
 
                 if (mDetector.isIdleState()) {
                     if (mLauncher.isAllAppsVisible()) {
-                        directionsToDetectScroll |= VerticalPullDetector.DIRECTION_DOWN;
+                        directionsToDetectScroll |= SwipeDetector.DIRECTION_NEGATIVE;
                     } else {
-                        directionsToDetectScroll |= VerticalPullDetector.DIRECTION_UP;
+                        directionsToDetectScroll |= SwipeDetector.DIRECTION_POSITIVE;
                     }
                 } else {
                     if (isInDisallowRecatchBottomZone()) {
-                        directionsToDetectScroll |= VerticalPullDetector.DIRECTION_UP;
+                        directionsToDetectScroll |= SwipeDetector.DIRECTION_POSITIVE;
                     } else if (isInDisallowRecatchTopZone()) {
-                        directionsToDetectScroll |= VerticalPullDetector.DIRECTION_DOWN;
+                        directionsToDetectScroll |= SwipeDetector.DIRECTION_NEGATIVE;
                     } else {
-                        directionsToDetectScroll |= VerticalPullDetector.DIRECTION_BOTH;
+                        directionsToDetectScroll |= SwipeDetector.DIRECTION_BOTH;
                         ignoreSlopWhenSettling = true;
                     }
                 }
@@ -360,7 +360,7 @@
     }
 
     private void calculateDuration(float velocity, float disp) {
-        mAnimationDuration = mDetector.calculateDuration(velocity, disp / mShiftRange);
+        mAnimationDuration = SwipeDetector.calculateDuration(velocity, disp / mShiftRange);
     }
 
     public boolean animateToAllApps(AnimatorSet animationOut, long duration) {
diff --git a/src/com/android/launcher3/allapps/VerticalPullDetector.java b/src/com/android/launcher3/allapps/VerticalPullDetector.java
deleted file mode 100644
index 13c4f63..0000000
--- a/src/com/android/launcher3/allapps/VerticalPullDetector.java
+++ /dev/null
@@ -1,306 +0,0 @@
-package com.android.launcher3.allapps;
-
-import android.content.Context;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.ViewConfiguration;
-import android.view.animation.Interpolator;
-
-/**
- * One dimensional scroll gesture detector for all apps container pull up interaction.
- * Client (e.g., AllAppsTransitionController) of this class can register a listener.
- * <p/>
- * Features that this gesture detector can support.
- */
-public class VerticalPullDetector {
-
-    private static final boolean DBG = false;
-    private static final String TAG = "VerticalPullDetector";
-
-    private final float mTouchSlop;
-
-    private int mScrollConditions;
-    public static final int DIRECTION_UP = 1 << 0;
-    public static final int DIRECTION_DOWN = 1 << 1;
-    public static final int DIRECTION_BOTH = DIRECTION_DOWN | DIRECTION_UP;
-
-    private static final float ANIMATION_DURATION = 1200;
-    private static final float FAST_FLING_PX_MS = 10;
-
-    /**
-     * The minimum release velocity in pixels per millisecond that triggers fling..
-     */
-    public static final float RELEASE_VELOCITY_PX_MS = 1.0f;
-
-    /**
-     * The time constant used to calculate dampening in the low-pass filter of scroll velocity.
-     * Cutoff frequency is set at 10 Hz.
-     */
-    public static final float SCROLL_VELOCITY_DAMPENING_RC = 1000f / (2f * (float) Math.PI * 10);
-
-    /* Scroll state, this is set to true during dragging and animation. */
-    private ScrollState mState = ScrollState.IDLE;
-
-    enum ScrollState {
-        IDLE,
-        DRAGGING,      // onDragStart, onDrag
-        SETTLING       // onDragEnd
-    }
-
-    //------------------- ScrollState transition diagram -----------------------------------
-    //
-    // IDLE ->      (mDisplacement > mTouchSlop) -> DRAGGING
-    // DRAGGING -> (MotionEvent#ACTION_UP, MotionEvent#ACTION_CANCEL) -> SETTLING
-    // SETTLING -> (MotionEvent#ACTION_DOWN) -> DRAGGING
-    // SETTLING -> (View settled) -> IDLE
-
-    private void setState(ScrollState newState) {
-        if (DBG) {
-            Log.d(TAG, "setState:" + mState + "->" + newState);
-        }
-        // onDragStart and onDragEnd is reported ONLY on state transition
-        if (newState == ScrollState.DRAGGING) {
-            initializeDragging();
-            if (mState == ScrollState.IDLE) {
-                reportDragStart(false /* recatch */);
-            } else if (mState == ScrollState.SETTLING) {
-                reportDragStart(true /* recatch */);
-            }
-        }
-        if (newState == ScrollState.SETTLING) {
-            reportDragEnd();
-        }
-
-        mState = newState;
-    }
-
-    public boolean isDraggingOrSettling() {
-        return mState == ScrollState.DRAGGING || mState == ScrollState.SETTLING;
-    }
-
-    /**
-     * There's no touch and there's no animation.
-     */
-    public boolean isIdleState() {
-        return mState == ScrollState.IDLE;
-    }
-
-    public boolean isSettlingState() {
-        return mState == ScrollState.SETTLING;
-    }
-
-    public boolean isDraggingState() {
-        return mState == ScrollState.DRAGGING;
-    }
-
-    private float mDownX;
-    private float mDownY;
-
-    private float mLastY;
-    private long mCurrentMillis;
-
-    private float mVelocity;
-    private float mLastDisplacement;
-    private float mDisplacementY;
-    private float mDisplacementX;
-
-    private float mSubtractDisplacement;
-    private boolean mIgnoreSlopWhenSettling;
-
-    /* Client of this gesture detector can register a callback. */
-    private Listener mListener;
-
-    public void setListener(Listener l) {
-        mListener = l;
-    }
-
-    public interface Listener {
-        void onDragStart(boolean start);
-
-        boolean onDrag(float displacement, float velocity);
-
-        void onDragEnd(float velocity, boolean fling);
-    }
-
-    public VerticalPullDetector(Context context) {
-        mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
-    }
-
-    public void setDetectableScrollConditions(int scrollDirectionFlags, boolean ignoreSlop) {
-        mScrollConditions = scrollDirectionFlags;
-        mIgnoreSlopWhenSettling = ignoreSlop;
-    }
-
-    private boolean shouldScrollStart() {
-        // reject cases where the slop condition is not met.
-        if (Math.abs(mDisplacementY) < mTouchSlop) {
-            return false;
-        }
-
-        // reject cases where the angle condition is not met.
-        float deltaY = Math.abs(mDisplacementY);
-        float deltaX = Math.max(Math.abs(mDisplacementX), 1);
-        if (deltaX > deltaY) {
-            return false;
-        }
-        // Check if the client is interested in scroll in current direction.
-        if (((mScrollConditions & DIRECTION_DOWN) > 0 && mDisplacementY > 0) ||
-                ((mScrollConditions & DIRECTION_UP) > 0 && mDisplacementY < 0)) {
-            return true;
-        }
-        return false;
-    }
-
-    public boolean onTouchEvent(MotionEvent ev) {
-        switch (ev.getAction()) {
-            case MotionEvent.ACTION_DOWN:
-                mDownX = ev.getX();
-                mDownY = ev.getY();
-                mLastDisplacement = 0;
-                mDisplacementY = 0;
-                mVelocity = 0;
-
-                if (mState == ScrollState.SETTLING && mIgnoreSlopWhenSettling) {
-                    setState(ScrollState.DRAGGING);
-                }
-                break;
-            case MotionEvent.ACTION_MOVE:
-                mDisplacementX = ev.getX() - mDownX;
-                mDisplacementY = ev.getY() - mDownY;
-                computeVelocity(ev);
-
-                // handle state and listener calls.
-                if (mState != ScrollState.DRAGGING && shouldScrollStart()) {
-                    setState(ScrollState.DRAGGING);
-                }
-                if (mState == ScrollState.DRAGGING) {
-                    reportDragging();
-                }
-                break;
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-                // These are synthetic events and there is no need to update internal values.
-                if (mState == ScrollState.DRAGGING) {
-                    setState(ScrollState.SETTLING);
-                }
-                break;
-            default:
-                //TODO: add multi finger tracking by tracking active pointer.
-                break;
-        }
-        // Do house keeping.
-        mLastDisplacement = mDisplacementY;
-        mLastY = ev.getY();
-        return true;
-    }
-
-    public void finishedScrolling() {
-        setState(ScrollState.IDLE);
-    }
-
-    private boolean reportDragStart(boolean recatch) {
-        mListener.onDragStart(!recatch);
-        if (DBG) {
-            Log.d(TAG, "onDragStart recatch:" + recatch);
-        }
-        return true;
-    }
-
-    private void initializeDragging() {
-        if (mState == ScrollState.SETTLING && mIgnoreSlopWhenSettling) {
-            mSubtractDisplacement = 0;
-        }
-        if (mDisplacementY > 0) {
-            mSubtractDisplacement = mTouchSlop;
-        } else {
-            mSubtractDisplacement = -mTouchSlop;
-        }
-    }
-
-    private boolean reportDragging() {
-        float delta = mDisplacementY - mLastDisplacement;
-        if (delta != 0) {
-            if (DBG) {
-                Log.d(TAG, String.format("onDrag disp=%.1f, velocity=%.1f",
-                        mDisplacementY, mVelocity));
-            }
-
-            return mListener.onDrag(mDisplacementY - mSubtractDisplacement, mVelocity);
-        }
-        return true;
-    }
-
-    private void reportDragEnd() {
-        if (DBG) {
-            Log.d(TAG, String.format("onScrollEnd disp=%.1f, velocity=%.1f",
-                    mDisplacementY, mVelocity));
-        }
-        mListener.onDragEnd(mVelocity, Math.abs(mVelocity) > RELEASE_VELOCITY_PX_MS);
-
-    }
-
-    /**
-     * Computes the damped velocity using the two motion events and the previous velocity.
-     */
-    private float computeVelocity(MotionEvent to) {
-        return computeVelocity(to.getY() - mLastY, to.getEventTime());
-    }
-
-    public float computeVelocity(float delta, long currentMillis) {
-        long previousMillis = mCurrentMillis;
-        mCurrentMillis = currentMillis;
-
-        float deltaTimeMillis = mCurrentMillis - previousMillis;
-        float velocity = (deltaTimeMillis > 0) ? (delta / deltaTimeMillis) : 0;
-        if (Math.abs(mVelocity) < 0.001f) {
-            mVelocity = velocity;
-        } else {
-            float alpha = computeDampeningFactor(deltaTimeMillis);
-            mVelocity = interpolate(mVelocity, velocity, alpha);
-        }
-        return mVelocity;
-    }
-
-    /**
-     * Returns a time-dependent dampening factor using delta time.
-     */
-    private static float computeDampeningFactor(float deltaTime) {
-        return deltaTime / (SCROLL_VELOCITY_DAMPENING_RC + deltaTime);
-    }
-
-    /**
-     * Returns the linear interpolation between two values
-     */
-    private static float interpolate(float from, float to, float alpha) {
-        return (1.0f - alpha) * from + alpha * to;
-    }
-
-    public long calculateDuration(float velocity, float progressNeeded) {
-        // TODO: make these values constants after tuning.
-        float velocityDivisor = Math.max(2f, Math.abs(0.5f * velocity));
-        float travelDistance = Math.max(0.2f, progressNeeded);
-        long duration = (long) Math.max(100, ANIMATION_DURATION / velocityDivisor * travelDistance);
-        if (DBG) {
-            Log.d(TAG, String.format("calculateDuration=%d, v=%f, d=%f", duration, velocity, progressNeeded));
-        }
-        return duration;
-    }
-
-    public static class ScrollInterpolator implements Interpolator {
-
-        boolean mSteeper;
-
-        public void setVelocityAtZero(float velocity) {
-            mSteeper = velocity > FAST_FLING_PX_MS;
-        }
-
-        public float getInterpolation(float t) {
-            t -= 1.0f;
-            float output = t * t * t;
-            if (mSteeper) {
-                output *= t * t; // Make interpolation initial slope steeper
-            }
-            return output + 1;
-        }
-    }
-}
diff --git a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
index 21eb3fb..26f6ec3 100644
--- a/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
+++ b/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithm.java
@@ -71,10 +71,6 @@
         return result;
     }
 
-    public static boolean matches(AppInfo info, String query) {
-        return matches(info, query, StringMatcher.getInstance());
-    }
-
     public static boolean matches(AppInfo info, String query, StringMatcher matcher) {
         int queryLength = query.length();
 
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
index 3efbbfb..4e00eae 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompat.java
@@ -16,15 +16,12 @@
 
 package com.android.launcher3.compat;
 
-import android.app.Activity;
-import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.Bundle;
 import android.os.UserHandle;
-import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
@@ -76,9 +73,6 @@
     public abstract boolean bindAppWidgetIdIfAllowed(
             int appWidgetId, AppWidgetProviderInfo info, Bundle options);
 
-    public abstract void startConfigActivity(AppWidgetProviderInfo info, int widgetId,
-            Activity activity, AppWidgetHost host, int requestCode);
-
     public abstract LauncherAppWidgetProviderInfo findProvider(
             ComponentName provider, UserHandle user);
 
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
index f239f5c..cb3bd6c 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatVL.java
@@ -16,24 +16,21 @@
 
 package com.android.launcher3.compat;
 
-import android.app.Activity;
-import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetProviderInfo;
-import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.support.annotation.Nullable;
-import android.widget.Toast;
 
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
-import com.android.launcher3.R;
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.ComponentKey;
 import com.android.launcher3.util.PackageUserKey;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -49,6 +46,9 @@
 
     @Override
     public List<AppWidgetProviderInfo> getAllProviders(@Nullable PackageUserKey packageUser) {
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            return Collections.emptyList();
+        }
         if (packageUser == null) {
             ArrayList<AppWidgetProviderInfo> providers = new ArrayList<AppWidgetProviderInfo>();
             for (UserHandle user : mUserManager.getUserProfiles()) {
@@ -71,24 +71,20 @@
     @Override
     public boolean bindAppWidgetIdIfAllowed(int appWidgetId, AppWidgetProviderInfo info,
             Bundle options) {
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            return false;
+        }
         return mAppWidgetManager.bindAppWidgetIdIfAllowed(
                 appWidgetId, info.getProfile(), info.provider, options);
     }
 
     @Override
-    public void startConfigActivity(AppWidgetProviderInfo info, int widgetId, Activity activity,
-            AppWidgetHost host, int requestCode) {
-        try {
-            host.startAppWidgetConfigureActivityForResult(activity, widgetId, 0, requestCode, null);
-        } catch (ActivityNotFoundException | SecurityException e) {
-            Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
-        }
-    }
-
-    @Override
     public LauncherAppWidgetProviderInfo findProvider(ComponentName provider, UserHandle user) {
-        for (AppWidgetProviderInfo info : mAppWidgetManager
-                .getInstalledProvidersForProfile(user)) {
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            return null;
+        }
+        for (AppWidgetProviderInfo info :
+                getAllProviders(new PackageUserKey(provider.getPackageName(), user))) {
             if (info.provider.equals(provider)) {
                 return LauncherAppWidgetProviderInfo.fromProviderInfo(mContext, info);
             }
@@ -99,6 +95,9 @@
     @Override
     public HashMap<ComponentKey, AppWidgetProviderInfo> getAllProvidersMap() {
         HashMap<ComponentKey, AppWidgetProviderInfo> result = new HashMap<>();
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            return result;
+        }
         for (UserHandle user : mUserManager.getUserProfiles()) {
             for (AppWidgetProviderInfo info :
                     mAppWidgetManager.getInstalledProvidersForProfile(user)) {
diff --git a/src/com/android/launcher3/compat/AppWidgetManagerCompatVO.java b/src/com/android/launcher3/compat/AppWidgetManagerCompatVO.java
index 1c48a13..44158ed 100644
--- a/src/com/android/launcher3/compat/AppWidgetManagerCompatVO.java
+++ b/src/com/android/launcher3/compat/AppWidgetManagerCompatVO.java
@@ -20,8 +20,10 @@
 import android.content.Context;
 import android.support.annotation.Nullable;
 
+import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.PackageUserKey;
 
+import java.util.Collections;
 import java.util.List;
 
 class AppWidgetManagerCompatVO extends AppWidgetManagerCompatVL {
@@ -32,6 +34,9 @@
 
     @Override
     public List<AppWidgetProviderInfo> getAllProviders(@Nullable PackageUserKey packageUser) {
+        if (FeatureFlags.GO_DISABLE_WIDGETS) {
+            return Collections.emptyList();
+        }
         if (packageUser == null) {
             return super.getAllProviders(null);
         }
diff --git a/src/com/android/launcher3/config/BaseFlags.java b/src/com/android/launcher3/config/BaseFlags.java
new file mode 100644
index 0000000..7964dd1
--- /dev/null
+++ b/src/com/android/launcher3/config/BaseFlags.java
@@ -0,0 +1,73 @@
+/*
+ * 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.config;
+
+/**
+ * Defines a set of flags used to control various launcher behaviors.
+ *
+ * All the flags should be defined here with appropriate default values. To override a value,
+ * redefine it in {@link FeatureFlags}.
+ *
+ * This class is kept package-private to prevent direct access.
+ */
+abstract class BaseFlags {
+
+    BaseFlags() {}
+
+    public static final boolean IS_DOGFOOD_BUILD = false;
+
+    // Custom flags go below this
+    public static boolean LAUNCHER3_DISABLE_ICON_NORMALIZATION = false;
+    public static boolean LAUNCHER3_LEGACY_FOLDER_ICON = false;
+    public static boolean LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW = false;
+    public static boolean LAUNCHER3_ALL_APPS_PULL_UP = true;
+    public static boolean LAUNCHER3_NEW_FOLDER_ANIMATION = true;
+    // When enabled allows to use any point on the fast scrollbar to start dragging.
+    public static final boolean LAUNCHER3_DIRECT_SCROLL = true;
+    // When enabled while all-apps open, the soft input will be set to adjust resize .
+    public static final boolean LAUNCHER3_UPDATE_SOFT_INPUT_MODE = false;
+    // When enabled the promise icon is visible in all apps while installation an app.
+    public static final boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = false;
+    // When enabled uses the AllAppsRadialGradientAndScrimDrawable for all apps
+    public static final boolean LAUNCHER3_GRADIENT_ALL_APPS = true;
+    // When enabled allows use of physics based motions in the Launcher.
+    public static final boolean LAUNCHER3_PHYSICS = true;
+    // When enabled allows use of spring motions on the icons.
+    public static final boolean LAUNCHER3_SPRING_ICONS = true;
+
+    // Feature flag to enable moving the QSB on the 0th screen of the workspace.
+    public static final boolean QSB_ON_FIRST_SCREEN = true;
+    // When enabled the all-apps icon is not added to the hotseat.
+    public static final boolean NO_ALL_APPS_ICON = true;
+    // When enabled fling down gesture on the first workspace triggers search.
+    public static final boolean PULLDOWN_SEARCH = false;
+    // When enabled the status bar may show dark icons based on the top of the wallpaper.
+    public static final boolean LIGHT_STATUS_BAR = false;
+    // When enabled icons are badged with the number of notifications associated with that app.
+    public static final boolean BADGE_ICONS = true;
+    // When enabled, icons not supporting {@link AdaptiveIconDrawable} will be wrapped in {@link FixedScaleDrawable}.
+    public static final boolean LEGACY_ICON_TREATMENT = true;
+    // When enabled, adaptive icons would have shadows baked when being stored to icon cache.
+    public static final boolean ADAPTIVE_ICON_SHADOW = true;
+    // When enabled, app discovery will be enabled if service is implemented
+    public static final boolean DISCOVERY_ENABLED = false;
+    // When enabled, the qsb will be moved to the hotseat.
+    public static final boolean QSB_IN_HOTSEAT = true;
+
+    // Features to control Launcher3Go behavior
+    public static final boolean GO_DISABLE_WIDGETS = false;
+}
diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java
index 01893bd..c843e72 100644
--- a/src/com/android/launcher3/dragndrop/AddItemActivity.java
+++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java
@@ -16,14 +16,8 @@
 
 package com.android.launcher3.dragndrop;
 
-import static com.android.launcher3.logging.LoggerUtils.newCommandAction;
-import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
-import static com.android.launcher3.logging.LoggerUtils.newItemTarget;
-import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
-
 import android.annotation.TargetApi;
 import android.app.ActivityOptions;
-import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetManager;
 import android.content.ClipData;
 import android.content.ClipDescription;
@@ -45,8 +39,8 @@
 import com.android.launcher3.BaseActivity;
 import com.android.launcher3.InstallShortcutReceiver;
 import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherAppWidgetHost;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
@@ -61,6 +55,11 @@
 import com.android.launcher3.widget.WidgetHostViewLoader;
 import com.android.launcher3.widget.WidgetImageView;
 
+import static com.android.launcher3.logging.LoggerUtils.newCommandAction;
+import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.LoggerUtils.newItemTarget;
+import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
+
 @TargetApi(Build.VERSION_CODES.O)
 public class AddItemActivity extends BaseActivity implements OnLongClickListener, OnTouchListener {
 
@@ -78,7 +77,7 @@
     private LivePreviewWidgetCell mWidgetCell;
 
     // Widget request specific options.
-    private AppWidgetHost mAppWidgetHost;
+    private LauncherAppWidgetHost mAppWidgetHost;
     private AppWidgetManagerCompat mAppWidgetManager;
     private PendingAddWidgetInfo mPendingWidgetInfo;
     private int mPendingBindWidgetId;
@@ -212,7 +211,7 @@
         mWidgetCell.setPreview(PinItemDragListener.getPreview(mRequest));
 
         mAppWidgetManager = AppWidgetManagerCompat.getInstance(this);
-        mAppWidgetHost = new AppWidgetHost(this, Launcher.APPWIDGET_HOST_ID);
+        mAppWidgetHost = new LauncherAppWidgetHost(this);
 
         mPendingWidgetInfo = new PendingAddWidgetInfo(widgetInfo);
         mPendingWidgetInfo.spanX = Math.min(mIdp.numColumns, widgetInfo.spanX);
@@ -256,13 +255,8 @@
         }
 
         // request bind widget
-        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
-        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mPendingBindWidgetId);
-        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER,
-                mPendingWidgetInfo.componentName);
-        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE,
-                mRequest.getAppWidgetProviderInfo(this).getProfile());
-        startActivityForResult(intent, REQUEST_BIND_APPWIDGET);
+        mAppWidgetHost.startBindFlow(this, mPendingBindWidgetId,
+                mRequest.getAppWidgetProviderInfo(this), REQUEST_BIND_APPWIDGET);
     }
 
     private void acceptWidget(int widgetId) {
@@ -280,7 +274,7 @@
     }
 
     @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    public void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (requestCode == REQUEST_BIND_APPWIDGET) {
             int widgetId = data != null
                     ? data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mPendingBindWidgetId)
diff --git a/src/com/android/launcher3/dragndrop/DragView.java b/src/com/android/launcher3/dragndrop/DragView.java
index 09cfc1e..e81e2a3 100644
--- a/src/com/android/launcher3/dragndrop/DragView.java
+++ b/src/com/android/launcher3/dragndrop/DragView.java
@@ -16,23 +16,18 @@
 
 package com.android.launcher3.dragndrop;
 
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.FloatArrayEvaluator;
 import android.animation.ValueAnimator;
 import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.annotation.SuppressLint;
 import android.annotation.TargetApi;
 import android.content.pm.LauncherActivityInfo;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.ColorFilter;
 import android.graphics.ColorMatrix;
 import android.graphics.ColorMatrixColorFilter;
-import android.graphics.Matrix;
 import android.graphics.Paint;
 import android.graphics.Path;
 import android.graphics.Point;
@@ -44,13 +39,11 @@
 import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
-import android.support.animation.DynamicAnimation;
+import android.support.animation.FloatPropertyCompat;
 import android.support.animation.SpringAnimation;
 import android.support.animation.SpringForce;
 import android.view.View;
 import android.view.animation.DecelerateInterpolator;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
 
 import com.android.launcher3.FastBitmapDrawable;
 import com.android.launcher3.ItemInfo;
@@ -76,12 +69,16 @@
 import java.util.Arrays;
 import java.util.List;
 
-public class DragView extends FrameLayout {
+public class DragView extends View {
+    private static final ColorMatrix sTempMatrix1 = new ColorMatrix();
+    private static final ColorMatrix sTempMatrix2 = new ColorMatrix();
+
     public static final int COLOR_CHANGE_DURATION = 120;
     public static final int VIEW_ZOOM_DURATION = 150;
 
     @Thunk static float sDragAlpha = 1f;
 
+    private boolean mDrawBitmap = true;
     private Bitmap mBitmap;
     private Bitmap mCrossFadeBitmap;
     @Thunk Paint mPaint;
@@ -114,16 +111,11 @@
     private int mAnimatedShiftY;
 
     // Below variable only needed IF FeatureFlags.LAUNCHER3_SPRING_ICONS is {@code true}
-    private SpringAnimation mSpringX, mSpringY;
-    private ImageView mFgImageView, mBgImageView;
+    private Drawable mBgSpringDrawable, mFgSpringDrawable;
+    private SpringFloatValue mTranslateX, mTranslateY;
     private Path mScaledMaskPath;
     private Drawable mBadge;
-
-    // Following three values are fine tuned with motion ux designer
-    private final static int STIFFNESS = 4000;
-    private final static float DAMPENING_RATIO = 1f;
-    private final static int PARALLAX_MAX_IN_DP = 8;
-    private final int mDelta;
+    private ColorMatrixColorFilter mBaseFilter;
 
     /**
      * Construct the drag view.
@@ -193,12 +185,11 @@
 
         mBlurSizeOutline = getResources().getDimensionPixelSize(R.dimen.blur_size_medium_outline);
         setElevation(getResources().getDimension(R.dimen.drag_elevation));
-        setWillNotDraw(false);
-        mDelta = (int)(getResources().getDisplayMetrics().density * PARALLAX_MAX_IN_DP);
     }
 
     /**
-     * Initialize {@code #mIconDrawable} only if the icon type is app icon (not shortcut or folder).
+     * Initialize {@code #mIconDrawable} if the item can be represented using
+     * an {@link AdaptiveIconDrawable} or {@link FolderAdaptiveIcon}.
      */
     @TargetApi(Build.VERSION_CODES.O)
     public void setItemInfo(final ItemInfo info) {
@@ -206,7 +197,8 @@
             return;
         }
         if (info.itemType != LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
-                info.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
+                info.itemType != LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT &&
+                info.itemType != LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
             return;
         }
         // Load the adaptive icon on a background thread and add the view in ui thread.
@@ -216,51 +208,106 @@
             public void run() {
                 LauncherAppState appState = LauncherAppState.getInstance(mLauncher);
                 Object[] outObj = new Object[1];
-                Drawable dr = getFullDrawable(info, appState, outObj);
+                final Drawable dr = getFullDrawable(info, appState, outObj);
 
                 if (dr instanceof AdaptiveIconDrawable) {
                     int w = mBitmap.getWidth();
                     int h = mBitmap.getHeight();
-                    AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr;
-                    float blurSizeOutline = mLauncher.getResources()
-                            .getDimension(R.dimen.blur_size_medium_outline);
-                    float normalizationScale = IconNormalizer.getInstance(mLauncher)
-                            .getScale(adaptiveIcon, null, null, null) * ((w - blurSizeOutline) / w);
-                    adaptiveIcon.setBounds(0, 0, w, h);
+                    int blurMargin = (int) mLauncher.getResources()
+                            .getDimension(R.dimen.blur_size_medium_outline) / 2;
 
-                    final Path mask = getMaskPath(adaptiveIcon, normalizationScale);
-                    mFgImageView = setupImageView(adaptiveIcon.getForeground(), normalizationScale);
-                    mBgImageView = setupImageView(adaptiveIcon.getBackground(), normalizationScale);
-                    mSpringX = setupSpringAnimation(-w/4, w/4, DynamicAnimation.TRANSLATION_X);
-                    mSpringY = setupSpringAnimation(-h/4, h/4, DynamicAnimation.TRANSLATION_Y);
-
+                    Rect bounds = new Rect(0, 0, w, h);
+                    bounds.inset(blurMargin, blurMargin);
+                    // Badge is applied after icon normalization so the bounds for badge should not
+                    // be scaled down due to icon normalization.
+                    Rect badgeBounds = new Rect(bounds);
                     mBadge = getBadge(info, appState, outObj[0]);
-                    int blurMargin = (int) blurSizeOutline / 2;
-                    mBadge.setBounds(blurMargin, blurMargin, w - blurMargin, h - blurMargin);
+                    mBadge.setBounds(badgeBounds);
+
+                    Utilities.scaleRectAboutCenter(bounds,
+                            IconNormalizer.getInstance(mLauncher).getScale(dr, null, null, null));
+                    AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) dr;
+
+                    // Shrink very tiny bit so that the clip path is smaller than the original bitmap
+                    // that has anti aliased edges and shadows.
+                    Rect shrunkBounds = new Rect(bounds);
+                    Utilities.scaleRectAboutCenter(shrunkBounds, 0.98f);
+                    adaptiveIcon.setBounds(shrunkBounds);
+                    final Path mask = adaptiveIcon.getIconMask();
+
+                    mTranslateX = new SpringFloatValue(DragView.this,
+                            w * AdaptiveIconDrawable.getExtraInsetFraction());
+                    mTranslateY = new SpringFloatValue(DragView.this,
+                            h * AdaptiveIconDrawable.getExtraInsetFraction());
+
+                    bounds.inset(
+                            (int) (-bounds.width() * AdaptiveIconDrawable.getExtraInsetFraction()),
+                            (int) (-bounds.height() * AdaptiveIconDrawable.getExtraInsetFraction())
+                    );
+                    mBgSpringDrawable = adaptiveIcon.getBackground();
+                    if (mBgSpringDrawable == null) {
+                        mBgSpringDrawable = new ColorDrawable(Color.TRANSPARENT);
+                    }
+                    mBgSpringDrawable.setBounds(bounds);
+                    mFgSpringDrawable = adaptiveIcon.getForeground();
+                    if (mFgSpringDrawable == null) {
+                        mFgSpringDrawable = new ColorDrawable(Color.TRANSPARENT);
+                    }
+                    mFgSpringDrawable.setBounds(bounds);
 
                     new Handler(Looper.getMainLooper()).post(new Runnable() {
                         @Override
                         public void run() {
                             // Assign the variable on the UI thread to avoid race conditions.
                             mScaledMaskPath = mask;
-                            addView(mBgImageView);
-                            addView(mFgImageView);
-                            setWillNotDraw(true);
+
+                            // Do not draw the background in case of folder as its translucent
+                            mDrawBitmap = !(dr instanceof FolderAdaptiveIcon);
 
                             if (info.isDisabled()) {
                                 FastBitmapDrawable d = new FastBitmapDrawable(null);
                                 d.setIsDisabled(true);
-                                ColorFilter cf = d.getColorFilter();
-                                mBgImageView.setColorFilter(cf);
-                                mFgImageView.setColorFilter(cf);
-                                mBadge.setColorFilter(cf);
+                                mBaseFilter = (ColorMatrixColorFilter) d.getColorFilter();
                             }
+                            updateColorFilter();
                         }
                     });
                 }
             }});
     }
 
+    @TargetApi(Build.VERSION_CODES.O)
+    private void updateColorFilter() {
+        if (mCurrentFilter == null) {
+            mPaint.setColorFilter(null);
+
+            if (mScaledMaskPath != null) {
+                mBgSpringDrawable.setColorFilter(mBaseFilter);
+                mBgSpringDrawable.setColorFilter(mBaseFilter);
+                mBadge.setColorFilter(mBaseFilter);
+            }
+        } else {
+            ColorMatrixColorFilter currentFilter = new ColorMatrixColorFilter(mCurrentFilter);
+            mPaint.setColorFilter(currentFilter);
+
+            if (mScaledMaskPath != null) {
+                if (mBaseFilter != null) {
+                    mBaseFilter.getColorMatrix(sTempMatrix1);
+                    sTempMatrix2.set(mCurrentFilter);
+                    sTempMatrix1.postConcat(sTempMatrix2);
+
+                    currentFilter = new ColorMatrixColorFilter(sTempMatrix1);
+                }
+
+                mBgSpringDrawable.setColorFilter(currentFilter);
+                mFgSpringDrawable.setColorFilter(currentFilter);
+                mBadge.setColorFilter(currentFilter);
+            }
+        }
+
+        invalidate();
+    }
+
     /**
      * Returns the full drawable for {@param info}.
      * @param outObj this is set to the internal data associated with {@param info},
@@ -291,6 +338,14 @@
                 return sm.getShortcutIconDrawable(si.get(0),
                         appState.getInvariantDeviceProfile().fillResIconDpi);
             }
+        } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
+            FolderAdaptiveIcon icon =  FolderAdaptiveIcon.createFolderAdaptiveIcon(
+                    mLauncher, info.id, new Point(mBitmap.getWidth(), mBitmap.getHeight()));
+            if (icon == null) {
+                return null;
+            }
+            outObj[0] = icon;
+            return icon;
         } else {
             return null;
         }
@@ -318,84 +373,17 @@
             float insetFraction = (iconSize - badgeSize) / iconSize;
             return new InsetDrawable(new FastBitmapDrawable(badge),
                     insetFraction, insetFraction, 0, 0);
+        } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
+            return ((FolderAdaptiveIcon) obj).getBadge();
         } else {
             return mLauncher.getPackageManager()
                     .getUserBadgedIcon(new FixedSizeEmptyDrawable(iconSize), info.user);
         }
     }
 
-    private ImageView setupImageView(Drawable drawable, float normalizationScale) {
-        FrameLayout.LayoutParams params = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
-        ImageView imageViewOut = new ImageView(getContext());
-        imageViewOut.setLayoutParams(params);
-        imageViewOut.setScaleType(ImageView.ScaleType.FIT_XY);
-        imageViewOut.setScaleX(normalizationScale);
-        imageViewOut.setScaleY(normalizationScale);
-        imageViewOut.setImageDrawable(drawable);
-        return imageViewOut;
-    }
-
-    private SpringAnimation setupSpringAnimation(int minValue, int maxValue,
-            DynamicAnimation.ViewProperty property) {
-        SpringAnimation s = new SpringAnimation(mFgImageView, property, 0);
-        s.setMinValue(minValue).setMaxValue(maxValue);
-        s.setSpring(new SpringForce(0)
-                        .setDampingRatio(DAMPENING_RATIO)
-                        .setStiffness(STIFFNESS));
-        return s;
-    }
-
-    @TargetApi(Build.VERSION_CODES.O)
-    private Path getMaskPath(AdaptiveIconDrawable dr, float normalizationScale) {
-        Matrix m = new Matrix();
-        // Shrink very tiny bit so that the clip path is smaller than the original bitmap
-        // that has anti aliased edges and shadows.
-        float s = normalizationScale * .97f;
-        m.setScale(s, s, dr.getBounds().centerX(), dr.getBounds().centerY());
-        Path p = new Path();
-        dr.getIconMask().transform(m, p);
-        return p;
-    }
-
-    private void applySpring(int x, int y) {
-        if (mSpringX == null || mSpringY == null) {
-            return;
-        }
-        mSpringX.animateToFinalPosition(Utilities.boundToRange(x, -mDelta, mDelta));
-        mSpringY.animateToFinalPosition(Utilities.boundToRange(y, -mDelta, mDelta));
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        int w = right - left;
-        int h = bottom - top;
-        for (int i = 0; i < getChildCount(); i++) {
-            getChildAt(i).layout(-w / 4, -h / 4, w + w / 4, h + h / 4);
-        }
-    }
-
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int w = mBitmap.getWidth();
-        int h = mBitmap.getHeight();
-        setMeasuredDimension(w, h);
-        for (int i = 0; i < getChildCount(); i++) {
-            getChildAt(i).measure(w, h);
-        }
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        if (mScaledMaskPath != null) {
-            int cnt = canvas.save();
-            canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
-            canvas.clipPath(mScaledMaskPath);
-            super.dispatchDraw(canvas);
-            canvas.restoreToCount(cnt);
-            mBadge.draw(canvas);
-        } else {
-            super.dispatchDraw(canvas);
-        }
+        setMeasuredDimension(mBitmap.getWidth(), mBitmap.getHeight());
     }
 
     /** Sets the scale of the view over the normal workspace icon size. */
@@ -439,43 +427,37 @@
         return mDragRegion;
     }
 
-    // Draws drag shadow for system DND.
-    @SuppressLint("WrongCall")
-    public void drawDragShadow(Canvas canvas) {
-        final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
-        canvas.scale(getScaleX(), getScaleY());
-        onDraw(canvas);
-        canvas.restoreToCount(saveCount);
-    }
-
-    // Provides drag shadow metrics for system DND.
-    public void provideDragShadowMetrics(Point size, Point touch) {
-        size.set((int)(mBitmap.getWidth() * getScaleX()), (int)(mBitmap.getHeight() * getScaleY()));
-
-        final float xGrowth = mBitmap.getWidth() * (getScaleX() - 1);
-        final float yGrowth = mBitmap.getHeight() * (getScaleY() - 1);
-        touch.set(
-                mRegistrationX + (int)Math.round(xGrowth / 2),
-                mRegistrationY + (int)Math.round(yGrowth / 2));
-    }
-
     @Override
     protected void onDraw(Canvas canvas) {
         mHasDrawn = true;
-        boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null;
-        if (crossFade) {
-            int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255;
-            mPaint.setAlpha(alpha);
+
+        if (mDrawBitmap) {
+            // Always draw the bitmap to mask anti aliasing due to clipPath
+            boolean crossFade = mCrossFadeProgress > 0 && mCrossFadeBitmap != null;
+            if (crossFade) {
+                int alpha = crossFade ? (int) (255 * (1 - mCrossFadeProgress)) : 255;
+                mPaint.setAlpha(alpha);
+            }
+            canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
+            if (crossFade) {
+                mPaint.setAlpha((int) (255 * mCrossFadeProgress));
+                final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
+                float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth();
+                float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight();
+                canvas.scale(sX, sY);
+                canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint);
+                canvas.restoreToCount(saveCount);
+            }
         }
-        canvas.drawBitmap(mBitmap, 0.0f, 0.0f, mPaint);
-        if (crossFade) {
-            mPaint.setAlpha((int) (255 * mCrossFadeProgress));
-            final int saveCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
-            float sX = (mBitmap.getWidth() * 1.0f) / mCrossFadeBitmap.getWidth();
-            float sY = (mBitmap.getHeight() * 1.0f) / mCrossFadeBitmap.getHeight();
-            canvas.scale(sX, sY);
-            canvas.drawBitmap(mCrossFadeBitmap, 0.0f, 0.0f, mPaint);
-            canvas.restoreToCount(saveCount);
+
+        if (mScaledMaskPath != null) {
+            int cnt = canvas.save();
+            canvas.clipPath(mScaledMaskPath);
+            mBgSpringDrawable.draw(canvas);
+            canvas.translate(mTranslateX.mValue, mTranslateY.mValue);
+            mFgSpringDrawable.draw(canvas);
+            canvas.restoreToCount(cnt);
+            mBadge.draw(canvas);
         }
     }
 
@@ -512,8 +494,7 @@
             animateFilterTo(m1.getArray());
         } else {
             if (mCurrentFilter == null) {
-                mPaint.setColorFilter(null);
-                invalidate();
+                updateColorFilter();
             } else {
                 animateFilterTo(new ColorMatrix().getArray());
             }
@@ -534,8 +515,7 @@
 
             @Override
             public void onAnimationUpdate(ValueAnimator animation) {
-                mPaint.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter));
-                invalidate();
+                updateColorFilter();
             }
         });
         mFilterAnimator.start();
@@ -590,8 +570,10 @@
      * @param touchY the y coordinate the user touched in DragLayer coordinates
      */
     public void move(int touchX, int touchY) {
-        if (touchX > 0 && touchY > 0 && mLastTouchX > 0 && mLastTouchY > 0) {
-            applySpring(mLastTouchX - touchX, mLastTouchY - touchY);
+        if (touchX > 0 && touchY > 0 && mLastTouchX > 0 && mLastTouchY > 0
+                && mScaledMaskPath != null) {
+            mTranslateX.animateToPos(mLastTouchX - touchX);
+            mTranslateY.animateToPos(mLastTouchY - touchY);
         }
         mLastTouchX = touchX;
         mLastTouchY = touchY;
@@ -642,6 +624,48 @@
         return mInitialScale;
     }
 
+    private static class SpringFloatValue {
+
+        private static final FloatPropertyCompat<SpringFloatValue> VALUE =
+                new FloatPropertyCompat<SpringFloatValue>("value") {
+                    @Override
+                    public float getValue(SpringFloatValue object) {
+                        return object.mValue;
+                    }
+
+                    @Override
+                    public void setValue(SpringFloatValue object, float value) {
+                        object.mValue = value;
+                        object.mView.invalidate();
+                    }
+                };
+
+        // Following three values are fine tuned with motion ux designer
+        private final static int STIFFNESS = 4000;
+        private final static float DAMPENING_RATIO = 1f;
+        private final static int PARALLAX_MAX_IN_DP = 8;
+
+        private final View mView;
+        private final SpringAnimation mSpring;
+        private final float mDelta;
+
+        private float mValue;
+
+        public SpringFloatValue(View view, float range) {
+            mView = view;
+            mSpring = new SpringAnimation(this, VALUE, 0)
+                    .setMinValue(-range).setMaxValue(range)
+                    .setSpring(new SpringForce(0)
+                            .setDampingRatio(DAMPENING_RATIO)
+                            .setStiffness(STIFFNESS));
+            mDelta = view.getResources().getDisplayMetrics().density * PARALLAX_MAX_IN_DP;
+        }
+
+        public void animateToPos(float value) {
+            mSpring.animateToFinalPosition(Utilities.boundToRange(value, -mDelta, mDelta));
+        }
+    }
+
     private static class FixedSizeEmptyDrawable extends ColorDrawable {
 
         private final int mSize;
diff --git a/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
new file mode 100644
index 0000000..c905460
--- /dev/null
+++ b/src/com/android/launcher3/dragndrop/FolderAdaptiveIcon.java
@@ -0,0 +1,175 @@
+/*
+ * 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.dragndrop;
+
+import android.annotation.TargetApi;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.ColorFilter;
+import android.graphics.Matrix;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PixelFormat;
+import android.graphics.Point;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.util.Log;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.MainThreadExecutor;
+import com.android.launcher3.R;
+import com.android.launcher3.folder.FolderIcon;
+import com.android.launcher3.folder.PreviewBackground;
+import com.android.launcher3.util.Preconditions;
+
+import java.util.concurrent.Callable;
+
+/**
+ * {@link AdaptiveIconDrawable} representation of a {@link FolderIcon}
+ */
+@TargetApi(Build.VERSION_CODES.O)
+public class FolderAdaptiveIcon extends AdaptiveIconDrawable {
+    private static final String TAG = "FolderAdaptiveIcon";
+
+    private final Drawable mBadge;
+    private final Path mMask;
+
+    private FolderAdaptiveIcon(Drawable bg, Drawable fg, Drawable badge, Path mask) {
+        super(bg, fg);
+        mBadge = badge;
+        mMask = mask;
+    }
+
+    @Override
+    public Path getIconMask() {
+        return mMask;
+    }
+
+    public Drawable getBadge() {
+        return mBadge;
+    }
+
+    public static FolderAdaptiveIcon createFolderAdaptiveIcon(
+            final Launcher launcher, final long folderId, Point dragViewSize) {
+        Preconditions.assertNonUiThread();
+        int margin = launcher.getResources()
+                .getDimensionPixelSize(R.dimen.blur_size_medium_outline);
+
+        // Allocate various bitmaps on the background thread, because why not!
+        final Bitmap badge = Bitmap.createBitmap(
+                dragViewSize.x - margin, dragViewSize.y - margin, Bitmap.Config.ARGB_8888);
+
+        // The bitmap for the preview is generated larger than needed to allow for the spring effect
+        float sizeScaleFactor = 1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction();
+        final Bitmap preview = Bitmap.createBitmap(
+                (int) (dragViewSize.x * sizeScaleFactor), (int) (dragViewSize.y * sizeScaleFactor),
+                Bitmap.Config.ARGB_8888);
+
+        // Create the actual drawable on the UI thread to avoid race conditions with
+        // FolderIcon draw pass
+        try {
+            return new MainThreadExecutor().submit(new Callable<FolderAdaptiveIcon>() {
+                @Override
+                public FolderAdaptiveIcon call() throws Exception {
+                    FolderIcon icon = launcher.findFolderIcon(folderId);
+                    return icon == null ? null : createDrawableOnUiThread(icon, badge, preview);
+                }
+            }).get();
+        } catch (Exception e) {
+            Log.e(TAG, "Unable to create folder icon", e);
+            return null;
+        }
+    }
+
+    /**
+     * Initializes various bitmaps on the UI thread and returns the final drawable.
+     */
+    private static FolderAdaptiveIcon createDrawableOnUiThread(FolderIcon icon,
+            Bitmap badgeBitmap, Bitmap previewBitmap) {
+        Preconditions.assertUIThread();
+        float margin = icon.getResources().getDimension(R.dimen.blur_size_medium_outline) / 2;
+
+        Canvas c = new Canvas();
+        PreviewBackground bg = icon.getFolderBackground();
+
+        // Initialize badge
+        c.setBitmap(badgeBitmap);
+        bg.drawShadow(c);
+        bg.drawBackgroundStroke(c);
+        icon.drawBadge(c);
+
+        // Initialize preview
+        float shiftFactor = AdaptiveIconDrawable.getExtraInsetFraction() /
+                (1 + 2 * AdaptiveIconDrawable.getExtraInsetFraction());
+        float previewShiftX = shiftFactor * previewBitmap.getWidth();
+        float previewShiftY = shiftFactor * previewBitmap.getHeight();
+
+        c.setBitmap(previewBitmap);
+        c.translate(previewShiftX, previewShiftY);
+        icon.getPreviewItemManager().draw(c);
+        c.setBitmap(null);
+
+        // Initialize mask
+        Path mask = new Path();
+        Matrix m = new Matrix();
+        m.setTranslate(margin, margin);
+        bg.getClipPath().transform(m, mask);
+
+        ShiftedBitmapDrawable badge = new ShiftedBitmapDrawable(badgeBitmap, margin, margin);
+        ShiftedBitmapDrawable foreground = new ShiftedBitmapDrawable(previewBitmap,
+                margin - previewShiftX, margin - previewShiftY);
+
+        return new FolderAdaptiveIcon(new ColorDrawable(bg.getBgColor()), foreground, badge, mask);
+    }
+
+    /**
+     * A simple drawable which draws a bitmap at a fixed position irrespective of the bounds
+     */
+    private static class ShiftedBitmapDrawable extends Drawable {
+
+        private final Paint mPaint = new Paint(Paint.FILTER_BITMAP_FLAG);
+        private final Bitmap mBitmap;
+        private final float mShiftX;
+        private final float mShiftY;
+
+        ShiftedBitmapDrawable(Bitmap bitmap, float shiftX, float shiftY) {
+            mBitmap = bitmap;
+            mShiftX = shiftX;
+            mShiftY = shiftY;
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+            canvas.drawBitmap(mBitmap, mShiftX, mShiftY, mPaint);
+        }
+
+        @Override
+        public void setAlpha(int i) { }
+
+        @Override
+        public void setColorFilter(ColorFilter colorFilter) {
+            mPaint.setColorFilter(colorFilter);
+        }
+
+        @Override
+        public int getOpacity() {
+            return PixelFormat.TRANSLUCENT;
+        }
+    }
+}
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index 84ec184..6533b04 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -440,6 +440,14 @@
         invalidate();
     }
 
+    public PreviewBackground getFolderBackground() {
+        return mBackground;
+    }
+
+    public PreviewItemManager getPreviewItemManager() {
+        return mPreviewItemManager;
+    }
+
     @Override
     protected void dispatchDraw(Canvas canvas) {
         super.dispatchDraw(canvas);
@@ -463,14 +471,11 @@
         } else {
             saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
             if (mPreviewLayoutRule.clipToBackground()) {
-                mBackground.clipCanvasSoftware(canvas, Region.Op.INTERSECT);
+                canvas.clipPath(mBackground.getClipPath(), Region.Op.INTERSECT);
             }
         }
 
-        // The items are drawn in coordinates relative to the preview offset
-        canvas.translate(mBackground.basePreviewOffsetX, mBackground.basePreviewOffsetY);
         mPreviewItemManager.draw(canvas);
-        canvas.translate(-mBackground.basePreviewOffsetX, -mBackground.basePreviewOffsetY);
 
         if (mPreviewLayoutRule.clipToBackground() && canvas.isHardwareAccelerated()) {
             mBackground.clipCanvasHardware(canvas);
@@ -481,6 +486,10 @@
             mBackground.drawBackgroundStroke(canvas);
         }
 
+        drawBadge(canvas);
+    }
+
+    public void drawBadge(Canvas canvas) {
         if ((mBadgeInfo != null && mBadgeInfo.hasBadge()) || mBadgeScale > 0) {
             int offsetX = mBackground.getOffsetX();
             int offsetY = mBackground.getOffsetY();
diff --git a/src/com/android/launcher3/folder/PreviewBackground.java b/src/com/android/launcher3/folder/PreviewBackground.java
index 61490ee..eba5d98 100644
--- a/src/com/android/launcher3/folder/PreviewBackground.java
+++ b/src/com/android/launcher3/folder/PreviewBackground.java
@@ -195,19 +195,28 @@
         invalidate();
     }
 
+    public int getBgColor() {
+        int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
+        return ColorUtils.setAlphaComponent(mBgColor, alpha);
+    }
+
     public void drawBackground(Canvas canvas) {
         mPaint.setStyle(Paint.Style.FILL);
-        int alpha = (int) Math.min(MAX_BG_OPACITY, BG_OPACITY * mColorMultiplier);
-        mPaint.setColor(ColorUtils.setAlphaComponent(mBgColor, alpha));
+        mPaint.setColor(getBgColor());
 
         drawCircle(canvas, 0 /* deltaRadius */);
 
-        // Draw shadow.
+        drawShadow(canvas);
+    }
+
+    public void drawShadow(Canvas canvas) {
         if (mShadowShader == null) {
             return;
         }
+
         float radius = getScaledRadius();
         float shadowRadius = radius + mStrokeWidth;
+        mPaint.setStyle(Paint.Style.FILL);
         mPaint.setColor(Color.BLACK);
         int offsetX = getOffsetX();
         int offsetY = getOffsetY();
@@ -219,7 +228,7 @@
 
         } else {
             saveCount = canvas.save(Canvas.CLIP_SAVE_FLAG);
-            clipCanvasSoftware(canvas, Region.Op.DIFFERENCE);
+            canvas.clipPath(getClipPath(), Region.Op.DIFFERENCE);
         }
 
         mShaderMatrix.setScale(shadowRadius, shadowRadius);
@@ -295,12 +304,11 @@
                 radius - deltaRadius, mPaint);
     }
 
-    // It is the callers responsibility to save and restore the canvas layers.
-    void clipCanvasSoftware(Canvas canvas, Region.Op op) {
+    public Path getClipPath() {
         mPath.reset();
         float r = getScaledRadius();
         mPath.addCircle(r + getOffsetX(), r + getOffsetY(), r, Path.Direction.CW);
-        canvas.clipPath(mPath, op);
+        return mPath;
     }
 
     // It is the callers responsibility to save and restore the canvas layers.
diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java
index 2ecb54c..2d979a6 100644
--- a/src/com/android/launcher3/folder/PreviewItemManager.java
+++ b/src/com/android/launcher3/folder/PreviewItemManager.java
@@ -146,6 +146,10 @@
     }
 
     public void draw(Canvas canvas) {
+        // The items are drawn in coordinates relative to the preview offset
+        PreviewBackground bg = mIcon.getFolderBackground();
+        canvas.translate(bg.basePreviewOffsetX, bg.basePreviewOffsetY);
+
         float firstPageItemsTransX = 0;
         if (mShouldSlideInFirstPage) {
             drawParams(canvas, mCurrentPageParams, mCurrentPageItemsTransX);
@@ -154,6 +158,7 @@
         }
 
         drawParams(canvas, mFirstPageParams, firstPageItemsTransX);
+        canvas.translate(-bg.basePreviewOffsetX, -bg.basePreviewOffsetY);
     }
 
     public void onParamsChanged() {
diff --git a/src/com/android/launcher3/graphics/GradientView.java b/src/com/android/launcher3/graphics/GradientView.java
index 678396d..5455b43 100644
--- a/src/com/android/launcher3/graphics/GradientView.java
+++ b/src/com/android/launcher3/graphics/GradientView.java
@@ -27,6 +27,7 @@
 import android.graphics.Shader;
 import android.support.v4.graphics.ColorUtils;
 import android.util.AttributeSet;
+import android.util.DisplayMetrics;
 import android.view.View;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.Interpolator;
@@ -46,7 +47,6 @@
     private static final int DEFAULT_COLOR = Color.WHITE;
     private static final int ALPHA_MASK_HEIGHT_DP = 500;
     private static final int ALPHA_MASK_WIDTH_DP = 2;
-    private static final int ALPHA_COLORS = 0xBF;
     private static final boolean DEBUG = false;
 
     private final Bitmap mAlphaGradientMask;
@@ -62,7 +62,7 @@
     private final Paint mPaintNoScrim = new Paint();
     private float mProgress;
     private final int mMaskHeight, mMaskWidth;
-    private final Context mAppContext;
+    private final int mAlphaColors;
     private final Paint mDebugPaint = DEBUG ? new Paint() : null;
     private final Interpolator mAccelerator = new AccelerateInterpolator();
     private final float mAlphaStart;
@@ -71,15 +71,14 @@
 
     public GradientView(Context context, AttributeSet attrs) {
         super(context, attrs);
-        this.mAppContext = context.getApplicationContext();
-        this.mMaskHeight = Utilities.pxFromDp(ALPHA_MASK_HEIGHT_DP,
-                mAppContext.getResources().getDisplayMetrics());
-        this.mMaskWidth = Utilities.pxFromDp(ALPHA_MASK_WIDTH_DP,
-                mAppContext.getResources().getDisplayMetrics());
+        DisplayMetrics dm = getResources().getDisplayMetrics();
+        this.mMaskHeight = Utilities.pxFromDp(ALPHA_MASK_HEIGHT_DP, dm);
+        this.mMaskWidth = Utilities.pxFromDp(ALPHA_MASK_WIDTH_DP, dm);
         Launcher launcher = Launcher.getLauncher(context);
         this.mAlphaStart = launcher.getDeviceProfile().isVerticalBarLayout() ? 0 : 100;
         this.mScrimColor = Themes.getAttrColor(context, R.attr.allAppsScrimColor);
         this.mWallpaperColorInfo = WallpaperColorInfo.getInstance(launcher);
+        mAlphaColors = getResources().getInteger(R.integer.extracted_color_gradient_alpha);
         updateColors();
         mAlphaGradientMask = createDitheredAlphaMask();
     }
@@ -104,9 +103,9 @@
 
     private void updateColors() {
         this.mColor1 = ColorUtils.setAlphaComponent(mWallpaperColorInfo.getMainColor(),
-                ALPHA_COLORS);
+                mAlphaColors);
         this.mColor2 = ColorUtils.setAlphaComponent(mWallpaperColorInfo.getSecondaryColor(),
-                ALPHA_COLORS);
+                mAlphaColors);
         if (mWidth + mHeight > 0) {
             createRadialShader();
         }
diff --git a/src/com/android/launcher3/graphics/IconNormalizer.java b/src/com/android/launcher3/graphics/IconNormalizer.java
index 34d0b72..8ed62bc 100644
--- a/src/com/android/launcher3/graphics/IconNormalizer.java
+++ b/src/com/android/launcher3/graphics/IconNormalizer.java
@@ -32,10 +32,8 @@
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.util.Log;
-
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.Utilities;
-
 import java.io.File;
 import java.io.FileOutputStream;
 import java.nio.ByteBuffer;
@@ -84,12 +82,12 @@
     private final Rect mBounds;
     private final Matrix mMatrix;
 
-    private Paint mPaintIcon;
-    private Canvas mCanvasARGB;
+    private final Paint mPaintIcon;
+    private final Canvas mCanvasARGB;
 
-    private File mDir;
+    private final File mDir;
     private int mFileId;
-    private Random mRandom;
+    private final Random mRandom;
 
     private IconNormalizer(Context context) {
         // Use twice the icon size as maximum size to avoid scaling down twice.
@@ -122,7 +120,6 @@
         mPaintMaskShapeOutline.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
 
         mMatrix = new Matrix();
-        int[] mPixels = new int[mMaxSize * mMaxSize];
         mAdaptiveIconScale = SCALE_NOT_INITIALIZED;
 
         mDir = context.getExternalFilesDir(null);
@@ -174,7 +171,8 @@
 
         boolean isTrans = isTransparentBitmap(mBitmapARGB);
         if (DEBUG) {
-            final File afterFile = new File(mDir, "isShape" + mFileId + "_after_" + isTrans + ".png");
+            final File afterFile = new File(mDir,
+                    "isShape" + mFileId + "_after_" + isTrans + ".png");
             try {
                 mBitmapARGB.compress(Bitmap.CompressFormat.PNG, 100,
                         new FileOutputStream(afterFile));
@@ -210,7 +208,9 @@
         float percentageDiffPixels = ((float) sum) / (mBounds.width() * mBounds.height());
         boolean transparentImage = percentageDiffPixels < PIXEL_DIFF_PERCENTAGE_THRESHOLD;
         if (DEBUG) {
-            Log.d(TAG, "Total # pixel that is different (id="+ mFileId + "):" + percentageDiffPixels + "="+ sum + "/" + mBounds.width() * mBounds.height());
+            Log.d(TAG,
+                    "Total # pixel that is different (id=" + mFileId + "):" + percentageDiffPixels
+                            + "=" + sum + "/" + mBounds.width() * mBounds.height());
         }
         return transparentImage;
     }
diff --git a/src/com/android/launcher3/logging/FileLog.java b/src/com/android/launcher3/logging/FileLog.java
index 4c83e9a..f7f8ef1 100644
--- a/src/com/android/launcher3/logging/FileLog.java
+++ b/src/com/android/launcher3/logging/FileLog.java
@@ -29,6 +29,8 @@
  */
 public final class FileLog {
 
+    protected static final boolean ENABLED =
+            FeatureFlags.IS_DOGFOOD_BUILD || Utilities.IS_DEBUG_DEVICE;
     private static final String FILE_NAME_PREFIX = "log-";
     private static final DateFormat DATE_FORMAT =
             DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT);
@@ -39,7 +41,7 @@
     private static File sLogsDirectory = null;
 
     public static void setDir(File logsDir) {
-        if (FeatureFlags.IS_DOGFOOD_BUILD || Utilities.IS_DEBUG_DEVICE) {
+        if (ENABLED) {
             synchronized (DATE_FORMAT) {
                 // If the target directory changes, stop any active thread.
                 if (sHandler != null && !logsDir.equals(sLogsDirectory)) {
@@ -76,7 +78,7 @@
     }
 
     public static void print(String tag, String msg, Exception e) {
-        if (!FeatureFlags.IS_DOGFOOD_BUILD) {
+        if (!ENABLED) {
             return;
         }
         String out = String.format("%s %s %s", DATE_FORMAT.format(new Date()), tag, msg);
@@ -102,7 +104,7 @@
      * @param out if not null, all the persisted logs are copied to the writer.
      */
     public static void flushAll(PrintWriter out) throws InterruptedException {
-        if (!FeatureFlags.IS_DOGFOOD_BUILD) {
+        if (!ENABLED) {
             return;
         }
         CountDownLatch latch = new CountDownLatch(1);
@@ -135,7 +137,7 @@
 
         @Override
         public boolean handleMessage(Message msg) {
-            if (sLogsDirectory == null || !FeatureFlags.IS_DOGFOOD_BUILD) {
+            if (sLogsDirectory == null || !ENABLED) {
                 return true;
             }
             switch (msg.what) {
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index 72a083b..ebb69c4 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -25,6 +25,7 @@
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.LauncherSettings;
 import com.android.launcher3.UninstallDropTarget;
+import com.android.launcher3.userevent.nano.LauncherLogExtensions.TargetExtension;
 import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
 import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
@@ -159,6 +160,13 @@
         return t;
     }
 
+    public static Target newTarget(int targetType, TargetExtension extension) {
+        Target t = new Target();
+        t.type = targetType;
+        t.extension = extension;
+        return t;
+    }
+
     public static Target newTarget(int targetType) {
         Target t = new Target();
         t.type = targetType;
diff --git a/src/com/android/launcher3/model/LoaderTask.java b/src/com/android/launcher3/model/LoaderTask.java
index 5bad436..c56325a 100644
--- a/src/com/android/launcher3/model/LoaderTask.java
+++ b/src/com/android/launcher3/model/LoaderTask.java
@@ -548,6 +548,11 @@
                             break;
 
                         case LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET:
+                            if (FeatureFlags.GO_DISABLE_WIDGETS) {
+                                c.markDeleted("Only legacy shortcuts can have null package");
+                                continue;
+                            }
+                            // Follow through
                         case LauncherSettings.Favorites.ITEM_TYPE_CUSTOM_APPWIDGET:
                             // Read all Launcher-specific widget details
                             boolean customWidget = c.itemType ==
diff --git a/src/com/android/launcher3/notification/FlingAnimationUtils.java b/src/com/android/launcher3/notification/FlingAnimationUtils.java
deleted file mode 100644
index a1f7e49..0000000
--- a/src/com/android/launcher3/notification/FlingAnimationUtils.java
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.notification;
-
-import android.animation.Animator;
-import android.content.Context;
-import android.view.ViewPropertyAnimator;
-import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
-
-/**
- * Utility class to calculate general fling animation when the finger is released.
- *
- * This class was copied from com.android.systemui.statusbar.
- */
-public class FlingAnimationUtils {
-
-    private static final float LINEAR_OUT_SLOW_IN_X2 = 0.35f;
-    private static final float LINEAR_OUT_SLOW_IN_X2_MAX = 0.68f;
-    private static final float LINEAR_OUT_FASTER_IN_X2 = 0.5f;
-    private static final float LINEAR_OUT_FASTER_IN_Y2_MIN = 0.4f;
-    private static final float LINEAR_OUT_FASTER_IN_Y2_MAX = 0.5f;
-    private static final float MIN_VELOCITY_DP_PER_SECOND = 250;
-    private static final float HIGH_VELOCITY_DP_PER_SECOND = 3000;
-
-    private static final float LINEAR_OUT_SLOW_IN_START_GRADIENT = 0.75f;
-    private final float mSpeedUpFactor;
-    private final float mY2;
-
-    private float mMinVelocityPxPerSecond;
-    private float mMaxLengthSeconds;
-    private float mHighVelocityPxPerSecond;
-    private float mLinearOutSlowInX2;
-
-    private AnimatorProperties mAnimatorProperties = new AnimatorProperties();
-    private PathInterpolator mInterpolator;
-    private float mCachedStartGradient = -1;
-    private float mCachedVelocityFactor = -1;
-
-    public FlingAnimationUtils(Context ctx, float maxLengthSeconds) {
-        this(ctx, maxLengthSeconds, 0.0f);
-    }
-
-    /**
-     * @param maxLengthSeconds the longest duration an animation can become in seconds
-     * @param speedUpFactor a factor from 0 to 1 how much the slow down should be shifted towards
-     *                      the end of the animation. 0 means it's at the beginning and no
-     *                      acceleration will take place.
-     */
-    public FlingAnimationUtils(Context ctx, float maxLengthSeconds, float speedUpFactor) {
-        this(ctx, maxLengthSeconds, speedUpFactor, -1.0f, 1.0f);
-    }
-
-    /**
-     * @param maxLengthSeconds the longest duration an animation can become in seconds
-     * @param speedUpFactor a factor from 0 to 1 how much the slow down should be shifted towards
-     *                      the end of the animation. 0 means it's at the beginning and no
-     *                      acceleration will take place.
-     * @param x2 the x value to take for the second point of the bezier spline. If a value below 0
-     *           is provided, the value is automatically calculated.
-     * @param y2 the y value to take for the second point of the bezier spline
-     */
-    public FlingAnimationUtils(Context ctx, float maxLengthSeconds, float speedUpFactor, float x2,
-            float y2) {
-        mMaxLengthSeconds = maxLengthSeconds;
-        mSpeedUpFactor = speedUpFactor;
-        if (x2 < 0) {
-            mLinearOutSlowInX2 = interpolate(LINEAR_OUT_SLOW_IN_X2,
-                    LINEAR_OUT_SLOW_IN_X2_MAX,
-                    mSpeedUpFactor);
-        } else {
-            mLinearOutSlowInX2 = x2;
-        }
-        mY2 = y2;
-
-        mMinVelocityPxPerSecond
-                = MIN_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density;
-        mHighVelocityPxPerSecond
-                = HIGH_VELOCITY_DP_PER_SECOND * ctx.getResources().getDisplayMetrics().density;
-    }
-
-    private static float interpolate(float start, float end, float amount) {
-        return start * (1.0f - amount) + end * amount;
-    }
-
-    /**
-     * Applies the interpolator and length to the animator, such that the fling animation is
-     * consistent with the finger motion.
-     *
-     * @param animator the animator to apply
-     * @param currValue the current value
-     * @param endValue the end value of the animator
-     * @param velocity the current velocity of the motion
-     */
-    public void apply(Animator animator, float currValue, float endValue, float velocity) {
-        apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue));
-    }
-
-    /**
-     * Applies the interpolator and length to the animator, such that the fling animation is
-     * consistent with the finger motion.
-     *
-     * @param animator the animator to apply
-     * @param currValue the current value
-     * @param endValue the end value of the animator
-     * @param velocity the current velocity of the motion
-     */
-    public void apply(ViewPropertyAnimator animator, float currValue, float endValue,
-            float velocity) {
-        apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue));
-    }
-
-    /**
-     * Applies the interpolator and length to the animator, such that the fling animation is
-     * consistent with the finger motion.
-     *
-     * @param animator the animator to apply
-     * @param currValue the current value
-     * @param endValue the end value of the animator
-     * @param velocity the current velocity of the motion
-     * @param maxDistance the maximum distance for this interaction; the maximum animation length
-     *                    gets multiplied by the ratio between the actual distance and this value
-     */
-    public void apply(Animator animator, float currValue, float endValue, float velocity,
-            float maxDistance) {
-        AnimatorProperties properties = getProperties(currValue, endValue, velocity,
-                maxDistance);
-        animator.setDuration(properties.duration);
-        animator.setInterpolator(properties.interpolator);
-    }
-
-    /**
-     * Applies the interpolator and length to the animator, such that the fling animation is
-     * consistent with the finger motion.
-     *
-     * @param animator the animator to apply
-     * @param currValue the current value
-     * @param endValue the end value of the animator
-     * @param velocity the current velocity of the motion
-     * @param maxDistance the maximum distance for this interaction; the maximum animation length
-     *                    gets multiplied by the ratio between the actual distance and this value
-     */
-    public void apply(ViewPropertyAnimator animator, float currValue, float endValue,
-            float velocity, float maxDistance) {
-        AnimatorProperties properties = getProperties(currValue, endValue, velocity,
-                maxDistance);
-        animator.setDuration(properties.duration);
-        animator.setInterpolator(properties.interpolator);
-    }
-
-    private AnimatorProperties getProperties(float currValue,
-            float endValue, float velocity, float maxDistance) {
-        float maxLengthSeconds = (float) (mMaxLengthSeconds
-                * Math.sqrt(Math.abs(endValue - currValue) / maxDistance));
-        float diff = Math.abs(endValue - currValue);
-        float velAbs = Math.abs(velocity);
-        float velocityFactor = mSpeedUpFactor == 0.0f
-                ? 1.0f : Math.min(velAbs / HIGH_VELOCITY_DP_PER_SECOND, 1.0f);
-        float startGradient = interpolate(LINEAR_OUT_SLOW_IN_START_GRADIENT,
-                mY2 / mLinearOutSlowInX2, velocityFactor);
-        float durationSeconds = startGradient * diff / velAbs;
-        Interpolator slowInInterpolator = getInterpolator(startGradient, velocityFactor);
-        if (durationSeconds <= maxLengthSeconds) {
-            mAnimatorProperties.interpolator = slowInInterpolator;
-        } else if (velAbs >= mMinVelocityPxPerSecond) {
-
-            // Cross fade between fast-out-slow-in and linear interpolator with current velocity.
-            durationSeconds = maxLengthSeconds;
-            VelocityInterpolator velocityInterpolator
-                    = new VelocityInterpolator(durationSeconds, velAbs, diff);
-            InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
-                    velocityInterpolator, slowInInterpolator, Interpolators.LINEAR_OUT_SLOW_IN);
-            mAnimatorProperties.interpolator = superInterpolator;
-        } else {
-
-            // Just use a normal interpolator which doesn't take the velocity into account.
-            durationSeconds = maxLengthSeconds;
-            mAnimatorProperties.interpolator = Interpolators.FAST_OUT_SLOW_IN;
-        }
-        mAnimatorProperties.duration = (long) (durationSeconds * 1000);
-        return mAnimatorProperties;
-    }
-
-    private Interpolator getInterpolator(float startGradient, float velocityFactor) {
-        if (startGradient != mCachedStartGradient
-                || velocityFactor != mCachedVelocityFactor) {
-            float speedup = mSpeedUpFactor * (1.0f - velocityFactor);
-            mInterpolator = new PathInterpolator(speedup,
-                    speedup * startGradient,
-                    mLinearOutSlowInX2, mY2);
-            mCachedStartGradient = startGradient;
-            mCachedVelocityFactor = velocityFactor;
-        }
-        return mInterpolator;
-    }
-
-    /**
-     * Applies the interpolator and length to the animator, such that the fling animation is
-     * consistent with the finger motion for the case when the animation is making something
-     * disappear.
-     *
-     * @param animator the animator to apply
-     * @param currValue the current value
-     * @param endValue the end value of the animator
-     * @param velocity the current velocity of the motion
-     * @param maxDistance the maximum distance for this interaction; the maximum animation length
-     *                    gets multiplied by the ratio between the actual distance and this value
-     */
-    public void applyDismissing(Animator animator, float currValue, float endValue,
-            float velocity, float maxDistance) {
-        AnimatorProperties properties = getDismissingProperties(currValue, endValue, velocity,
-                maxDistance);
-        animator.setDuration(properties.duration);
-        animator.setInterpolator(properties.interpolator);
-    }
-
-    /**
-     * Applies the interpolator and length to the animator, such that the fling animation is
-     * consistent with the finger motion for the case when the animation is making something
-     * disappear.
-     *
-     * @param animator the animator to apply
-     * @param currValue the current value
-     * @param endValue the end value of the animator
-     * @param velocity the current velocity of the motion
-     * @param maxDistance the maximum distance for this interaction; the maximum animation length
-     *                    gets multiplied by the ratio between the actual distance and this value
-     */
-    public void applyDismissing(ViewPropertyAnimator animator, float currValue, float endValue,
-            float velocity, float maxDistance) {
-        AnimatorProperties properties = getDismissingProperties(currValue, endValue, velocity,
-                maxDistance);
-        animator.setDuration(properties.duration);
-        animator.setInterpolator(properties.interpolator);
-    }
-
-    private AnimatorProperties getDismissingProperties(float currValue, float endValue,
-            float velocity, float maxDistance) {
-        float maxLengthSeconds = (float) (mMaxLengthSeconds
-                * Math.pow(Math.abs(endValue - currValue) / maxDistance, 0.5f));
-        float diff = Math.abs(endValue - currValue);
-        float velAbs = Math.abs(velocity);
-        float y2 = calculateLinearOutFasterInY2(velAbs);
-
-        float startGradient = y2 / LINEAR_OUT_FASTER_IN_X2;
-        Interpolator mLinearOutFasterIn = new PathInterpolator(0, 0, LINEAR_OUT_FASTER_IN_X2, y2);
-        float durationSeconds = startGradient * diff / velAbs;
-        if (durationSeconds <= maxLengthSeconds) {
-            mAnimatorProperties.interpolator = mLinearOutFasterIn;
-        } else if (velAbs >= mMinVelocityPxPerSecond) {
-
-            // Cross fade between linear-out-faster-in and linear interpolator with current
-            // velocity.
-            durationSeconds = maxLengthSeconds;
-            VelocityInterpolator velocityInterpolator
-                    = new VelocityInterpolator(durationSeconds, velAbs, diff);
-            InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
-                    velocityInterpolator, mLinearOutFasterIn, Interpolators.LINEAR_OUT_SLOW_IN);
-            mAnimatorProperties.interpolator = superInterpolator;
-        } else {
-
-            // Just use a normal interpolator which doesn't take the velocity into account.
-            durationSeconds = maxLengthSeconds;
-            mAnimatorProperties.interpolator = Interpolators.FAST_OUT_LINEAR_IN;
-        }
-        mAnimatorProperties.duration = (long) (durationSeconds * 1000);
-        return mAnimatorProperties;
-    }
-
-    /**
-     * Calculates the y2 control point for a linear-out-faster-in path interpolator depending on the
-     * velocity. The faster the velocity, the more "linear" the interpolator gets.
-     *
-     * @param velocity the velocity of the gesture.
-     * @return the y2 control point for a cubic bezier path interpolator
-     */
-    private float calculateLinearOutFasterInY2(float velocity) {
-        float t = (velocity - mMinVelocityPxPerSecond)
-                / (mHighVelocityPxPerSecond - mMinVelocityPxPerSecond);
-        t = Math.max(0, Math.min(1, t));
-        return (1 - t) * LINEAR_OUT_FASTER_IN_Y2_MIN + t * LINEAR_OUT_FASTER_IN_Y2_MAX;
-    }
-
-    /**
-     * @return the minimum velocity a gesture needs to have to be considered a fling
-     */
-    public float getMinVelocityPxPerSecond() {
-        return mMinVelocityPxPerSecond;
-    }
-
-    /**
-     * An interpolator which interpolates two interpolators with an interpolator.
-     */
-    private static final class InterpolatorInterpolator implements Interpolator {
-
-        private Interpolator mInterpolator1;
-        private Interpolator mInterpolator2;
-        private Interpolator mCrossfader;
-
-        InterpolatorInterpolator(Interpolator interpolator1, Interpolator interpolator2,
-                Interpolator crossfader) {
-            mInterpolator1 = interpolator1;
-            mInterpolator2 = interpolator2;
-            mCrossfader = crossfader;
-        }
-
-        @Override
-        public float getInterpolation(float input) {
-            float t = mCrossfader.getInterpolation(input);
-            return (1 - t) * mInterpolator1.getInterpolation(input)
-                    + t * mInterpolator2.getInterpolation(input);
-        }
-    }
-
-    /**
-     * An interpolator which interpolates with a fixed velocity.
-     */
-    private static final class VelocityInterpolator implements Interpolator {
-
-        private float mDurationSeconds;
-        private float mVelocity;
-        private float mDiff;
-
-        private VelocityInterpolator(float durationSeconds, float velocity, float diff) {
-            mDurationSeconds = durationSeconds;
-            mVelocity = velocity;
-            mDiff = diff;
-        }
-
-        @Override
-        public float getInterpolation(float input) {
-            float time = input * mDurationSeconds;
-            return time * mVelocity / mDiff;
-        }
-    }
-
-    private static class AnimatorProperties {
-        Interpolator interpolator;
-        long duration;
-    }
-
-}
diff --git a/src/com/android/launcher3/notification/NotificationItemView.java b/src/com/android/launcher3/notification/NotificationItemView.java
index 11f6aa0..78c64d7 100644
--- a/src/com/android/launcher3/notification/NotificationItemView.java
+++ b/src/com/android/launcher3/notification/NotificationItemView.java
@@ -37,6 +37,7 @@
 import com.android.launcher3.graphics.IconPalette;
 import com.android.launcher3.logging.UserEventDispatcher.LogContainerProvider;
 import com.android.launcher3.popup.PopupItemView;
+import com.android.launcher3.touch.SwipeDetector;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.util.Themes;
 
@@ -56,7 +57,7 @@
     private TextView mHeaderCount;
     private NotificationMainView mMainView;
     private NotificationFooterLayout mFooter;
-    private SwipeHelper mSwipeHelper;
+    private SwipeDetector mSwipeDetector;
     private boolean mAnimatingNextIcon;
     private int mNotificationHeaderTextColor = Notification.COLOR_DEFAULT;
 
@@ -75,12 +76,14 @@
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
-        mHeaderText = (TextView) findViewById(R.id.notification_text);
-        mHeaderCount = (TextView) findViewById(R.id.notification_count);
-        mMainView = (NotificationMainView) findViewById(R.id.main_view);
-        mFooter = (NotificationFooterLayout) findViewById(R.id.footer);
-        mSwipeHelper = new SwipeHelper(SwipeHelper.X, mMainView, getContext());
-        mSwipeHelper.setDisableHardwareLayers(true);
+        mHeaderText = findViewById(R.id.notification_text);
+        mHeaderCount = findViewById(R.id.notification_count);
+        mMainView = findViewById(R.id.main_view);
+        mFooter = findViewById(R.id.footer);
+
+        mSwipeDetector = new SwipeDetector(getContext(), mMainView, SwipeDetector.HORIZONTAL);
+        mSwipeDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false);
+        mMainView.setSwipeDetector(mSwipeDetector);
     }
 
     public NotificationMainView getMainView() {
@@ -136,7 +139,8 @@
             return false;
         }
         getParent().requestDisallowInterceptTouchEvent(true);
-        return mSwipeHelper.onInterceptTouchEvent(ev);
+        mSwipeDetector.onTouchEvent(ev);
+        return mSwipeDetector.isDraggingOrSettling();
     }
 
     @Override
@@ -145,7 +149,7 @@
             // The notification hasn't been populated yet.
             return false;
         }
-        return mSwipeHelper.onTouchEvent(ev) || super.onTouchEvent(ev);
+        return mSwipeDetector.onTouchEvent(ev) || super.onTouchEvent(ev);
     }
 
     public void applyNotificationInfos(final List<NotificationInfo> notificationInfos) {
diff --git a/src/com/android/launcher3/notification/NotificationListener.java b/src/com/android/launcher3/notification/NotificationListener.java
index 73d89aa..6a70989 100644
--- a/src/com/android/launcher3/notification/NotificationListener.java
+++ b/src/com/android/launcher3/notification/NotificationListener.java
@@ -30,15 +30,20 @@
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.Pair;
+
 import com.android.launcher3.LauncherModel;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.PackageUserKey;
+import com.android.launcher3.util.SettingsObserver;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 
+import static com.android.launcher3.SettingsActivity.NOTIFICATION_BADGING;
+
 /**
  * A {@link NotificationListenerService} that sends updates to its
  * {@link NotificationsChangedListener} when notifications are posted or canceled,
@@ -57,12 +62,14 @@
     private static NotificationListener sNotificationListenerInstance = null;
     private static NotificationsChangedListener sNotificationsChangedListener;
     private static boolean sIsConnected;
+    private static boolean sIsCreated;
 
     private final Handler mWorkerHandler;
     private final Handler mUiHandler;
-
     private final Ranking mTempRanking = new Ranking();
 
+    private SettingsObserver mNotificationBadgingObserver;
+
     private final Handler.Callback mWorkerCallback = new Handler.Callback() {
         @Override
         public boolean handleMessage(Message message) {
@@ -77,7 +84,7 @@
                     List<StatusBarNotification> activeNotifications;
                     if (sIsConnected) {
                         try {
-                            activeNotifications =  filterNotifications(getActiveNotifications());
+                            activeNotifications = filterNotifications(getActiveNotifications());
                         } catch (SecurityException ex) {
                             Log.e(TAG, "SecurityException: failed to fetch notifications");
                             activeNotifications = new ArrayList<StatusBarNotification>();
@@ -130,6 +137,28 @@
         sNotificationListenerInstance = this;
     }
 
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        sIsCreated = true;
+        mNotificationBadgingObserver = new SettingsObserver.Secure(getContentResolver()) {
+            @Override
+            public void onSettingChanged(boolean isNotificationBadgingEnabled) {
+                if (!isNotificationBadgingEnabled) {
+                    requestUnbind();
+                }
+            }
+        };
+        mNotificationBadgingObserver.register(NOTIFICATION_BADGING);
+    }
+
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        sIsCreated = false;
+        mNotificationBadgingObserver.unregister();
+    }
+
     public static @Nullable NotificationListener getInstanceIfConnected() {
         return sIsConnected ? sNotificationListenerInstance : null;
     }
@@ -143,6 +172,11 @@
         NotificationListener notificationListener = getInstanceIfConnected();
         if (notificationListener != null) {
             notificationListener.onNotificationFullRefresh();
+        } else if (!sIsCreated && sNotificationsChangedListener != null) {
+            // User turned off badging globally, so we unbound this service;
+            // tell the listener that there are no notifications to remove dots.
+            sNotificationsChangedListener.onNotificationFullRefresh(
+                    Collections.<StatusBarNotification>emptyList());
         }
     }
 
@@ -205,7 +239,7 @@
                 .getActiveNotifications(NotificationKeyData.extractKeysOnly(keys)
                         .toArray(new String[keys.size()]));
         return notifications == null
-            ? Collections.<StatusBarNotification>emptyList() : Arrays.asList(notifications);
+                ? Collections.<StatusBarNotification>emptyList() : Arrays.asList(notifications);
     }
 
     /**
diff --git a/src/com/android/launcher3/notification/NotificationMainView.java b/src/com/android/launcher3/notification/NotificationMainView.java
index 9b8dd64..5aff28d 100644
--- a/src/com/android/launcher3/notification/NotificationMainView.java
+++ b/src/com/android/launcher3/notification/NotificationMainView.java
@@ -23,15 +23,17 @@
 import android.graphics.drawable.RippleDrawable;
 import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewPropertyAnimator;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
 import com.android.launcher3.ItemInfo;
 import com.android.launcher3.Launcher;
 import com.android.launcher3.R;
+import com.android.launcher3.touch.OverScroll;
+import com.android.launcher3.touch.SwipeDetector;
 import com.android.launcher3.userevent.nano.LauncherLogProto;
 import com.android.launcher3.util.Themes;
 
@@ -39,7 +41,7 @@
  * A {@link android.widget.FrameLayout} that contains a single notification,
  * e.g. icon + title + text.
  */
-public class NotificationMainView extends FrameLayout implements SwipeHelper.Callback {
+public class NotificationMainView extends FrameLayout implements SwipeDetector.Listener {
 
     private NotificationInfo mNotificationInfo;
     private ViewGroup mTextAndBackground;
@@ -47,6 +49,8 @@
     private TextView mTitleView;
     private TextView mTextView;
 
+    private SwipeDetector mSwipeDetector;
+
     public NotificationMainView(Context context) {
         this(context, null, 0);
     }
@@ -78,6 +82,10 @@
         applyNotificationInfo(mainNotification, iconView, false);
     }
 
+    public void setSwipeDetector(SwipeDetector swipeDetector) {
+        mSwipeDetector = swipeDetector;
+    }
+
     /**
      * Sets the content of this view, animating it after a new icon shifts up if necessary.
      */
@@ -113,29 +121,11 @@
     }
 
 
-    // SwipeHelper.Callback's
-
-    @Override
-    public View getChildAtPosition(MotionEvent ev) {
-        return this;
-    }
-
-    @Override
-    public boolean canChildBeDismissed(View v) {
+    public boolean canChildBeDismissed() {
         return mNotificationInfo != null && mNotificationInfo.dismissable;
     }
 
-    @Override
-    public boolean isAntiFalsingNeeded() {
-        return false;
-    }
-
-    @Override
-    public void onBeginDrag(View v) {
-    }
-
-    @Override
-    public void onChildDismissed(View v) {
+    public void onChildDismissed() {
         Launcher launcher = Launcher.getLauncher(getContext());
         launcher.getPopupDataProvider().cancelNotification(
                 mNotificationInfo.notificationKey);
@@ -145,22 +135,55 @@
                 LauncherLogProto.ItemType.NOTIFICATION);
     }
 
+    // SwipeDetector.Listener's
     @Override
-    public void onDragCancelled(View v) {
-    }
+    public void onDragStart(boolean start) { }
+
 
     @Override
-    public void onChildSnappedBack(View animView, float targetLeft) {
-    }
-
-    @Override
-    public boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress) {
-        // Don't fade out.
+    public boolean onDrag(float displacement, float velocity) {
+        setTranslationX(canChildBeDismissed()
+                ? displacement : OverScroll.dampedScroll(displacement, getWidth()));
+        animate().cancel();
         return true;
     }
 
     @Override
-    public float getFalsingThresholdFactor() {
-        return 1;
+    public void onDragEnd(float velocity, boolean fling) {
+        final boolean willExit;
+        final float endTranslation;
+
+        if (!canChildBeDismissed()) {
+            willExit = false;
+            endTranslation = 0;
+        } else if (fling) {
+            willExit = true;
+            endTranslation = velocity < 0 ? - getWidth() : getWidth();
+        } else if (Math.abs(getTranslationX()) > getWidth() / 2) {
+            willExit = true;
+            endTranslation = (getTranslationX() < 0 ? -getWidth() : getWidth());
+        } else {
+            willExit = false;
+            endTranslation = 0;
+        }
+
+        SwipeDetector.ScrollInterpolator interpolator = new SwipeDetector.ScrollInterpolator();
+        interpolator.setVelocityAtZero(velocity);
+
+        long duration = SwipeDetector.calculateDuration(velocity,
+                (endTranslation - getTranslationX()) / getWidth());
+        animate()
+                .setDuration(duration)
+                .setInterpolator(interpolator)
+                .translationX(endTranslation)
+                .withEndAction(new Runnable() {
+                    @Override
+                    public void run() {
+                        mSwipeDetector.finishedScrolling();
+                        if (willExit) {
+                            onChildDismissed();
+                        }
+                    }
+                }).start();
     }
 }
diff --git a/src/com/android/launcher3/notification/SwipeHelper.java b/src/com/android/launcher3/notification/SwipeHelper.java
deleted file mode 100644
index ebbe5fc..0000000
--- a/src/com/android/launcher3/notification/SwipeHelper.java
+++ /dev/null
@@ -1,687 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.notification;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
-import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.graphics.RectF;
-import android.os.Handler;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.view.MotionEvent;
-import android.view.VelocityTracker;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.accessibility.AccessibilityEvent;
-import com.android.launcher3.R;
-
-/**
- * This class was copied from com.android.systemui.
- */
-public class SwipeHelper {
-    private static final String TAG = "SwipeHelper";
-    private static final boolean DEBUG_INVALIDATE = false;
-    private static final boolean SLOW_ANIMATIONS = false; // DEBUG;
-    private static final boolean CONSTRAIN_SWIPE = true;
-    private static final boolean FADE_OUT_DURING_SWIPE = true;
-    private static final boolean DISMISS_IF_SWIPED_FAR_ENOUGH = true;
-
-    public static final int X = 0;
-    public static final int Y = 1;
-
-    private static final float SWIPE_ESCAPE_VELOCITY = 100f; // dp/sec
-    private static final int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms
-    private static final int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms
-    private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec
-    private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 150; // ms
-
-    static final float SWIPE_PROGRESS_FADE_END = 0.5f; // fraction of thumbnail width
-                                                // beyond which swipe progress->0
-    private float mMinSwipeProgress = 0f;
-    private float mMaxSwipeProgress = 1f;
-
-    private final FlingAnimationUtils mFlingAnimationUtils;
-    private float mPagingTouchSlop;
-    private final Callback mCallback;
-    private final Handler mHandler;
-    private final int mSwipeDirection;
-    private final VelocityTracker mVelocityTracker;
-
-    private float mInitialTouchPos;
-    private float mPerpendicularInitialTouchPos;
-    private boolean mDragging;
-    private boolean mSnappingChild;
-    private View mCurrView;
-    private boolean mCanCurrViewBeDimissed;
-    private float mDensityScale;
-    private float mTranslation = 0;
-
-    private boolean mLongPressSent;
-    private LongPressListener mLongPressListener;
-    private Runnable mWatchLongPress;
-    private final long mLongPressTimeout;
-
-    final private int[] mTmpPos = new int[2];
-    private final int mFalsingThreshold;
-    private boolean mTouchAboveFalsingThreshold;
-    private boolean mDisableHwLayers;
-
-    private final ArrayMap<View, Animator> mDismissPendingMap = new ArrayMap<>();
-
-    public SwipeHelper(int swipeDirection, Callback callback, Context context) {
-        mCallback = callback;
-        mHandler = new Handler();
-        mSwipeDirection = swipeDirection;
-        mVelocityTracker = VelocityTracker.obtain();
-        mDensityScale =  context.getResources().getDisplayMetrics().density;
-        mPagingTouchSlop = ViewConfiguration.get(context).getScaledPagingTouchSlop();
-
-        mLongPressTimeout = (long) (ViewConfiguration.getLongPressTimeout() * 1.5f); // extra long-press!
-        mFalsingThreshold = context.getResources().getDimensionPixelSize(
-                R.dimen.swipe_helper_falsing_threshold);
-        mFlingAnimationUtils = new FlingAnimationUtils(context, getMaxEscapeAnimDuration() / 1000f);
-    }
-
-    public void setLongPressListener(LongPressListener listener) {
-        mLongPressListener = listener;
-    }
-
-    public void setDensityScale(float densityScale) {
-        mDensityScale = densityScale;
-    }
-
-    public void setPagingTouchSlop(float pagingTouchSlop) {
-        mPagingTouchSlop = pagingTouchSlop;
-    }
-
-    public void setDisableHardwareLayers(boolean disableHwLayers) {
-        mDisableHwLayers = disableHwLayers;
-    }
-
-    private float getPos(MotionEvent ev) {
-        return mSwipeDirection == X ? ev.getX() : ev.getY();
-    }
-
-    private float getPerpendicularPos(MotionEvent ev) {
-        return mSwipeDirection == X ? ev.getY() : ev.getX();
-    }
-
-    protected float getTranslation(View v) {
-        return mSwipeDirection == X ? v.getTranslationX() : v.getTranslationY();
-    }
-
-    private float getVelocity(VelocityTracker vt) {
-        return mSwipeDirection == X ? vt.getXVelocity() :
-                vt.getYVelocity();
-    }
-
-    protected ObjectAnimator createTranslationAnimation(View v, float newPos) {
-        ObjectAnimator anim = ObjectAnimator.ofFloat(v,
-                mSwipeDirection == X ? View.TRANSLATION_X : View.TRANSLATION_Y, newPos);
-        return anim;
-    }
-
-    private float getPerpendicularVelocity(VelocityTracker vt) {
-        return mSwipeDirection == X ? vt.getYVelocity() :
-                vt.getXVelocity();
-    }
-
-    protected Animator getViewTranslationAnimator(View v, float target,
-            AnimatorUpdateListener listener) {
-        ObjectAnimator anim = createTranslationAnimation(v, target);
-        if (listener != null) {
-            anim.addUpdateListener(listener);
-        }
-        return anim;
-    }
-
-    protected void setTranslation(View v, float translate) {
-        if (v == null) {
-            return;
-        }
-        if (mSwipeDirection == X) {
-            v.setTranslationX(translate);
-        } else {
-            v.setTranslationY(translate);
-        }
-    }
-
-    protected float getSize(View v) {
-        return mSwipeDirection == X ? v.getMeasuredWidth() :
-                v.getMeasuredHeight();
-    }
-
-    public void setMinSwipeProgress(float minSwipeProgress) {
-        mMinSwipeProgress = minSwipeProgress;
-    }
-
-    public void setMaxSwipeProgress(float maxSwipeProgress) {
-        mMaxSwipeProgress = maxSwipeProgress;
-    }
-
-    private float getSwipeProgressForOffset(View view, float translation) {
-        float viewSize = getSize(view);
-        float result = Math.abs(translation / viewSize);
-        return Math.min(Math.max(mMinSwipeProgress, result), mMaxSwipeProgress);
-    }
-
-    private float getSwipeAlpha(float progress) {
-        return Math.min(0, Math.max(1, progress / SWIPE_PROGRESS_FADE_END));
-    }
-
-    private void updateSwipeProgressFromOffset(View animView, boolean dismissable) {
-        updateSwipeProgressFromOffset(animView, dismissable, getTranslation(animView));
-    }
-
-    private void updateSwipeProgressFromOffset(View animView, boolean dismissable,
-            float translation) {
-        float swipeProgress = getSwipeProgressForOffset(animView, translation);
-        if (!mCallback.updateSwipeProgress(animView, dismissable, swipeProgress)) {
-            if (FADE_OUT_DURING_SWIPE && dismissable) {
-                float alpha = swipeProgress;
-                if (!mDisableHwLayers) {
-                    if (alpha != 0f && alpha != 1f) {
-                        animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-                    } else {
-                        animView.setLayerType(View.LAYER_TYPE_NONE, null);
-                    }
-                }
-                animView.setAlpha(getSwipeAlpha(swipeProgress));
-            }
-        }
-        invalidateGlobalRegion(animView);
-    }
-
-    // invalidate the view's own bounds all the way up the view hierarchy
-    public static void invalidateGlobalRegion(View view) {
-        invalidateGlobalRegion(
-                view,
-                new RectF(view.getLeft(), view.getTop(), view.getRight(), view.getBottom()));
-    }
-
-    // invalidate a rectangle relative to the view's coordinate system all the way up the view
-    // hierarchy
-    public static void invalidateGlobalRegion(View view, RectF childBounds) {
-        //childBounds.offset(view.getTranslationX(), view.getTranslationY());
-        if (DEBUG_INVALIDATE)
-            Log.v(TAG, "-------------");
-        while (view.getParent() != null && view.getParent() instanceof View) {
-            view = (View) view.getParent();
-            view.getMatrix().mapRect(childBounds);
-            view.invalidate((int) Math.floor(childBounds.left),
-                    (int) Math.floor(childBounds.top),
-                    (int) Math.ceil(childBounds.right),
-                    (int) Math.ceil(childBounds.bottom));
-            if (DEBUG_INVALIDATE) {
-                Log.v(TAG, "INVALIDATE(" + (int) Math.floor(childBounds.left)
-                        + "," + (int) Math.floor(childBounds.top)
-                        + "," + (int) Math.ceil(childBounds.right)
-                        + "," + (int) Math.ceil(childBounds.bottom));
-            }
-        }
-    }
-
-    public void removeLongPressCallback() {
-        if (mWatchLongPress != null) {
-            mHandler.removeCallbacks(mWatchLongPress);
-            mWatchLongPress = null;
-        }
-    }
-
-    public boolean onInterceptTouchEvent(final MotionEvent ev) {
-        final int action = ev.getAction();
-
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                mTouchAboveFalsingThreshold = false;
-                mDragging = false;
-                mSnappingChild = false;
-                mLongPressSent = false;
-                mVelocityTracker.clear();
-                mCurrView = mCallback.getChildAtPosition(ev);
-
-                if (mCurrView != null) {
-                    onDownUpdate(mCurrView);
-                    mCanCurrViewBeDimissed = mCallback.canChildBeDismissed(mCurrView);
-                    mVelocityTracker.addMovement(ev);
-                    mInitialTouchPos = getPos(ev);
-                    mPerpendicularInitialTouchPos = getPerpendicularPos(ev);
-                    mTranslation = getTranslation(mCurrView);
-                    if (mLongPressListener != null) {
-                        if (mWatchLongPress == null) {
-                            mWatchLongPress = new Runnable() {
-                                @Override
-                                public void run() {
-                                    if (mCurrView != null && !mLongPressSent) {
-                                        mLongPressSent = true;
-                                        mCurrView.sendAccessibilityEvent(
-                                                AccessibilityEvent.TYPE_VIEW_LONG_CLICKED);
-                                        mCurrView.getLocationOnScreen(mTmpPos);
-                                        final int x = (int) ev.getRawX() - mTmpPos[0];
-                                        final int y = (int) ev.getRawY() - mTmpPos[1];
-                                        mLongPressListener.onLongPress(mCurrView, x, y);
-                                    }
-                                }
-                            };
-                        }
-                        mHandler.postDelayed(mWatchLongPress, mLongPressTimeout);
-                    }
-                }
-                break;
-
-            case MotionEvent.ACTION_MOVE:
-                if (mCurrView != null && !mLongPressSent) {
-                    mVelocityTracker.addMovement(ev);
-                    float pos = getPos(ev);
-                    float perpendicularPos = getPerpendicularPos(ev);
-                    float delta = pos - mInitialTouchPos;
-                    float deltaPerpendicular = perpendicularPos - mPerpendicularInitialTouchPos;
-                    if (Math.abs(delta) > mPagingTouchSlop
-                            && Math.abs(delta) > Math.abs(deltaPerpendicular)) {
-                        mCallback.onBeginDrag(mCurrView);
-                        mDragging = true;
-                        mInitialTouchPos = getPos(ev);
-                        mTranslation = getTranslation(mCurrView);
-                        removeLongPressCallback();
-                    }
-                }
-                break;
-
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                final boolean captured = (mDragging || mLongPressSent);
-                mDragging = false;
-                mCurrView = null;
-                mLongPressSent = false;
-                removeLongPressCallback();
-                if (captured) return true;
-                break;
-        }
-        return mDragging || mLongPressSent;
-    }
-
-    /**
-     * @param view The view to be dismissed
-     * @param velocity The desired pixels/second speed at which the view should move
-     * @param useAccelerateInterpolator Should an accelerating Interpolator be used
-     */
-    public void dismissChild(final View view, float velocity, boolean useAccelerateInterpolator) {
-        dismissChild(view, velocity, null /* endAction */, 0 /* delay */,
-                useAccelerateInterpolator, 0 /* fixedDuration */, false /* isDismissAll */);
-    }
-
-    /**
-     * @param animView The view to be dismissed
-     * @param velocity The desired pixels/second speed at which the view should move
-     * @param endAction The action to perform at the end
-     * @param delay The delay after which we should start
-     * @param useAccelerateInterpolator Should an accelerating Interpolator be used
-     * @param fixedDuration If not 0, this exact duration will be taken
-     */
-    public void dismissChild(final View animView, float velocity, final Runnable endAction,
-            long delay, boolean useAccelerateInterpolator, long fixedDuration,
-            boolean isDismissAll) {
-        final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
-        float newPos;
-        boolean isLayoutRtl = animView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
-
-        // if we use the Menu to dismiss an item in landscape, animate up
-        boolean animateUpForMenu = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll)
-                && mSwipeDirection == Y;
-        // if the language is rtl we prefer swiping to the left
-        boolean animateLeftForRtl = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll)
-                && isLayoutRtl;
-        boolean animateLeft = velocity < 0
-                || (velocity == 0 && getTranslation(animView) < 0 && !isDismissAll);
-
-        if (animateLeft || animateLeftForRtl || animateUpForMenu) {
-            newPos = -getSize(animView);
-        } else {
-            newPos = getSize(animView);
-        }
-        long duration;
-        if (fixedDuration == 0) {
-            duration = MAX_ESCAPE_ANIMATION_DURATION;
-            if (velocity != 0) {
-                duration = Math.min(duration,
-                        (int) (Math.abs(newPos - getTranslation(animView)) * 1000f / Math
-                                .abs(velocity))
-                );
-            } else {
-                duration = DEFAULT_ESCAPE_ANIMATION_DURATION;
-            }
-        } else {
-            duration = fixedDuration;
-        }
-
-        if (!mDisableHwLayers) {
-            animView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-        }
-        AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
-            public void onAnimationUpdate(ValueAnimator animation) {
-                onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
-            }
-        };
-
-        Animator anim = getViewTranslationAnimator(animView, newPos, updateListener);
-        if (anim == null) {
-            return;
-        }
-        if (useAccelerateInterpolator) {
-            anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN);
-            anim.setDuration(duration);
-        } else {
-            mFlingAnimationUtils.applyDismissing(anim, getTranslation(animView),
-                    newPos, velocity, getSize(animView));
-        }
-        if (delay > 0) {
-            anim.setStartDelay(delay);
-        }
-        anim.addListener(new AnimatorListenerAdapter() {
-            private boolean mCancelled;
-
-            public void onAnimationCancel(Animator animation) {
-                mCancelled = true;
-            }
-
-            public void onAnimationEnd(Animator animation) {
-                updateSwipeProgressFromOffset(animView, canBeDismissed);
-                mDismissPendingMap.remove(animView);
-                if (!mCancelled) {
-                    mCallback.onChildDismissed(animView);
-                }
-                if (endAction != null) {
-                    endAction.run();
-                }
-                if (!mDisableHwLayers) {
-                    animView.setLayerType(View.LAYER_TYPE_NONE, null);
-                }
-            }
-        });
-
-        prepareDismissAnimation(animView, anim);
-        mDismissPendingMap.put(animView, anim);
-        anim.start();
-    }
-
-    /**
-     * Called to update the dismiss animation.
-     */
-    protected void prepareDismissAnimation(View view, Animator anim) {
-        // Do nothing
-    }
-
-    public void snapChild(final View animView, final float targetLeft, float velocity) {
-        final boolean canBeDismissed = mCallback.canChildBeDismissed(animView);
-        AnimatorUpdateListener updateListener = new AnimatorUpdateListener() {
-            public void onAnimationUpdate(ValueAnimator animation) {
-                onTranslationUpdate(animView, (float) animation.getAnimatedValue(), canBeDismissed);
-            }
-        };
-
-        Animator anim = getViewTranslationAnimator(animView, targetLeft, updateListener);
-        if (anim == null) {
-            return;
-        }
-        int duration = SNAP_ANIM_LEN;
-        anim.setDuration(duration);
-        anim.addListener(new AnimatorListenerAdapter() {
-            public void onAnimationEnd(Animator animator) {
-                mSnappingChild = false;
-                updateSwipeProgressFromOffset(animView, canBeDismissed);
-                mCallback.onChildSnappedBack(animView, targetLeft);
-            }
-        });
-        prepareSnapBackAnimation(animView, anim);
-        mSnappingChild = true;
-        anim.start();
-    }
-
-    /**
-     * Called to update the snap back animation.
-     */
-    protected void prepareSnapBackAnimation(View view, Animator anim) {
-        // Do nothing
-    }
-
-    /**
-     * Called when there's a down event.
-     */
-    public void onDownUpdate(View currView) {
-        // Do nothing
-    }
-
-    /**
-     * Called on a move event.
-     */
-    protected void onMoveUpdate(View view, float totalTranslation, float delta) {
-        // Do nothing
-    }
-
-    /**
-     * Called in {@link AnimatorUpdateListener#onAnimationUpdate(ValueAnimator)} when the current
-     * view is being animated to dismiss or snap.
-     */
-    public void onTranslationUpdate(View animView, float value, boolean canBeDismissed) {
-        updateSwipeProgressFromOffset(animView, canBeDismissed, value);
-    }
-
-    private void snapChildInstantly(final View view) {
-        final boolean canAnimViewBeDismissed = mCallback.canChildBeDismissed(view);
-        setTranslation(view, 0);
-        updateSwipeProgressFromOffset(view, canAnimViewBeDismissed);
-    }
-
-    /**
-     * Called when a view is updated to be non-dismissable, if the view was being dismissed before
-     * the update this will handle snapping it back into place.
-     *
-     * @param view the view to snap if necessary.
-     * @param animate whether to animate the snap or not.
-     * @param targetLeft the target to snap to.
-     */
-    public void snapChildIfNeeded(final View view, boolean animate, float targetLeft) {
-        if ((mDragging && mCurrView == view) || mSnappingChild) {
-            return;
-        }
-        boolean needToSnap = false;
-        Animator dismissPendingAnim = mDismissPendingMap.get(view);
-        if (dismissPendingAnim != null) {
-            needToSnap = true;
-            dismissPendingAnim.cancel();
-        } else if (getTranslation(view) != 0) {
-            needToSnap = true;
-        }
-        if (needToSnap) {
-            if (animate) {
-                snapChild(view, targetLeft, 0.0f /* velocity */);
-            } else {
-                snapChildInstantly(view);
-            }
-        }
-    }
-
-    public boolean onTouchEvent(MotionEvent ev) {
-        if (mLongPressSent) {
-            return true;
-        }
-
-        if (!mDragging) {
-            if (mCallback.getChildAtPosition(ev) != null) {
-
-                // We are dragging directly over a card, make sure that we also catch the gesture
-                // even if nobody else wants the touch event.
-                onInterceptTouchEvent(ev);
-                 return true;
-            } else {
-
-                // We are not doing anything, make sure the long press callback
-                // is not still ticking like a bomb waiting to go off.
-                removeLongPressCallback();
-                return false;
-            }
-        }
-
-        mVelocityTracker.addMovement(ev);
-        final int action = ev.getAction();
-        switch (action) {
-            case MotionEvent.ACTION_OUTSIDE:
-            case MotionEvent.ACTION_MOVE:
-                if (mCurrView != null) {
-                    float delta = getPos(ev) - mInitialTouchPos;
-                    float absDelta = Math.abs(delta);
-                    if (absDelta >= getFalsingThreshold()) {
-                        mTouchAboveFalsingThreshold = true;
-                    }
-                    // don't let items that can't be dismissed be dragged more than
-                    // maxScrollDistance
-                    if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) {
-                        float size = getSize(mCurrView);
-                        float maxScrollDistance = 0.25f * size;
-                        if (absDelta >= size) {
-                            delta = delta > 0 ? maxScrollDistance : -maxScrollDistance;
-                        } else {
-                            delta = maxScrollDistance * (float) Math.sin((delta/size)*(Math.PI/2));
-                        }
-                    }
-
-                    setTranslation(mCurrView, mTranslation + delta);
-                    updateSwipeProgressFromOffset(mCurrView, mCanCurrViewBeDimissed);
-                    onMoveUpdate(mCurrView, mTranslation + delta, delta);
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                if (mCurrView == null) {
-                    break;
-                }
-                mVelocityTracker.computeCurrentVelocity(1000 /* px/sec */, getMaxVelocity());
-                float velocity = getVelocity(mVelocityTracker);
-
-                if (!handleUpEvent(ev, mCurrView, velocity, getTranslation(mCurrView))) {
-                    if (isDismissGesture(ev)) {
-                        // flingadingy
-                        dismissChild(mCurrView, velocity,
-                                !swipedFastEnough() /* useAccelerateInterpolator */);
-                    } else {
-                        // snappity
-                        mCallback.onDragCancelled(mCurrView);
-                        snapChild(mCurrView, 0 /* leftTarget */, velocity);
-                    }
-                    mCurrView = null;
-                }
-                mDragging = false;
-                break;
-        }
-        return true;
-    }
-
-    private int getFalsingThreshold() {
-        float factor = mCallback.getFalsingThresholdFactor();
-        return (int) (mFalsingThreshold * factor);
-    }
-
-    private float getMaxVelocity() {
-        return MAX_DISMISS_VELOCITY * mDensityScale;
-    }
-
-    protected float getEscapeVelocity() {
-        return getUnscaledEscapeVelocity() * mDensityScale;
-    }
-
-    protected float getUnscaledEscapeVelocity() {
-        return SWIPE_ESCAPE_VELOCITY;
-    }
-
-    protected long getMaxEscapeAnimDuration() {
-        return MAX_ESCAPE_ANIMATION_DURATION;
-    }
-
-    protected boolean swipedFarEnough() {
-        float translation = getTranslation(mCurrView);
-        return DISMISS_IF_SWIPED_FAR_ENOUGH && Math.abs(translation) > 0.4 * getSize(mCurrView);
-    }
-
-    protected boolean isDismissGesture(MotionEvent ev) {
-        boolean falsingDetected = mCallback.isAntiFalsingNeeded() && !mTouchAboveFalsingThreshold;
-        return !falsingDetected && (swipedFastEnough() || swipedFarEnough())
-                && ev.getActionMasked() == MotionEvent.ACTION_UP
-                && mCallback.canChildBeDismissed(mCurrView);
-    }
-
-    protected boolean swipedFastEnough() {
-        float velocity = getVelocity(mVelocityTracker);
-        float translation = getTranslation(mCurrView);
-        boolean ret = (Math.abs(velocity) > getEscapeVelocity())
-                && (velocity > 0) == (translation > 0);
-        return ret;
-    }
-
-    protected boolean handleUpEvent(MotionEvent ev, View animView, float velocity,
-            float translation) {
-        return false;
-    }
-
-    public interface Callback {
-        View getChildAtPosition(MotionEvent ev);
-
-        boolean canChildBeDismissed(View v);
-
-        boolean isAntiFalsingNeeded();
-
-        void onBeginDrag(View v);
-
-        void onChildDismissed(View v);
-
-        void onDragCancelled(View v);
-
-        /**
-         * Called when the child is snapped to a position.
-         *
-         * @param animView the view that was snapped.
-         * @param targetLeft the left position the view was snapped to.
-         */
-        void onChildSnappedBack(View animView, float targetLeft);
-
-        /**
-         * Updates the swipe progress on a child.
-         *
-         * @return if true, prevents the default alpha fading.
-         */
-        boolean updateSwipeProgress(View animView, boolean dismissable, float swipeProgress);
-
-        /**
-         * @return The factor the falsing threshold should be multiplied with
-         */
-        float getFalsingThresholdFactor();
-    }
-
-    /**
-     * Equivalent to View.OnLongClickListener with coordinates
-     */
-    public interface LongPressListener {
-        /**
-         * Equivalent to {@link View.OnLongClickListener#onLongClick(View)} with coordinates
-         * @return whether the longpress was handled
-         */
-        boolean onLongPress(View v, int x, int y);
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index 4dc3c1c..d26f9f6 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -39,12 +39,14 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.config.FeatureFlags;
 
 /**
  * A frame layout which contains a QSB. This internally uses fragment to bind the view, which
  * allows it to contain the logic for {@link Fragment#startActivityForResult(Intent, int)}.
+ *
+ * Note: AppWidgetManagerCompat can be disabled using FeatureFlags. In QSB, we should use
+ * AppWidgetManager directly, so that it keeps working in that case.
  */
 public class QsbContainerView extends FrameLayout {
 
@@ -106,7 +108,7 @@
                 return QsbWidgetHostView.getDefaultView(container);
             }
 
-            AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(activity);
+            AppWidgetManager widgetManager = AppWidgetManager.getInstance(activity);
             InvariantDeviceProfile idp = LauncherAppState.getIDP(activity);
 
             Bundle opts = new Bundle();
@@ -129,7 +131,8 @@
                 }
 
                 widgetId = mQsbWidgetHost.allocateAppWidgetId();
-                isWidgetBound = widgetManager.bindAppWidgetIdIfAllowed(widgetId, mWidgetInfo, opts);
+                isWidgetBound = widgetManager.bindAppWidgetIdIfAllowed(
+                        widgetId, mWidgetInfo.getProfile(), mWidgetInfo.provider, opts);
                 if (!isWidgetBound) {
                     mQsbWidgetHost.deleteAppWidgetId(widgetId);
                     widgetId = -1;
diff --git a/src/com/android/launcher3/touch/OverScroll.java b/src/com/android/launcher3/touch/OverScroll.java
new file mode 100644
index 0000000..dc801ec
--- /dev/null
+++ b/src/com/android/launcher3/touch/OverScroll.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.touch;
+
+/**
+ * Utility methods for overscroll damping and related effect.
+ */
+public class OverScroll {
+
+    private static final float OVERSCROLL_DAMP_FACTOR = 0.07f;
+
+    /**
+     * This curve determines how the effect of scrolling over the limits of the page diminishes
+     * as the user pulls further and further from the bounds
+     *
+     * @param f The percentage of how much the user has overscrolled.
+     * @return A transformed percentage based on the influence curve.
+     */
+    private static float overScrollInfluenceCurve(float f) {
+        f -= 1.0f;
+        return f * f * f + 1.0f;
+    }
+
+    /**
+     * @param amount The original amount overscrolled.
+     * @param max The maximum amount that the View can overscroll.
+     * @return The dampened overscroll amount.
+     */
+    public static int dampedScroll(float amount, int max) {
+        if (Float.compare(amount, 0) == 0) return 0;
+
+        float f = amount / max;
+        f = f / (Math.abs(f)) * (overScrollInfluenceCurve(Math.abs(f)));
+
+        // Clamp this factor, f, to -1 < f < 1
+        if (Math.abs(f) >= 1) {
+            f /= Math.abs(f);
+        }
+
+        return Math.round(OVERSCROLL_DAMP_FACTOR * f * max);
+    }
+}
diff --git a/src/com/android/launcher3/touch/SwipeDetector.java b/src/com/android/launcher3/touch/SwipeDetector.java
new file mode 100644
index 0000000..be4648e
--- /dev/null
+++ b/src/com/android/launcher3/touch/SwipeDetector.java
@@ -0,0 +1,372 @@
+/*
+ * 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.touch;
+
+import static android.view.MotionEvent.INVALID_POINTER_ID;
+import android.content.Context;
+import android.graphics.PointF;
+import android.support.annotation.NonNull;
+import android.support.annotation.VisibleForTesting;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+import android.view.animation.Interpolator;
+
+/**
+ * One dimensional scroll/drag/swipe gesture detector.
+ *
+ * Definition of swipe is different from android system in that this detector handles
+ * 'swipe to dismiss', 'swiping up/down a container' but also keeps scrolling state before
+ * swipe action happens
+ */
+public class SwipeDetector {
+
+    private static final boolean DBG = false;
+    private static final String TAG = "SwipeDetector";
+
+    private int mScrollConditions;
+    public static final int DIRECTION_POSITIVE = 1 << 0;
+    public static final int DIRECTION_NEGATIVE = 1 << 1;
+    public static final int DIRECTION_BOTH = DIRECTION_NEGATIVE | DIRECTION_POSITIVE;
+
+    private static final float ANIMATION_DURATION = 1200;
+    private static final float FAST_FLING_PX_MS = 10;
+
+    protected int mActivePointerId = INVALID_POINTER_ID;
+
+    /**
+     * The minimum release velocity in pixels per millisecond that triggers fling..
+     */
+    public static final float RELEASE_VELOCITY_PX_MS = 1.0f;
+
+    /**
+     * The time constant used to calculate dampening in the low-pass filter of scroll velocity.
+     * Cutoff frequency is set at 10 Hz.
+     */
+    public static final float SCROLL_VELOCITY_DAMPENING_RC = 1000f / (2f * (float) Math.PI * 10);
+
+    /* Scroll state, this is set to true during dragging and animation. */
+    private ScrollState mState = ScrollState.IDLE;
+
+    enum ScrollState {
+        IDLE,
+        DRAGGING,      // onDragStart, onDrag
+        SETTLING       // onDragEnd
+    }
+
+    public static abstract class Direction {
+
+        abstract float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint);
+
+        /**
+         * Distance in pixels a touch can wander before we think the user is scrolling.
+         */
+        abstract float getActiveTouchSlop(MotionEvent ev, int pointerIndex, PointF downPos);
+    }
+
+    public static final Direction VERTICAL = new Direction() {
+
+        @Override
+        float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint) {
+            return ev.getY(pointerIndex) - refPoint.y;
+        }
+
+        @Override
+        float getActiveTouchSlop(MotionEvent ev, int pointerIndex, PointF downPos) {
+            return Math.abs(ev.getX(pointerIndex) - downPos.x);
+        }
+    };
+
+    public static final Direction HORIZONTAL = new Direction() {
+
+        @Override
+        float getDisplacement(MotionEvent ev, int pointerIndex, PointF refPoint) {
+            return ev.getX(pointerIndex) - refPoint.x;
+        }
+
+        @Override
+        float getActiveTouchSlop(MotionEvent ev, int pointerIndex, PointF downPos) {
+            return Math.abs(ev.getY(pointerIndex) - downPos.y);
+        }
+    };
+
+    //------------------- ScrollState transition diagram -----------------------------------
+    //
+    // IDLE ->      (mDisplacement > mTouchSlop) -> DRAGGING
+    // DRAGGING -> (MotionEvent#ACTION_UP, MotionEvent#ACTION_CANCEL) -> SETTLING
+    // SETTLING -> (MotionEvent#ACTION_DOWN) -> DRAGGING
+    // SETTLING -> (View settled) -> IDLE
+
+    private void setState(ScrollState newState) {
+        if (DBG) {
+            Log.d(TAG, "setState:" + mState + "->" + newState);
+        }
+        // onDragStart and onDragEnd is reported ONLY on state transition
+        if (newState == ScrollState.DRAGGING) {
+            initializeDragging();
+            if (mState == ScrollState.IDLE) {
+                reportDragStart(false /* recatch */);
+            } else if (mState == ScrollState.SETTLING) {
+                reportDragStart(true /* recatch */);
+            }
+        }
+        if (newState == ScrollState.SETTLING) {
+            reportDragEnd();
+        }
+
+        mState = newState;
+    }
+
+    public boolean isDraggingOrSettling() {
+        return mState == ScrollState.DRAGGING || mState == ScrollState.SETTLING;
+    }
+
+    /**
+     * There's no touch and there's no animation.
+     */
+    public boolean isIdleState() {
+        return mState == ScrollState.IDLE;
+    }
+
+    public boolean isSettlingState() {
+        return mState == ScrollState.SETTLING;
+    }
+
+    public boolean isDraggingState() {
+        return mState == ScrollState.DRAGGING;
+    }
+
+    private final PointF mDownPos = new PointF();
+    private final PointF mLastPos = new PointF();
+    private final Direction mDir;
+
+    private final float mTouchSlop;
+
+    /* Client of this gesture detector can register a callback. */
+    private final Listener mListener;
+
+    private long mCurrentMillis;
+
+    private float mVelocity;
+    private float mLastDisplacement;
+    private float mDisplacement;
+
+    private float mSubtractDisplacement;
+    private boolean mIgnoreSlopWhenSettling;
+
+    public interface Listener {
+        void onDragStart(boolean start);
+
+        boolean onDrag(float displacement, float velocity);
+
+        void onDragEnd(float velocity, boolean fling);
+    }
+
+    public SwipeDetector(@NonNull Context context, @NonNull Listener l, @NonNull Direction dir) {
+        this(ViewConfiguration.get(context).getScaledTouchSlop(), l, dir);
+    }
+
+    @VisibleForTesting
+    protected SwipeDetector(float touchSlope, @NonNull Listener l, @NonNull Direction dir) {
+        mTouchSlop = touchSlope;
+        mListener = l;
+        mDir = dir;
+    }
+
+    public void setDetectableScrollConditions(int scrollDirectionFlags, boolean ignoreSlop) {
+        mScrollConditions = scrollDirectionFlags;
+        mIgnoreSlopWhenSettling = ignoreSlop;
+    }
+
+    private boolean shouldScrollStart(MotionEvent ev, int pointerIndex) {
+        // reject cases where the angle or slop condition is not met.
+        if (Math.max(mDir.getActiveTouchSlop(ev, pointerIndex, mDownPos), mTouchSlop)
+                > Math.abs(mDisplacement)) {
+            return false;
+        }
+
+        // Check if the client is interested in scroll in current direction.
+        if (((mScrollConditions & DIRECTION_NEGATIVE) > 0 && mDisplacement > 0) ||
+                ((mScrollConditions & DIRECTION_POSITIVE) > 0 && mDisplacement < 0)) {
+            return true;
+        }
+        return false;
+    }
+
+    public boolean onTouchEvent(MotionEvent ev) {
+        switch (ev.getActionMasked()) {
+            case MotionEvent.ACTION_DOWN:
+                mActivePointerId = ev.getPointerId(0);
+                mDownPos.set(ev.getX(), ev.getY());
+                mLastPos.set(mDownPos);
+                mLastDisplacement = 0;
+                mDisplacement = 0;
+                mVelocity = 0;
+
+                if (mState == ScrollState.SETTLING && mIgnoreSlopWhenSettling) {
+                    setState(ScrollState.DRAGGING);
+                }
+                break;
+            //case MotionEvent.ACTION_POINTER_DOWN:
+            case MotionEvent.ACTION_POINTER_UP:
+                int ptrIdx = ev.getActionIndex();
+                int ptrId = ev.getPointerId(ptrIdx);
+                if (ptrId == mActivePointerId) {
+                    final int newPointerIdx = ptrIdx == 0 ? 1 : 0;
+                    mDownPos.set(
+                            ev.getX(newPointerIdx) - (mLastPos.x - mDownPos.x),
+                            ev.getY(newPointerIdx) - (mLastPos.y - mDownPos.y));
+                    mLastPos.set(ev.getX(newPointerIdx), ev.getY(newPointerIdx));
+                    mActivePointerId = ev.getPointerId(newPointerIdx);
+                }
+                break;
+            case MotionEvent.ACTION_MOVE:
+                int pointerIndex = ev.findPointerIndex(mActivePointerId);
+                if (pointerIndex == INVALID_POINTER_ID) {
+                    break;
+                }
+                mDisplacement = mDir.getDisplacement(ev, pointerIndex, mDownPos);
+                computeVelocity(mDir.getDisplacement(ev, pointerIndex, mLastPos),
+                        ev.getEventTime());
+
+                // handle state and listener calls.
+                if (mState != ScrollState.DRAGGING && shouldScrollStart(ev, pointerIndex)) {
+                    setState(ScrollState.DRAGGING);
+                }
+                if (mState == ScrollState.DRAGGING) {
+                    reportDragging();
+                }
+                mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex));
+                break;
+            case MotionEvent.ACTION_CANCEL:
+            case MotionEvent.ACTION_UP:
+                // These are synthetic events and there is no need to update internal values.
+                if (mState == ScrollState.DRAGGING) {
+                    setState(ScrollState.SETTLING);
+                }
+                break;
+            default:
+                break;
+        }
+        return true;
+    }
+
+    public void finishedScrolling() {
+        setState(ScrollState.IDLE);
+    }
+
+    private boolean reportDragStart(boolean recatch) {
+        mListener.onDragStart(!recatch);
+        if (DBG) {
+            Log.d(TAG, "onDragStart recatch:" + recatch);
+        }
+        return true;
+    }
+
+    private void initializeDragging() {
+        if (mState == ScrollState.SETTLING && mIgnoreSlopWhenSettling) {
+            mSubtractDisplacement = 0;
+        }
+        if (mDisplacement > 0) {
+            mSubtractDisplacement = mTouchSlop;
+        } else {
+            mSubtractDisplacement = -mTouchSlop;
+        }
+    }
+
+    private boolean reportDragging() {
+        if (mDisplacement != mLastDisplacement) {
+            if (DBG) {
+                Log.d(TAG, String.format("onDrag disp=%.1f, velocity=%.1f",
+                        mDisplacement, mVelocity));
+            }
+
+            mLastDisplacement = mDisplacement;
+            return mListener.onDrag(mDisplacement - mSubtractDisplacement, mVelocity);
+        }
+        return true;
+    }
+
+    private void reportDragEnd() {
+        if (DBG) {
+            Log.d(TAG, String.format("onScrollEnd disp=%.1f, velocity=%.1f",
+                    mDisplacement, mVelocity));
+        }
+        mListener.onDragEnd(mVelocity, Math.abs(mVelocity) > RELEASE_VELOCITY_PX_MS);
+
+    }
+
+    /**
+     * Computes the damped velocity.
+     */
+    public float computeVelocity(float delta, long currentMillis) {
+        long previousMillis = mCurrentMillis;
+        mCurrentMillis = currentMillis;
+
+        float deltaTimeMillis = mCurrentMillis - previousMillis;
+        float velocity = (deltaTimeMillis > 0) ? (delta / deltaTimeMillis) : 0;
+        if (Math.abs(mVelocity) < 0.001f) {
+            mVelocity = velocity;
+        } else {
+            float alpha = computeDampeningFactor(deltaTimeMillis);
+            mVelocity = interpolate(mVelocity, velocity, alpha);
+        }
+        return mVelocity;
+    }
+
+    /**
+     * Returns a time-dependent dampening factor using delta time.
+     */
+    private static float computeDampeningFactor(float deltaTime) {
+        return deltaTime / (SCROLL_VELOCITY_DAMPENING_RC + deltaTime);
+    }
+
+    /**
+     * Returns the linear interpolation between two values
+     */
+    private static float interpolate(float from, float to, float alpha) {
+        return (1.0f - alpha) * from + alpha * to;
+    }
+
+    public static long calculateDuration(float velocity, float progressNeeded) {
+        // TODO: make these values constants after tuning.
+        float velocityDivisor = Math.max(2f, Math.abs(0.5f * velocity));
+        float travelDistance = Math.max(0.2f, progressNeeded);
+        long duration = (long) Math.max(100, ANIMATION_DURATION / velocityDivisor * travelDistance);
+        if (DBG) {
+            Log.d(TAG, String.format("calculateDuration=%d, v=%f, d=%f", duration, velocity, progressNeeded));
+        }
+        return duration;
+    }
+
+    public static class ScrollInterpolator implements Interpolator {
+
+        boolean mSteeper;
+
+        public void setVelocityAtZero(float velocity) {
+            mSteeper = velocity > FAST_FLING_PX_MS;
+        }
+
+        public float getInterpolation(float t) {
+            t -= 1.0f;
+            float output = t * t * t;
+            if (mSteeper) {
+                output *= t * t; // Make interpolation initial slope steeper
+            }
+            return output + 1;
+        }
+    }
+}
diff --git a/src/com/android/launcher3/util/SettingsObserver.java b/src/com/android/launcher3/util/SettingsObserver.java
new file mode 100644
index 0000000..6baa242
--- /dev/null
+++ b/src/com/android/launcher3/util/SettingsObserver.java
@@ -0,0 +1,100 @@
+/*
+ * 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.ContentResolver;
+import android.database.ContentObserver;
+import android.os.Handler;
+import android.provider.Settings;
+
+public interface SettingsObserver {
+
+    /**
+     * Registers the content observer to call {@link #onSettingChanged(boolean)} when any of the
+     * passed settings change. The value passed to onSettingChanged() is based on the key setting.
+     */
+    void register(String keySetting, String ... dependentSettings);
+    void unregister();
+    void onSettingChanged(boolean keySettingEnabled);
+
+
+    abstract class Secure extends ContentObserver implements SettingsObserver {
+        private ContentResolver mResolver;
+        private String mKeySetting;
+
+        public Secure(ContentResolver resolver) {
+            super(new Handler());
+            mResolver = resolver;
+        }
+
+        @Override
+        public void register(String keySetting, String ... dependentSettings) {
+            mKeySetting = keySetting;
+            mResolver.registerContentObserver(
+                    Settings.Secure.getUriFor(mKeySetting), false, this);
+            for (String setting : dependentSettings) {
+                mResolver.registerContentObserver(
+                        Settings.Secure.getUriFor(setting), false, this);
+            }
+            onChange(true);
+        }
+
+        @Override
+        public void unregister() {
+            mResolver.unregisterContentObserver(this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            onSettingChanged(Settings.Secure.getInt(mResolver, mKeySetting, 1) == 1);
+        }
+    }
+
+    abstract class System extends ContentObserver implements SettingsObserver {
+        private ContentResolver mResolver;
+        private String mKeySetting;
+
+        public System(ContentResolver resolver) {
+            super(new Handler());
+            mResolver = resolver;
+        }
+
+        @Override
+        public void register(String keySetting, String ... dependentSettings) {
+            mKeySetting = keySetting;
+            mResolver.registerContentObserver(
+                    Settings.System.getUriFor(mKeySetting), false, this);
+            for (String setting : dependentSettings) {
+                mResolver.registerContentObserver(
+                        Settings.System.getUriFor(setting), false, this);
+            }
+            onChange(true);
+        }
+
+        @Override
+        public void unregister() {
+            mResolver.unregisterContentObserver(this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            super.onChange(selfChange);
+            onSettingChanged(Settings.System.getInt(mResolver, mKeySetting, 1) == 1);
+        }
+    }
+}
diff --git a/src/com/android/launcher3/util/ViewOnDrawExecutor.java b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
index 4cb6ca8..e5c1dd1 100644
--- a/src/com/android/launcher3/util/ViewOnDrawExecutor.java
+++ b/src/com/android/launcher3/util/ViewOnDrawExecutor.java
@@ -16,11 +16,13 @@
 
 package com.android.launcher3.util;
 
+import android.os.Process;
 import android.view.View;
 import android.view.View.OnAttachStateChangeListener;
 import android.view.ViewTreeObserver.OnDrawListener;
 
 import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherModel;
 
 import java.util.ArrayList;
 import java.util.concurrent.Executor;
@@ -37,6 +39,7 @@
     private Launcher mLauncher;
     private View mAttachedView;
     private boolean mCompleted;
+    private boolean mIsExecuting;
 
     private boolean mLoadAnimationCompleted;
     private boolean mFirstDrawCompleted;
@@ -62,6 +65,7 @@
     @Override
     public void execute(Runnable command) {
         mTasks.add(command);
+        LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_BACKGROUND);
     }
 
     @Override
@@ -78,6 +82,13 @@
         mAttachedView.post(this);
     }
 
+    /**
+     * Returns whether the executor is still queuing tasks and hasn't yet executed them.
+     */
+    public boolean canQueue() {
+        return !mIsExecuting && !mCompleted;
+    }
+
     public void onLoadAnimationCompleted() {
         mLoadAnimationCompleted = true;
         if (mAttachedView != null) {
@@ -89,6 +100,7 @@
     public void run() {
         // Post the pending tasks after both onDraw and onLoadAnimationCompleted have been called.
         if (mLoadAnimationCompleted && mFirstDrawCompleted && !mCompleted) {
+            mIsExecuting = true;
             for (final Runnable r : mTasks) {
                 mExecutor.execute(r);
             }
@@ -99,6 +111,7 @@
     public void markCompleted() {
         mTasks.clear();
         mCompleted = true;
+        mIsExecuting = false;
         if (mAttachedView != null) {
             mAttachedView.getViewTreeObserver().removeOnDrawListener(this);
             mAttachedView.removeOnAttachStateChangeListener(this);
@@ -106,5 +119,6 @@
         if (mLauncher != null) {
             mLauncher.clearPendingExecutor(this);
         }
+        LauncherModel.setWorkerPriority(Process.THREAD_PRIORITY_DEFAULT);
     }
 }
diff --git a/src/com/android/launcher3/widget/WidgetAddFlowHandler.java b/src/com/android/launcher3/widget/WidgetAddFlowHandler.java
index 629f30c..5387be8 100644
--- a/src/com/android/launcher3/widget/WidgetAddFlowHandler.java
+++ b/src/com/android/launcher3/widget/WidgetAddFlowHandler.java
@@ -15,10 +15,8 @@
  */
 package com.android.launcher3.widget;
 
-import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
 import android.content.Context;
-import android.content.Intent;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -26,7 +24,6 @@
 import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
-import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.util.PendingRequestArgs;
 
 /**
@@ -56,15 +53,8 @@
 
     public void startBindFlow(Launcher launcher, int appWidgetId, ItemInfo info, int requestCode) {
         launcher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(appWidgetId, this, info));
-
-        Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
-        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, mProviderInfo.provider);
-        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE,
-                mProviderInfo.getProfile());
-        // TODO: we need to make sure that this accounts for the options bundle.
-        // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
-        launcher.startActivityForResult(intent, requestCode);
+        launcher.getAppWidgetHost()
+                .startBindFlow(launcher, appWidgetId, mProviderInfo, requestCode);
     }
 
     /**
@@ -85,9 +75,7 @@
             return false;
         }
         launcher.setWaitingForResult(PendingRequestArgs.forWidgetInfo(appWidgetId, this, info));
-
-        AppWidgetManagerCompat.getInstance(launcher).startConfigActivity(
-                mProviderInfo, appWidgetId, launcher, launcher.getAppWidgetHost(), requestCode);
+        launcher.getAppWidgetHost().startConfigActivity(launcher, appWidgetId, requestCode);
         return true;
     }
 
diff --git a/src/com/android/launcher3/widget/WidgetsBottomSheet.java b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
index 717a61c..01101ac 100644
--- a/src/com/android/launcher3/widget/WidgetsBottomSheet.java
+++ b/src/com/android/launcher3/widget/WidgetsBottomSheet.java
@@ -40,7 +40,7 @@
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
-import com.android.launcher3.allapps.VerticalPullDetector;
+import com.android.launcher3.touch.SwipeDetector;
 import com.android.launcher3.anim.PropertyListBuilder;
 import com.android.launcher3.dragndrop.DragController;
 import com.android.launcher3.dragndrop.DragOptions;
@@ -58,7 +58,7 @@
  * Bottom sheet for the "Widgets" system shortcut in the long-press popup.
  */
 public class WidgetsBottomSheet extends AbstractFloatingView implements Insettable, TouchController,
-        VerticalPullDetector.Listener, View.OnClickListener, View.OnLongClickListener,
+        SwipeDetector.Listener, View.OnClickListener, View.OnLongClickListener,
         DragController.DragListener {
 
     private int mTranslationYOpen;
@@ -69,9 +69,9 @@
     private ItemInfo mOriginalItemInfo;
     private ObjectAnimator mOpenCloseAnimator;
     private Interpolator mFastOutSlowInInterpolator;
-    private VerticalPullDetector.ScrollInterpolator mScrollInterpolator;
+    private SwipeDetector.ScrollInterpolator mScrollInterpolator;
     private Rect mInsets;
-    private VerticalPullDetector mVerticalPullDetector;
+    private SwipeDetector mSwipeDetector;
     private GradientView mGradientBackground;
 
     public WidgetsBottomSheet(Context context, AttributeSet attrs) {
@@ -85,10 +85,9 @@
         mOpenCloseAnimator = LauncherAnimUtils.ofPropertyValuesHolder(this);
         mFastOutSlowInInterpolator =
                 AnimationUtils.loadInterpolator(context, android.R.interpolator.fast_out_slow_in);
-        mScrollInterpolator = new VerticalPullDetector.ScrollInterpolator();
+        mScrollInterpolator = new SwipeDetector.ScrollInterpolator();
         mInsets = new Rect();
-        mVerticalPullDetector = new VerticalPullDetector(context);
-        mVerticalPullDetector.setListener(this);
+        mSwipeDetector = new SwipeDetector(context, this, SwipeDetector.VERTICAL);
         mGradientBackground = (GradientView) mLauncher.getLayoutInflater().inflate(
                 R.layout.gradient_bg, mLauncher.getDragLayer(), false);
     }
@@ -195,7 +194,7 @@
             mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
-                    mVerticalPullDetector.finishedScrolling();
+                    mSwipeDetector.finishedScrolling();
                 }
             });
             mOpenCloseAnimator.setInterpolator(mFastOutSlowInInterpolator);
@@ -216,11 +215,11 @@
             mOpenCloseAnimator.addListener(new AnimatorListenerAdapter() {
                 @Override
                 public void onAnimationEnd(Animator animation) {
-                    mVerticalPullDetector.finishedScrolling();
+                    mSwipeDetector.finishedScrolling();
                     onCloseComplete();
                 }
             });
-            mOpenCloseAnimator.setInterpolator(mVerticalPullDetector.isIdleState()
+            mOpenCloseAnimator.setInterpolator(mSwipeDetector.isIdleState()
                     ? mFastOutSlowInInterpolator : mScrollInterpolator);
             mOpenCloseAnimator.start();
         } else {
@@ -265,7 +264,7 @@
                 getPaddingRight() + rightInset, getPaddingBottom() + bottomInset);
     }
 
-    /* VerticalPullDetector.Listener */
+    /* SwipeDetector.Listener */
 
     @Override
     public void onDragStart(boolean start) {
@@ -291,12 +290,12 @@
     public void onDragEnd(float velocity, boolean fling) {
         if ((fling && velocity > 0) || getTranslationY() > (mTranslationYRange) / 2) {
             mScrollInterpolator.setVelocityAtZero(velocity);
-            mOpenCloseAnimator.setDuration(mVerticalPullDetector.calculateDuration(velocity,
+            mOpenCloseAnimator.setDuration(SwipeDetector.calculateDuration(velocity,
                     (mTranslationYClosed - getTranslationY()) / mTranslationYRange));
             close(true);
         } else {
             mIsOpen = false;
-            mOpenCloseAnimator.setDuration(mVerticalPullDetector.calculateDuration(velocity,
+            mOpenCloseAnimator.setDuration(SwipeDetector.calculateDuration(velocity,
                     (getTranslationY() - mTranslationYOpen) / mTranslationYRange));
             open(true);
         }
@@ -304,17 +303,17 @@
 
     @Override
     public boolean onControllerTouchEvent(MotionEvent ev) {
-        return mVerticalPullDetector.onTouchEvent(ev);
+        return mSwipeDetector.onTouchEvent(ev);
     }
 
     @Override
     public boolean onControllerInterceptTouchEvent(MotionEvent ev) {
-        int directionsToDetectScroll = mVerticalPullDetector.isIdleState() ?
-                VerticalPullDetector.DIRECTION_DOWN : 0;
-        mVerticalPullDetector.setDetectableScrollConditions(
+        int directionsToDetectScroll = mSwipeDetector.isIdleState() ?
+                SwipeDetector.DIRECTION_NEGATIVE : 0;
+        mSwipeDetector.setDetectableScrollConditions(
                 directionsToDetectScroll, false);
-        mVerticalPullDetector.onTouchEvent(ev);
-        return mVerticalPullDetector.isDraggingOrSettling();
+        mSwipeDetector.onTouchEvent(ev);
+        return mSwipeDetector.isDraggingOrSettling();
     }
 
     /* DragListener */
diff --git a/src_flags/com/android/launcher3/config/FeatureFlags.java b/src_flags/com/android/launcher3/config/FeatureFlags.java
index 42a110c..3ffb6c9 100644
--- a/src_flags/com/android/launcher3/config/FeatureFlags.java
+++ b/src_flags/com/android/launcher3/config/FeatureFlags.java
@@ -19,48 +19,7 @@
 /**
  * Defines a set of flags used to control various launcher behaviors
  */
-public final class FeatureFlags {
-
-    public static final boolean IS_DOGFOOD_BUILD = true;
+public final class FeatureFlags extends BaseFlags {
 
     private FeatureFlags() {}
-
-    // Custom flags go below this
-    public static boolean LAUNCHER3_DISABLE_ICON_NORMALIZATION = false;
-    public static boolean LAUNCHER3_LEGACY_FOLDER_ICON = false;
-    public static boolean LAUNCHER3_USE_SYSTEM_DRAG_DRIVER = true;
-    public static boolean LAUNCHER3_DISABLE_PINCH_TO_OVERVIEW = false;
-    public static boolean LAUNCHER3_ALL_APPS_PULL_UP = true;
-    public static boolean LAUNCHER3_NEW_FOLDER_ANIMATION = true;
-    // When enabled allows to use any point on the fast scrollbar to start dragging.
-    public static boolean LAUNCHER3_DIRECT_SCROLL = true;
-    // When enabled while all-apps open, the soft input will be set to adjust resize .
-    public static boolean LAUNCHER3_UPDATE_SOFT_INPUT_MODE = true;
-    // When enabled the promise icon is visible in all apps while installation an app.
-    public static boolean LAUNCHER3_PROMISE_APPS_IN_ALL_APPS = false;
-    // When enabled uses the AllAppsRadialGradientAndScrimDrawable for all apps
-    public static boolean LAUNCHER3_GRADIENT_ALL_APPS = true;
-    // When enabled allows use of physics based motions in the Launcher.
-    public static boolean LAUNCHER3_PHYSICS = true;
-    // When enabled allows use of spring motions on the icons.
-    public static boolean LAUNCHER3_SPRING_ICONS = true;
-
-    // Feature flag to enable moving the QSB on the 0th screen of the workspace.
-    public static final boolean QSB_ON_FIRST_SCREEN = true;
-    // When enabled the all-apps icon is not added to the hotseat.
-    public static final boolean NO_ALL_APPS_ICON = true;
-    // When enabled fling down gesture on the first workspace triggers search.
-    public static final boolean PULLDOWN_SEARCH = false;
-    // When enabled the status bar may show dark icons based on the top of the wallpaper.
-    public static final boolean LIGHT_STATUS_BAR = false;
-    // When enabled icons are badged with the number of notifications associated with that app.
-    public static final boolean BADGE_ICONS = true;
-    // When enabled, icons not supporting {@link AdaptiveIconDrawable} will be wrapped in {@link FixedScaleDrawable}.
-    public static final boolean LEGACY_ICON_TREATMENT = true;
-    // When enabled, adaptive icons would have shadows baked when being stored to icon cache.
-    public static final boolean ADAPTIVE_ICON_SHADOW = true;
-    // When enabled, app discovery will be enabled if service is implemented
-    public static final boolean DISCOVERY_ENABLED = false;
-    // When enabled, the qsb will be moved to the hotseat.
-    public static final boolean QSB_IN_HOTSEAT = true;
 }
diff --git a/tests/src/com/android/launcher3/InvariantDeviceProfileTest.java b/tests/src/com/android/launcher3/InvariantDeviceProfileTest.java
deleted file mode 100644
index 230d623..0000000
--- a/tests/src/com/android/launcher3/InvariantDeviceProfileTest.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3;
-
-import android.content.res.Resources;
-import android.graphics.Point;
-import android.graphics.PointF;
-import android.graphics.Rect;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import java.util.ArrayList;
-
-/**
- * Tests the {@link DeviceProfile} and {@link InvariantDeviceProfile}.
- */
-@SmallTest
-public class InvariantDeviceProfileTest extends AndroidTestCase {
-
-    private static final String TAG = "DeviceProfileTest";
-    private static final boolean DEBUG = false;
-
-    private InvariantDeviceProfile mInvariantProfile;
-    private ArrayList<InvariantDeviceProfile> mPredefinedDeviceProfiles;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mInvariantProfile = new InvariantDeviceProfile(getContext());
-        mPredefinedDeviceProfiles = mInvariantProfile.getPredefinedDeviceProfiles(getContext());
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        // Nothing to tear down as this class only tests static methods.
-    }
-
-    public void testFindClosestDeviceProfile2() {
-        for (InvariantDeviceProfile idf: mPredefinedDeviceProfiles) {
-            ArrayList<InvariantDeviceProfile> predefinedProfilesCopy =
-                    new ArrayList<>(mPredefinedDeviceProfiles);
-            ArrayList<InvariantDeviceProfile> closestProfiles =
-                    mInvariantProfile.findClosestDeviceProfiles(
-                            idf.minWidthDps, idf.minHeightDps, predefinedProfilesCopy
-                    );
-            assertTrue(closestProfiles.get(0).equals(idf));
-        }
-    }
-
-    /**
-     * Used to print out how the invDistWeightedInterpolate works between device profiles to
-     * tweak the two constants that control how the interpolation curve is shaped.
-     */
-    public void testInvInterpolation() {
-
-        InvariantDeviceProfile p1 = mPredefinedDeviceProfiles.get(7); // e.g., Large Phone
-        InvariantDeviceProfile p2 = mPredefinedDeviceProfiles.get(8); // e.g., Nexus 7
-
-        ArrayList<PointF> pts = createInterpolatedPoints(
-                new PointF(p1.minWidthDps, p1.minHeightDps),
-                new PointF(p2.minWidthDps, p2.minHeightDps),
-                20f);
-
-        for (int i = 0; i < pts.size(); i++) {
-            ArrayList<InvariantDeviceProfile> closestProfiles =
-                    mInvariantProfile.findClosestDeviceProfiles(
-                            pts.get(i).x, pts.get(i).y, mPredefinedDeviceProfiles);
-            InvariantDeviceProfile result =
-                    mInvariantProfile.invDistWeightedInterpolate(
-                            pts.get(i).x, pts.get(i).y, closestProfiles);
-            if (DEBUG) {
-                Log.d(TAG, String.format("width x height = (%f, %f)] iconSize = %f",
-                        pts.get(i).x, pts.get(i).y, result.iconSize));
-            }
-        }
-    }
-
-    private ArrayList<PointF> createInterpolatedPoints(PointF a, PointF b, float numPts) {
-        ArrayList<PointF> result = new ArrayList<PointF>();
-        result.add(a);
-        for (float i = 1; i < numPts; i = i + 1.0f) {
-            result.add(new PointF((b.x * i +  a.x * (numPts - i)) / numPts,
-                    (b.y * i + a.y * (numPts - i)) / numPts));
-        }
-        result.add(b);
-        return result;
-    }
-
-    /**
-     * Ensures that system calls (e.g., WindowManager, DisplayMetrics) that require contexts are
-     * properly working to generate minimum width and height of the display.
-     */
-    public void test_hammerhead() {
-        if (!android.os.Build.DEVICE.equals("hammerhead")) {
-            return;
-        }
-        assertEquals(4, mInvariantProfile.numRows);
-        assertEquals(4, mInvariantProfile.numColumns);
-        assertEquals(5, mInvariantProfile.numHotseatIcons);
-    }
-
-    // Add more tests for other devices, however, running them once on a single device is enough
-    // for verifying that for a platform version, the WindowManager and DisplayMetrics is
-    // working as intended.
-}
diff --git a/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
index 26ec69b..846a163 100644
--- a/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
+++ b/tests/src/com/android/launcher3/allapps/search/DefaultAppSearchAlgorithmTest.java
@@ -16,85 +16,78 @@
 package com.android.launcher3.allapps.search;
 
 import android.content.ComponentName;
-import android.test.InstrumentationTestCase;
+import android.support.test.runner.AndroidJUnit4;
 
 import com.android.launcher3.AppInfo;
 import com.android.launcher3.Utilities;
 
-import java.util.ArrayList;
-import java.util.List;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Unit tests for {@link DefaultAppSearchAlgorithm}
  */
-public class DefaultAppSearchAlgorithmTest extends InstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class DefaultAppSearchAlgorithmTest {
+    private static final DefaultAppSearchAlgorithm.StringMatcher MATCHER =
+            DefaultAppSearchAlgorithm.StringMatcher.getInstance();
 
-    private List<AppInfo> mAppsList;
-    private DefaultAppSearchAlgorithm mAlgorithm;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mAppsList = new ArrayList<>();
-        getInstrumentation().runOnMainSync(new Runnable() {
-            @Override
-            public void run() {
-                mAlgorithm = new DefaultAppSearchAlgorithm(mAppsList);
-            }
-        });
-    }
-
+    @Test
     public void testMatches() {
-        assertTrue(mAlgorithm.matches(getInfo("white cow"), "cow"));
-        assertTrue(mAlgorithm.matches(getInfo("whiteCow"), "cow"));
-        assertTrue(mAlgorithm.matches(getInfo("whiteCOW"), "cow"));
-        assertTrue(mAlgorithm.matches(getInfo("whitecowCOW"), "cow"));
-        assertTrue(mAlgorithm.matches(getInfo("white2cow"), "cow"));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("white cow"), "cow", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whiteCow"), "cow", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whiteCOW"), "cow", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whitecowCOW"), "cow", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("white2cow"), "cow", MATCHER));
 
-        assertFalse(mAlgorithm.matches(getInfo("whitecow"), "cow"));
-        assertFalse(mAlgorithm.matches(getInfo("whitEcow"), "cow"));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("whitecow"), "cow", MATCHER));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("whitEcow"), "cow", MATCHER));
 
-        assertTrue(mAlgorithm.matches(getInfo("whitecowCow"), "cow"));
-        assertTrue(mAlgorithm.matches(getInfo("whitecow cow"), "cow"));
-        assertFalse(mAlgorithm.matches(getInfo("whitecowcow"), "cow"));
-        assertFalse(mAlgorithm.matches(getInfo("whit ecowcow"), "cow"));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whitecowCow"), "cow", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("whitecow cow"), "cow", MATCHER));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("whitecowcow"), "cow", MATCHER));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("whit ecowcow"), "cow", MATCHER));
 
-        assertTrue(mAlgorithm.matches(getInfo("cats&dogs"), "dog"));
-        assertTrue(mAlgorithm.matches(getInfo("cats&Dogs"), "dog"));
-        assertTrue(mAlgorithm.matches(getInfo("cats&Dogs"), "&"));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("cats&dogs"), "dog", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("cats&Dogs"), "dog", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("cats&Dogs"), "&", MATCHER));
 
-        assertTrue(mAlgorithm.matches(getInfo("2+43"), "43"));
-        assertFalse(mAlgorithm.matches(getInfo("2+43"), "3"));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("2+43"), "43", MATCHER));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("2+43"), "3", MATCHER));
 
-        assertTrue(mAlgorithm.matches(getInfo("Q"), "q"));
-        assertTrue(mAlgorithm.matches(getInfo("  Q"), "q"));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("Q"), "q", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("  Q"), "q", MATCHER));
 
         // match lower case words
-        assertTrue(mAlgorithm.matches(getInfo("elephant"), "e"));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("elephant"), "e", MATCHER));
 
-        assertTrue(mAlgorithm.matches(getInfo("电子邮件"), "电"));
-        assertTrue(mAlgorithm.matches(getInfo("电子邮件"), "电子"));
-        assertFalse(mAlgorithm.matches(getInfo("电子邮件"), "子"));
-        assertFalse(mAlgorithm.matches(getInfo("电子邮件"), "邮件"));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("电子邮件"), "电", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("电子邮件"), "电子", MATCHER));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("电子邮件"), "子", MATCHER));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("电子邮件"), "邮件", MATCHER));
 
-        assertFalse(mAlgorithm.matches(getInfo("Bot"), "ba"));
-        assertFalse(mAlgorithm.matches(getInfo("bot"), "ba"));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("Bot"), "ba", MATCHER));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("bot"), "ba", MATCHER));
     }
 
+    @Test
     public void testMatchesVN() {
         if (!Utilities.ATLEAST_NOUGAT) {
             return;
         }
-        assertTrue(mAlgorithm.matches(getInfo("다운로드"), "다"));
-        assertTrue(mAlgorithm.matches(getInfo("드라이브"), "드"));
-        assertTrue(mAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷ"));
-        assertTrue(mAlgorithm.matches(getInfo("운로 드라이브"), "ㄷ"));
-        assertTrue(mAlgorithm.matches(getInfo("abc"), "åbç"));
-        assertTrue(mAlgorithm.matches(getInfo("Alpha"), "ål"));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("다운로드"), "다", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("드라이브"), "드", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷ", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("운로 드라이브"), "ㄷ", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("abc"), "åbç", MATCHER));
+        assertTrue(DefaultAppSearchAlgorithm.matches(getInfo("Alpha"), "ål", MATCHER));
 
-        assertFalse(mAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷㄷ"));
-        assertFalse(mAlgorithm.matches(getInfo("로드라이브"), "ㄷ"));
-        assertFalse(mAlgorithm.matches(getInfo("abc"), "åç"));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("다운로드 드라이브"), "ㄷㄷ", MATCHER));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("로드라이브"), "ㄷ", MATCHER));
+        assertFalse(DefaultAppSearchAlgorithm.matches(getInfo("abc"), "åç", MATCHER));
     }
 
     private AppInfo getInfo(String title) {
diff --git a/tests/src/com/android/launcher3/logging/FileLogTest.java b/tests/src/com/android/launcher3/logging/FileLogTest.java
index c24cc3f..7048c28 100644
--- a/tests/src/com/android/launcher3/logging/FileLogTest.java
+++ b/tests/src/com/android/launcher3/logging/FileLogTest.java
@@ -37,6 +37,9 @@
     }
 
     public void testPrintLog() throws Exception {
+        if (!FileLog.ENABLED) {
+            return;
+        }
         FileLog.print("Testing", "hoolalala");
         StringWriter writer = new StringWriter();
         FileLog.flushAll(new PrintWriter(writer));
@@ -54,6 +57,9 @@
     }
 
     public void testOldFileTruncated() throws Exception {
+        if (!FileLog.ENABLED) {
+            return;
+        }
         FileLog.print("Testing", "hoolalala");
         StringWriter writer = new StringWriter();
         FileLog.flushAll(new PrintWriter(writer));
diff --git a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
index 4c80902..ae15f08 100644
--- a/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
+++ b/tests/src/com/android/launcher3/model/AddWorkspaceItemsTaskTest.java
@@ -20,9 +20,9 @@
 import org.mockito.ArgumentCaptor;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
+import static org.mockito.Matchers.isNull;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -131,7 +131,7 @@
         // only info2 should be added because info was already added to the workspace
         // in setupWorkspaceWithHoles()
         verify(callbacks).bindAppsAdded(any(ArrayList.class), notAnimated.capture(),
-                animated.capture(), any(ArrayList.class));
+                animated.capture(), isNull(ArrayList.class));
         assertTrue(notAnimated.getValue().isEmpty());
 
         assertEquals(1, animated.getValue().size());
diff --git a/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java b/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java
new file mode 100644
index 0000000..80d6341
--- /dev/null
+++ b/tests/src/com/android/launcher3/testcomponent/TouchEventGenerator.java
@@ -0,0 +1,275 @@
+/*
+ * 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.testcomponent;
+
+import android.graphics.Point;
+import android.util.Pair;
+import android.view.InputDevice;
+import android.view.MotionEvent;
+import android.view.MotionEvent.PointerCoords;
+import android.view.MotionEvent.PointerProperties;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Utility class to generate MotionEvent event sequences for testing touch gesture detectors.
+ */
+public class TouchEventGenerator {
+
+    /**
+     * Amount of time between two generated events.
+     */
+    private static final long TIME_INCREMENT_MS = 20L;
+
+    /**
+     * Id of the fake device generating the events.
+     */
+    private static final int DEVICE_ID = 2104;
+
+    /**
+     * The fingers currently present on the emulated touch screen.
+     */
+    private Map<Integer, Point> mFingers;
+
+    /**
+     * Initial event time for the current sequence.
+     */
+    private long mInitialTime;
+
+    /**
+     * Time of the last generated event.
+     */
+    private long mLastEventTime;
+
+    /**
+     * Time of the next event.
+     */
+    private long mTime;
+
+    /**
+     * Receives the generated events.
+     */
+    public interface Listener {
+
+        /**
+         * Called when an event was generated.
+         */
+        void onTouchEvent(MotionEvent event);
+    }
+    private final Listener mListener;
+
+    public TouchEventGenerator(Listener listener) {
+        mListener = listener;
+        mFingers = new HashMap<Integer, Point>();
+    }
+
+    /**
+     * Adds a finger on the touchscreen.
+     */
+    public TouchEventGenerator put(int id, int x, int y, long ms) {
+        checkFingerExistence(id, false);
+        boolean isInitialDown = mFingers.isEmpty();
+        mFingers.put(id, new Point(x, y));
+        int action;
+        if (isInitialDown) {
+            action = MotionEvent.ACTION_DOWN;
+        } else {
+            action = MotionEvent.ACTION_POINTER_DOWN;
+            // Set the id of the changed pointer.
+            action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+        }
+        generateEvent(action, ms);
+        return this;
+    }
+
+    /**
+     * Adds a finger on the touchscreen after advancing default time interval.
+     */
+    public TouchEventGenerator put(int id, int x, int y) {
+        return put(id, x, y, TIME_INCREMENT_MS);
+    }
+
+    /**
+     * Adjusts the position of a finger for an upcoming move event.
+     *
+     * @see #move(long ms)
+     */
+    public TouchEventGenerator position(int id, int x, int y) {
+        checkFingerExistence(id, true);
+        mFingers.get(id).set(x, y);
+        return this;
+    }
+
+    /**
+     * Commits the finger position changes of {@link #position(int, int, int)} by generating a move
+     * event.
+     *
+     * @see #position(int, int, int)
+     */
+    public TouchEventGenerator move(long ms) {
+        generateEvent(MotionEvent.ACTION_MOVE, ms);
+        return this;
+    }
+
+    /**
+     * Commits the finger position changes of {@link #position(int, int, int)} by generating a move
+     * event after advancing the default time interval.
+     *
+     * @see #position(int, int, int)
+     */
+    public TouchEventGenerator move() {
+        return move(TIME_INCREMENT_MS);
+    }
+
+    /**
+     * Moves a single finger on the touchscreen.
+     */
+    public TouchEventGenerator move(int id, int x, int y, long ms) {
+        return position(id, x, y).move(ms);
+    }
+
+    /**
+     * Moves a single finger on the touchscreen after advancing default time interval.
+     */
+    public TouchEventGenerator move(int id, int x, int y) {
+        return move(id, x, y, TIME_INCREMENT_MS);
+    }
+
+    /**
+     * Removes an existing finger from the touchscreen.
+     */
+    public TouchEventGenerator lift(int id, long ms) {
+        checkFingerExistence(id, true);
+        boolean isFinalUp = mFingers.size() == 1;
+        int action;
+        if (isFinalUp) {
+            action = MotionEvent.ACTION_UP;
+        } else {
+            action = MotionEvent.ACTION_POINTER_UP;
+            // Set the id of the changed pointer.
+            action |= id << MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+        }
+        generateEvent(action, ms);
+        mFingers.remove(id);
+        return this;
+    }
+
+    /**
+     * Removes a finger from the touchscreen.
+     */
+    public TouchEventGenerator lift(int id, int x, int y, long ms) {
+        checkFingerExistence(id, true);
+        mFingers.get(id).set(x, y);
+        return lift(id, ms);
+    }
+
+    /**
+     * Removes an existing finger from the touchscreen after advancing default time interval.
+     */
+    public TouchEventGenerator lift(int id) {
+        return lift(id, TIME_INCREMENT_MS);
+    }
+
+    /**
+     * Cancels an ongoing sequence.
+     */
+    public TouchEventGenerator cancel(long ms) {
+        generateEvent(MotionEvent.ACTION_CANCEL, ms);
+        mFingers.clear();
+        return this;
+    }
+
+    /**
+     * Cancels an ongoing sequence.
+     */
+    public TouchEventGenerator cancel() {
+        return cancel(TIME_INCREMENT_MS);
+    }
+
+    private void checkFingerExistence(int id, boolean shouldExist) {
+        if (shouldExist != mFingers.containsKey(id)) {
+            throw new IllegalArgumentException(
+                    shouldExist ? "Finger does not exist" : "Finger already exists");
+        }
+    }
+
+    private void generateEvent(int action, long ms) {
+        mTime = mLastEventTime + ms;
+        Pair<PointerProperties[], PointerCoords[]> state = getFingerState();
+        MotionEvent event = MotionEvent.obtain(
+                mInitialTime,
+                mTime,
+                action,
+                state.first.length,
+                state.first,
+                state.second,
+                0 /* metaState */,
+                0 /* buttonState */,
+                1.0f /* xPrecision */,
+                1.0f /* yPrecision */,
+                DEVICE_ID,
+                0 /* edgeFlags */,
+                InputDevice.SOURCE_TOUCHSCREEN,
+                0 /* flags */);
+        mListener.onTouchEvent(event);
+        if (action == MotionEvent.ACTION_UP) {
+            resetTime();
+        }
+        event.recycle();
+        mLastEventTime = mTime;
+    }
+
+    /**
+     * Returns the description of the fingers' state expected by MotionEvent.
+     */
+    private Pair<PointerProperties[], PointerCoords[]> getFingerState() {
+        int nFingers = mFingers.size();
+        PointerProperties[] properties = new PointerProperties[nFingers];
+        PointerCoords[] coordinates = new PointerCoords[nFingers];
+
+        int index = 0;
+        for (Map.Entry<Integer, Point> entry : mFingers.entrySet()) {
+            int id = entry.getKey();
+            Point location = entry.getValue();
+
+            PointerProperties property = new PointerProperties();
+            property.id = id;
+            property.toolType = MotionEvent.TOOL_TYPE_FINGER;
+            properties[index] = property;
+
+            PointerCoords coordinate = new PointerCoords();
+            coordinate.x = location.x;
+            coordinate.y = location.y;
+            coordinate.pressure = 1.0f;
+            coordinates[index] = coordinate;
+
+            index++;
+        }
+
+        return new Pair<MotionEvent.PointerProperties[], MotionEvent.PointerCoords[]>(
+                properties, coordinates);
+    }
+
+    /**
+     * Resets the time references for a new sequence.
+     */
+    private void resetTime() {
+        mInitialTime = 0L;
+        mLastEventTime = -1L;
+        mTime = 0L;
+    }
+}
diff --git a/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java b/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java
new file mode 100644
index 0000000..ff83131
--- /dev/null
+++ b/tests/src/com/android/launcher3/touch/SwipeDetectorTest.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.touch;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import com.android.launcher3.testcomponent.TouchEventGenerator;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyFloat;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class SwipeDetectorTest {
+
+    private static final String TAG = SwipeDetectorTest.class.getSimpleName();
+    public static void L(String s, Object... parts) {
+        Log.d(TAG, (parts.length == 0) ? s : String.format(s, parts));
+    }
+
+    private TouchEventGenerator mGenerator;
+    private SwipeDetector mDetector;
+    private int mTouchSlop;
+
+    @Mock
+    private SwipeDetector.Listener mMockListener;
+
+    @Before
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+        mGenerator = new TouchEventGenerator(new TouchEventGenerator.Listener() {
+            @Override
+            public void onTouchEvent(MotionEvent event) {
+                mDetector.onTouchEvent(event);
+            }
+        });
+
+        mDetector = new SwipeDetector(mTouchSlop, mMockListener, SwipeDetector.VERTICAL);
+        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false);
+        mTouchSlop = ViewConfiguration.get(InstrumentationRegistry.getTargetContext())
+                .getScaledTouchSlop();
+        L("mTouchSlop=", mTouchSlop);
+    }
+
+    @Test
+    public void testDragStart_vertical() throws Exception {
+        mGenerator.put(0, 100, 100);
+        mGenerator.move(0, 100, 100 + mTouchSlop);
+        // TODO: actually calculate the following parameters and do exact value checks.
+        verify(mMockListener).onDragStart(anyBoolean());
+    }
+
+    @Test
+    public void testDragStart_failed() throws Exception {
+        mGenerator.put(0, 100, 100);
+        mGenerator.move(0, 100 + mTouchSlop, 100);
+        // TODO: actually calculate the following parameters and do exact value checks.
+        verify(mMockListener, never()).onDragStart(anyBoolean());
+    }
+
+    @Test
+    public void testDragStart_horizontal() throws Exception {
+        mDetector = new SwipeDetector(mTouchSlop, mMockListener, SwipeDetector.HORIZONTAL);
+        mDetector.setDetectableScrollConditions(SwipeDetector.DIRECTION_BOTH, false);
+
+        mGenerator.put(0, 100, 100);
+        mGenerator.move(0, 100 + mTouchSlop, 100);
+        // TODO: actually calculate the following parameters and do exact value checks.
+        verify(mMockListener).onDragStart(anyBoolean());
+    }
+
+    @Test
+    public void testDrag() throws Exception {
+        mGenerator.put(0, 100, 100);
+        mGenerator.move(0, 100, 100 + mTouchSlop);
+        // TODO: actually calculate the following parameters and do exact value checks.
+        verify(mMockListener).onDrag(anyFloat(), anyFloat());
+    }
+
+    @Test
+    public void testDragEnd() throws Exception {
+        mGenerator.put(0, 100, 100);
+        mGenerator.move(0, 100, 100 + mTouchSlop);
+        mGenerator.move(0, 100, 100 + mTouchSlop * 2);
+        mGenerator.lift(0);
+        // TODO: actually calculate the following parameters and do exact value checks.
+        verify(mMockListener).onDragEnd(anyFloat(), anyBoolean());
+    }
+}
diff --git a/tests/src/com/android/launcher3/ui/LauncherInstrumentationTestCase.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
similarity index 80%
rename from tests/src/com/android/launcher3/ui/LauncherInstrumentationTestCase.java
rename to tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 47b43f5..7fb5d85 100644
--- a/tests/src/com/android/launcher3/ui/LauncherInstrumentationTestCase.java
+++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -15,29 +15,26 @@
  */
 package com.android.launcher3.ui;
 
+import android.app.Instrumentation;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
+import android.content.pm.LauncherActivityInfo;
 import android.graphics.Point;
-import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.SystemClock;
+import android.support.test.InstrumentationRegistry;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.BySelector;
 import android.support.test.uiautomator.Direction;
 import android.support.test.uiautomator.UiDevice;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
-import android.test.InstrumentationTestCase;
 import android.view.MotionEvent;
 
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppState;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.LauncherSettings;
@@ -45,25 +42,26 @@
 import com.android.launcher3.R;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
+import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.testcomponent.AppWidgetNoConfig;
 import com.android.launcher3.testcomponent.AppWidgetWithConfig;
 import com.android.launcher3.util.ManagedProfileHeuristic;
 
-import java.io.BufferedReader;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.util.ArrayList;
+import org.junit.Before;
+
 import java.util.Locale;
 import java.util.concurrent.Callable;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
 /**
  * Base class for all instrumentation tests providing various utility methods.
  */
-public class LauncherInstrumentationTestCase extends InstrumentationTestCase {
+public abstract class AbstractLauncherUiTest {
 
     public static final long DEFAULT_ACTIVITY_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
     public static final long DEFAULT_BROADCAST_TIMEOUT_SECS = 5;
@@ -71,16 +69,15 @@
     public static final long DEFAULT_UI_TIMEOUT = 3000;
     public static final long DEFAULT_WORKER_TIMEOUT_SECS = 5;
 
+    protected MainThreadExecutor mMainThreadExecutor = new MainThreadExecutor();
     protected UiDevice mDevice;
     protected Context mTargetContext;
     protected String mTargetPackage;
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
+    @Before
+    public void setUp() throws Exception {
         mDevice = UiDevice.getInstance(getInstrumentation());
-        mTargetContext = getInstrumentation().getTargetContext();
+        mTargetContext = InstrumentationRegistry.getTargetContext();
         mTargetPackage = mTargetContext.getPackageName();
     }
 
@@ -97,56 +94,15 @@
         }
     }
 
-    /**
-     * Starts the launcher activity in the target package and returns the Launcher instance.
-     */
-    protected Launcher startLauncher() {
-        return (Launcher) getInstrumentation().startActivitySync(getHomeIntent());
-    }
-
-    protected Intent getHomeIntent() {
-        return new Intent(Intent.ACTION_MAIN)
-                .addCategory(Intent.CATEGORY_HOME)
-                .setPackage(mTargetPackage)
-                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-    }
-
-    /**
-     * Grants the launcher permission to bind widgets.
-     */
-    protected void grantWidgetPermission() throws IOException {
-        // Check bind widget permission
-        if (mTargetContext.getPackageManager().checkPermission(
-                mTargetPackage, android.Manifest.permission.BIND_APPWIDGET)
-                != PackageManager.PERMISSION_GRANTED) {
-            runShellCommand("appwidget grantbind --package " + mTargetPackage);
-        }
-    }
-
-    /**
-     * Sets the target launcher as default launcher.
-     */
-    protected void setDefaultLauncher() throws IOException {
-        ActivityInfo launcher = mTargetContext.getPackageManager()
-                .queryIntentActivities(getHomeIntent(), 0).get(0).activityInfo;
-        runShellCommand("cmd package set-home-activity " +
-                new ComponentName(launcher.packageName, launcher.name).flattenToString());
-    }
-
-    protected void runShellCommand(String command) throws IOException {
-        ParcelFileDescriptor pfd = getInstrumentation().getUiAutomation()
-                .executeShellCommand(command);
-
-        // Read the input stream fully.
-        FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
-        while (fis.read() != -1);
-        fis.close();
+    protected Instrumentation getInstrumentation() {
+        return InstrumentationRegistry.getInstrumentation();
     }
 
     /**
      * Opens all apps and returns the recycler view
      */
     protected UiObject2 openAllApps() {
+        mDevice.waitForIdle();
         if (FeatureFlags.LAUNCHER3_ALL_APPS_PULL_UP) {
             // clicking on the page indicator brings up all apps tray on non tablets.
             findViewById(R.id.page_indicator).click();
@@ -262,7 +218,7 @@
 
     protected void resetLoaderState() {
         try {
-            runTestOnUiThread(new Runnable() {
+            mMainThreadExecutor.execute(new Runnable() {
                 @Override
                 public void run() {
                     ManagedProfileHeuristic.markExistingUsersForNoFolderCreation(mTargetContext);
@@ -279,7 +235,7 @@
      */
     protected <T> T getOnUiThread(final Callable<T> callback) {
         try {
-            return new MainThreadExecutor().submit(callback).get();
+            return mMainThreadExecutor.submit(callback).get();
         } catch (Exception e) {
             throw new RuntimeException(e);
         }
@@ -315,6 +271,10 @@
         return By.res(mTargetPackage, name);
     }
 
+    protected LauncherActivityInfo getSettingsApp() {
+        return LauncherAppsCompat.getInstance(mTargetContext)
+                .getActivityList("com.android.settings", Process.myUserHandle()).get(0);
+    }
 
     /**
      * Broadcast receiver which blocks until the result is received.
diff --git a/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java b/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java
index 0ced7cf..46343a3 100644
--- a/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java
+++ b/tests/src/com/android/launcher3/ui/AllAppsAppLaunchTest.java
@@ -1,52 +1,55 @@
 package com.android.launcher3.ui;
 
 import android.content.pm.LauncherActivityInfo;
-import android.os.Process;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
-import android.test.suitebuilder.annotation.LargeTest;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.Condition;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.LauncherActivityRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test for verifying apps is launched from all-apps
  */
 @LargeTest
-public class AllAppsAppLaunchTest extends LauncherInstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AllAppsAppLaunchTest extends AbstractLauncherUiTest {
 
-    private LauncherActivityInfo mSettingsApp;
+    @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext)
-                .getActivityList("com.android.settings", Process.myUserHandle()).get(0);
-    }
-
+    @Test
     public void testAppLauncher_portrait() throws Exception {
         lockRotation(true);
         performTest();
     }
 
+    @Test
     public void testAppLauncher_landscape() throws Exception {
         lockRotation(false);
         performTest();
     }
 
     private void performTest() throws Exception {
-        startLauncher();
+        mActivityMonitor.startLauncher();
+
+        LauncherActivityInfo settingsApp = getSettingsApp();
 
         // Open all apps and wait for load complete
         final UiObject2 appsContainer = openAllApps();
         assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT));
 
         // Open settings app and verify app launched
-        scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString())).click();
+        scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString())).click();
         assertTrue(mDevice.wait(Until.hasObject(By.pkg(
-                mSettingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT));
+                settingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT));
     }
 }
diff --git a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
index 9361750..00f30ad 100644
--- a/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
+++ b/tests/src/com/android/launcher3/ui/AllAppsIconToHomeTest.java
@@ -1,58 +1,62 @@
 package com.android.launcher3.ui;
 
 import android.content.pm.LauncherActivityInfo;
-import android.os.Process;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
-import android.test.suitebuilder.annotation.LargeTest;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.Condition;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.LauncherActivityRule;
+import com.android.launcher3.util.rule.ShellCommandRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test for dragging an icon from all-apps to homescreen.
  */
 @LargeTest
-public class AllAppsIconToHomeTest extends LauncherInstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AllAppsIconToHomeTest extends AbstractLauncherUiTest {
 
-    private LauncherActivityInfo mSettingsApp;
+    @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
+    @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher();
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        setDefaultLauncher();
-
-        mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext)
-                .getActivityList("com.android.settings", Process.myUserHandle()).get(0);
-    }
-
+    @Test
     public void testDragIcon_portrait() throws Throwable {
         lockRotation(true);
         performTest();
     }
 
+    @Test
     public void testDragIcon_landscape() throws Throwable {
         lockRotation(false);
         performTest();
     }
 
     private void performTest() throws Throwable {
+        LauncherActivityInfo settingsApp = getSettingsApp();
+
         clearHomescreen();
-        startLauncher();
+        mActivityMonitor.startLauncher();
 
         // Open all apps and wait for load complete.
         final UiObject2 appsContainer = openAllApps();
         assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT));
 
         // Drag icon to homescreen.
-        UiObject2 icon = scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString()));
+        UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString()));
         dragToWorkspace(icon, true);
 
         // Verify that the icon works on homescreen.
-        mDevice.findObject(By.text(mSettingsApp.getLabel().toString())).click();
+        mDevice.findObject(By.text(settingsApp.getLabel().toString())).click();
         assertTrue(mDevice.wait(Until.hasObject(By.pkg(
-                mSettingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT));
+                settingsApp.getComponentName().getPackageName()).depth(0)), DEFAULT_UI_TIMEOUT));
     }
 }
diff --git a/tests/src/com/android/launcher3/ui/RotationPreferenceTest.java b/tests/src/com/android/launcher3/ui/RotationPreferenceTest.java
deleted file mode 100644
index e84ad04..0000000
--- a/tests/src/com/android/launcher3/ui/RotationPreferenceTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package com.android.launcher3.ui;
-
-import android.content.SharedPreferences;
-import android.graphics.Rect;
-import android.support.test.uiautomator.UiDevice;
-import android.support.test.uiautomator.UiObject;
-import android.support.test.uiautomator.UiSelector;
-import android.test.suitebuilder.annotation.MediumTest;
-
-import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
-
-/**
- * Test for auto rotate preference.
- */
-@MediumTest
-public class RotationPreferenceTest extends LauncherInstrumentationTestCase {
-
-    private SharedPreferences mPrefs;
-    private boolean mOriginalRotationValue;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mDevice = UiDevice.getInstance(getInstrumentation());
-        mTargetContext = getInstrumentation().getTargetContext();
-        mTargetPackage = mTargetContext.getPackageName();
-        mPrefs = Utilities.getPrefs(mTargetContext);
-        mOriginalRotationValue = mPrefs.getBoolean(Utilities.ALLOW_ROTATION_PREFERENCE_KEY, false);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        setRotationEnabled(mOriginalRotationValue);
-        super.tearDown();
-    }
-
-    public void testRotation_disabled() throws Exception {
-        if (mTargetContext.getResources().getBoolean(R.bool.allow_rotation)) {
-            // This is a tablet. The test is only valid to mobile devices.
-            return;
-        }
-
-        setRotationEnabled(false);
-        mDevice.setOrientationRight();
-        startLauncher();
-
-        Rect hotseat = getHotseatBounds();
-        assertTrue(hotseat.width() > hotseat.height());
-    }
-
-    public void testRotation_enabled() throws Exception {
-        if (mTargetContext.getResources().getBoolean(R.bool.allow_rotation)) {
-            // This is a tablet. The test is only valid to mobile devices.
-            return;
-        }
-
-        setRotationEnabled(true);
-        mDevice.setOrientationRight();
-        startLauncher();
-
-        Rect hotseat = getHotseatBounds();
-        assertTrue(hotseat.width() < hotseat.height());
-    }
-
-    private void setRotationEnabled(boolean enabled) {
-        mPrefs.edit().putBoolean(Utilities.ALLOW_ROTATION_PREFERENCE_KEY, enabled).commit();
-    }
-
-    private Rect getHotseatBounds() throws Exception {
-        UiObject hotseat = mDevice.findObject(
-                new UiSelector().resourceId(mTargetPackage + ":id/hotseat"));
-        hotseat.waitForExists(6000);
-        return hotseat.getVisibleBounds();
-    }
-}
diff --git a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java
index 3a0b613..a40ad7f 100644
--- a/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java
+++ b/tests/src/com/android/launcher3/ui/ShortcutsLaunchTest.java
@@ -2,54 +2,58 @@
 
 import android.content.pm.LauncherActivityInfo;
 import android.graphics.Point;
-import android.os.Process;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.view.MotionEvent;
 
 import com.android.launcher3.R;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.Condition;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.LauncherActivityRule;
+import com.android.launcher3.util.rule.ShellCommandRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test for verifying that shortcuts are shown and can be launched after long pressing an app
  */
 @LargeTest
-public class ShortcutsLaunchTest extends LauncherInstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class ShortcutsLaunchTest extends AbstractLauncherUiTest {
 
-    private LauncherActivityInfo mSettingsApp;
+    @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
+    @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher();
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        setDefaultLauncher();
-
-        mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext)
-                .getActivityList("com.android.settings", Process.myUserHandle()).get(0);
-    }
-
+    @Test
     public void testAppLauncher_portrait() throws Exception {
         lockRotation(true);
         performTest();
     }
 
+    @Test
     public void testAppLauncher_landscape() throws Exception {
         lockRotation(false);
         performTest();
     }
 
     private void performTest() throws Exception {
-        startLauncher();
+        mActivityMonitor.startLauncher();
+        LauncherActivityInfo settingsApp = getSettingsApp();
 
         // Open all apps and wait for load complete
         final UiObject2 appsContainer = openAllApps();
         assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT));
 
         // Find settings app and verify shortcuts appear when long pressed
-        UiObject2 icon = scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString()));
+        UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString()));
         // Press icon center until shortcuts appear
         Point iconCenter = icon.getVisibleCenter();
         sendPointer(MotionEvent.ACTION_DOWN, iconCenter);
@@ -63,7 +67,7 @@
                 .findObject(getSelectorForId(R.id.bubble_text));
         shortcut.click();
         assertTrue(mDevice.wait(Until.hasObject(By.pkg(
-                mSettingsApp.getComponentName().getPackageName())
+                settingsApp.getComponentName().getPackageName())
                 .text(shortcut.getText())), DEFAULT_UI_TIMEOUT));
     }
 }
diff --git a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java
index 5d86d1e..434311d 100644
--- a/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java
+++ b/tests/src/com/android/launcher3/ui/ShortcutsToHomeTest.java
@@ -2,40 +2,43 @@
 
 import android.content.pm.LauncherActivityInfo;
 import android.graphics.Point;
-import android.os.Process;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.view.MotionEvent;
 
 import com.android.launcher3.R;
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.util.Condition;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.LauncherActivityRule;
+import com.android.launcher3.util.rule.ShellCommandRule;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test for dragging a deep shortcut to the home screen.
  */
 @LargeTest
-public class ShortcutsToHomeTest extends LauncherInstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class ShortcutsToHomeTest extends AbstractLauncherUiTest {
 
-    private LauncherActivityInfo mSettingsApp;
+    @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
+    @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher();
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        setDefaultLauncher();
-
-        mSettingsApp = LauncherAppsCompat.getInstance(mTargetContext)
-                .getActivityList("com.android.settings", Process.myUserHandle()).get(0);
-    }
-
+    @Test
     public void testDragIcon_portrait() throws Throwable {
         lockRotation(true);
         performTest();
     }
 
+    @Test
     public void testDragIcon_landscape() throws Throwable {
         lockRotation(false);
         performTest();
@@ -43,14 +46,16 @@
 
     private void performTest() throws Throwable {
         clearHomescreen();
-        startLauncher();
+        mActivityMonitor.startLauncher();
+
+        LauncherActivityInfo settingsApp  = getSettingsApp();
 
         // Open all apps and wait for load complete.
         final UiObject2 appsContainer = openAllApps();
         assertTrue(Wait.atMost(Condition.minChildCount(appsContainer, 2), DEFAULT_UI_TIMEOUT));
 
         // Find the app and long press it to show shortcuts.
-        UiObject2 icon = scrollAndFind(appsContainer, By.text(mSettingsApp.getLabel().toString()));
+        UiObject2 icon = scrollAndFind(appsContainer, By.text(settingsApp.getLabel().toString()));
         // Press icon center until shortcuts appear
         Point iconCenter = icon.getVisibleCenter();
         sendPointer(MotionEvent.ACTION_DOWN, iconCenter);
@@ -69,7 +74,7 @@
         // (the app opens and has the same text as the shortcut).
         mDevice.findObject(By.text(shortcutName)).click();
         assertTrue(mDevice.wait(Until.hasObject(By.pkg(
-                mSettingsApp.getComponentName().getPackageName())
+                settingsApp.getComponentName().getPackageName())
                 .text(shortcutName)), DEFAULT_UI_TIMEOUT));
     }
 }
diff --git a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
index 0b4e34f..a5c2e69 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddConfigWidgetTest.java
@@ -15,75 +15,75 @@
  */
 package com.android.launcher3.ui.widget;
 
-import android.app.Activity;
-import android.app.Application;
 import android.appwidget.AppWidgetManager;
 import android.content.Intent;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.view.View;
 
 import com.android.launcher3.ItemInfo;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
-import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.Workspace;
 import com.android.launcher3.testcomponent.WidgetConfigActivity;
-import com.android.launcher3.ui.LauncherInstrumentationTestCase;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.util.Condition;
-import com.android.launcher3.util.SimpleActivityMonitor;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.LauncherActivityRule;
+import com.android.launcher3.util.rule.ShellCommandRule;
 import com.android.launcher3.widget.WidgetCell;
 
-import java.util.concurrent.Callable;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test to verify widget configuration is properly shown.
  */
 @LargeTest
-public class AddConfigWidgetTest extends LauncherInstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AddConfigWidgetTest extends AbstractLauncherUiTest {
+
+    @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
+    @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind();
 
     private LauncherAppWidgetProviderInfo mWidgetInfo;
-    private SimpleActivityMonitor mActivityMonitor;
-    private MainThreadExecutor mMainThreadExecutor;
     private AppWidgetManager mAppWidgetManager;
 
     private int mWidgetId;
 
     @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         super.setUp();
         mWidgetInfo = findWidgetProvider(true /* hasConfigureScreen */);
-        mActivityMonitor = new SimpleActivityMonitor();
-        ((Application) getInstrumentation().getTargetContext().getApplicationContext())
-                .registerActivityLifecycleCallbacks(mActivityMonitor);
-        mMainThreadExecutor = new MainThreadExecutor();
         mAppWidgetManager = AppWidgetManager.getInstance(mTargetContext);
-
-        grantWidgetPermission();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        ((Application) getInstrumentation().getTargetContext().getApplicationContext())
-                .unregisterActivityLifecycleCallbacks(mActivityMonitor);
-        super.tearDown();
-    }
-
+    @Test
     public void testWidgetConfig() throws Throwable {
         runTest(false, true);
     }
 
+    @Test
     public void testWidgetConfig_rotate() throws Throwable {
         runTest(true, true);
     }
 
+    @Test
     public void testConfigCancelled() throws Throwable {
         runTest(false, false);
     }
 
+    @Test
     public void testConfigCancelled_rotate() throws Throwable {
         runTest(true, false);
     }
@@ -96,7 +96,7 @@
         lockRotation(true);
 
         clearHomescreen();
-        startLauncher();
+        mActivityMonitor.startLauncher();
 
         // Open widget tray and wait for load complete.
         final UiObject2 widgetContainer = openWidgetsTray();
@@ -146,11 +146,11 @@
      * Condition for searching widget id
      */
     private class WidgetSearchCondition extends Condition
-            implements Callable<Boolean>, Workspace.ItemOperator {
+            implements Workspace.ItemOperator {
 
         @Override
         public boolean isTrue() throws Throwable {
-            return mMainThreadExecutor.submit(this).get();
+            return mMainThreadExecutor.submit(mActivityMonitor.itemExists(this)).get();
         }
 
         @Override
@@ -159,21 +159,6 @@
                     ((LauncherAppWidgetInfo) info).providerName.equals(mWidgetInfo.provider) &&
                     ((LauncherAppWidgetInfo) info).appWidgetId == mWidgetId;
         }
-
-        @Override
-        public Boolean call() throws Exception {
-            // Find the resumed launcher
-            Launcher launcher = null;
-            for (Activity a : mActivityMonitor.resumed) {
-                if (a instanceof Launcher) {
-                    launcher = (Launcher) a;
-                }
-            }
-            if (launcher == null) {
-                return false;
-            }
-            return launcher.getWorkspace().getFirstMatch(this) != null;
-        }
     }
 
     /**
diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
index 3c92c57..19f7db7 100644
--- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java
@@ -15,42 +15,46 @@
  */
 package com.android.launcher3.ui.widget;
 
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.view.View;
 
 import com.android.launcher3.ItemInfo;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
 import com.android.launcher3.Workspace.ItemOperator;
-import com.android.launcher3.ui.LauncherInstrumentationTestCase;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.util.Condition;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.LauncherActivityRule;
+import com.android.launcher3.util.rule.ShellCommandRule;
 import com.android.launcher3.widget.WidgetCell;
 
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.assertTrue;
+
 /**
  * Test to add widget from widget tray
  */
 @LargeTest
-public class AddWidgetTest extends LauncherInstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class AddWidgetTest extends AbstractLauncherUiTest {
 
-    private LauncherAppWidgetProviderInfo widgetInfo;
+    @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
+    @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind();
 
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        grantWidgetPermission();
-
-        widgetInfo = findWidgetProvider(false /* hasConfigureScreen */);
-    }
-
+    @Test
     public void testDragIcon_portrait() throws Throwable {
         lockRotation(true);
         performTest();
     }
 
+    @Test
     public void testDragIcon_landscape() throws Throwable {
         lockRotation(false);
         performTest();
@@ -58,7 +62,10 @@
 
     private void performTest() throws Throwable {
         clearHomescreen();
-        Launcher launcher = startLauncher();
+        mActivityMonitor.startLauncher();
+
+        final LauncherAppWidgetProviderInfo widgetInfo =
+                findWidgetProvider(false /* hasConfigureScreen */);
 
         // Open widget tray and wait for load complete.
         final UiObject2 widgetContainer = openWidgetsTray();
@@ -69,12 +76,12 @@
                 .hasDescendant(By.text(widgetInfo.getLabel(mTargetContext.getPackageManager()))));
         dragToWorkspace(widget, false);
 
-        assertNotNull(launcher.getWorkspace().getFirstMatch(new ItemOperator() {
+        assertTrue(mActivityMonitor.itemExists(new ItemOperator() {
             @Override
             public boolean evaluate(ItemInfo info, View view) {
                 return info instanceof LauncherAppWidgetInfo &&
                         ((LauncherAppWidgetInfo) info).providerName.equals(widgetInfo.provider);
             }
-        }));
+        }).call());
     }
 }
diff --git a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
index 97f7b50..d4d517a 100644
--- a/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/BindWidgetTest.java
@@ -24,10 +24,11 @@
 import android.content.pm.PackageManager;
 import android.database.Cursor;
 import android.os.Bundle;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.UiSelector;
-import android.test.suitebuilder.annotation.LargeTest;
 
-import com.android.launcher3.Launcher;
+import com.android.launcher3.LauncherAppWidgetHost;
 import com.android.launcher3.LauncherAppWidgetHostView;
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherAppWidgetProviderInfo;
@@ -37,23 +38,40 @@
 import com.android.launcher3.Workspace;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.PackageInstallerCompat;
-import com.android.launcher3.ui.LauncherInstrumentationTestCase;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.util.ContentWriter;
 import com.android.launcher3.util.LooperExecutor;
+import com.android.launcher3.util.rule.LauncherActivityRule;
+import com.android.launcher3.util.rule.ShellCommandRule;
 import com.android.launcher3.widget.PendingAddWidgetInfo;
 import com.android.launcher3.widget.WidgetHostViewLoader;
 
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
 /**
  * Tests for bind widget flow.
  *
  * Note running these tests will clear the workspace on the device.
  */
 @LargeTest
-public class BindWidgetTest extends LauncherInstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class BindWidgetTest extends AbstractLauncherUiTest {
+
+    @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
+    @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind();
 
     private ContentResolver mResolver;
     private AppWidgetManagerCompat mWidgetManager;
@@ -64,21 +82,20 @@
     private int mSessionId = -1;
 
     @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         super.setUp();
 
         mResolver = mTargetContext.getContentResolver();
         mWidgetManager = AppWidgetManagerCompat.getInstance(mTargetContext);
-        grantWidgetPermission();
 
         // Clear all existing data
         LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
         LauncherSettings.Settings.call(mResolver, LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
+    @After
+    public void tearDown() throws Exception {
         if (mCursor != null) {
             mCursor.close();
         }
@@ -88,6 +105,7 @@
         }
     }
 
+    @Test
     public void testBindNormalWidget_withConfig() {
         LauncherAppWidgetProviderInfo info = findWidgetProvider(true);
         LauncherAppWidgetInfo item = createWidgetInfo(info, true);
@@ -95,6 +113,7 @@
         setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label);
     }
 
+    @Test
     public void testBindNormalWidget_withoutConfig() {
         LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
         LauncherAppWidgetInfo item = createWidgetInfo(info, true);
@@ -102,6 +121,7 @@
         setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label);
     }
 
+    @Test
     public void testUnboundWidget_removed() throws Exception {
         LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
         LauncherAppWidgetInfo item = createWidgetInfo(info, false);
@@ -120,6 +140,7 @@
         assertFalse(mDevice.findObject(new UiSelector().description(info.label)).exists());
     }
 
+    @Test
     public void testPendingWidget_autoRestored() {
         // A non-restored widget with no config screen gets restored automatically.
         LauncherAppWidgetProviderInfo info = findWidgetProvider(false);
@@ -131,6 +152,7 @@
         setupAndVerifyContents(item, LauncherAppWidgetHostView.class, info.label);
     }
 
+    @Test
     public void testPendingWidget_withConfigScreen() throws Exception {
         // A non-restored widget with config screen get bound and shows a 'Click to setup' UI.
         LauncherAppWidgetProviderInfo info = findWidgetProvider(true);
@@ -153,6 +175,7 @@
                 LauncherSettings.Favorites.APPWIDGET_ID))));
     }
 
+    @Test
     public void testPendingWidget_notRestored_removed() throws Exception {
         LauncherAppWidgetInfo item = getInvalidWidgetInfo();
         item.restoreStatus = LauncherAppWidgetInfo.FLAG_ID_NOT_VALID
@@ -169,6 +192,7 @@
         assertEquals(0, mCursor.getCount());
     }
 
+    @Test
     public void testPendingWidget_notRestored_brokenInstall() throws Exception {
         // A widget which is was being installed once, even if its not being
         // installed at the moment is not removed.
@@ -191,6 +215,7 @@
                         & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID);
     }
 
+    @Test
     public void testPendingWidget_notRestored_activeInstall() throws Exception {
         // A widget which is being installed is not removed
         LauncherAppWidgetInfo item = getInvalidWidgetInfo();
@@ -249,7 +274,7 @@
         resetLoaderState();
 
         // Launch the home activity
-        startLauncher();
+        mActivityMonitor.startLauncher();
         // Verify UI
         UiSelector selector = new UiSelector().packageName(mTargetContext.getPackageName())
                 .className(widgetClass);
@@ -285,7 +310,7 @@
             pendingInfo.minSpanY = item.minSpanY;
             Bundle options = WidgetHostViewLoader.getDefaultOptionsForWidget(mTargetContext, pendingInfo);
 
-            AppWidgetHost host = new AppWidgetHost(mTargetContext, Launcher.APPWIDGET_HOST_ID);
+            AppWidgetHost host = new LauncherAppWidgetHost(mTargetContext);
             int widgetId = host.allocateAppWidgetId();
             if (!mWidgetManager.bindAppWidgetIdIfAllowed(widgetId, info, options)) {
                 host.deleteAppWidgetId(widgetId);
diff --git a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
index b798dfa..4b9d83f 100644
--- a/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/RequestPinItemTest.java
@@ -15,23 +15,20 @@
  */
 package com.android.launcher3.ui.widget;
 
-import android.app.Activity;
-import android.app.Application;
 import android.app.PendingIntent;
 import android.appwidget.AppWidgetManager;
 import android.content.Intent;
 import android.graphics.Color;
+import android.support.test.filters.LargeTest;
+import android.support.test.runner.AndroidJUnit4;
 import android.support.test.uiautomator.By;
 import android.support.test.uiautomator.UiObject2;
 import android.support.test.uiautomator.Until;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.view.View;
 
 import com.android.launcher3.ItemInfo;
-import com.android.launcher3.Launcher;
 import com.android.launcher3.LauncherAppWidgetInfo;
 import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.MainThreadExecutor;
 import com.android.launcher3.R;
 import com.android.launcher3.ShortcutInfo;
 import com.android.launcher3.Utilities;
@@ -40,50 +37,48 @@
 import com.android.launcher3.testcomponent.AppWidgetNoConfig;
 import com.android.launcher3.testcomponent.AppWidgetWithConfig;
 import com.android.launcher3.testcomponent.RequestPinItemActivity;
-import com.android.launcher3.ui.LauncherInstrumentationTestCase;
+import com.android.launcher3.ui.AbstractLauncherUiTest;
 import com.android.launcher3.util.Condition;
-import com.android.launcher3.util.SimpleActivityMonitor;
 import com.android.launcher3.util.Wait;
+import com.android.launcher3.util.rule.LauncherActivityRule;
+import com.android.launcher3.util.rule.ShellCommandRule;
 import com.android.launcher3.widget.WidgetCell;
 
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
 import java.util.UUID;
-import java.util.concurrent.Callable;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
 
 /**
  * Test to verify pin item request flow.
  */
 @LargeTest
-public class RequestPinItemTest  extends LauncherInstrumentationTestCase {
+@RunWith(AndroidJUnit4.class)
+public class RequestPinItemTest  extends AbstractLauncherUiTest {
 
-    private SimpleActivityMonitor mActivityMonitor;
-    private MainThreadExecutor mMainThreadExecutor;
+    @Rule public LauncherActivityRule mActivityMonitor = new LauncherActivityRule();
+    @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grandWidgetBind();
+    @Rule public ShellCommandRule mDefaultLauncherRule = ShellCommandRule.setDefaultLauncher();
 
     private String mCallbackAction;
     private String mShortcutId;
     private int mAppWidgetId;
 
     @Override
-    protected void setUp() throws Exception {
+    @Before
+    public void setUp() throws Exception {
         super.setUp();
-        grantWidgetPermission();
-        setDefaultLauncher();
-
-        mActivityMonitor = new SimpleActivityMonitor();
-        ((Application) getInstrumentation().getTargetContext().getApplicationContext())
-                .registerActivityLifecycleCallbacks(mActivityMonitor);
-        mMainThreadExecutor = new MainThreadExecutor();
-
         mCallbackAction = UUID.randomUUID().toString();
         mShortcutId = UUID.randomUUID().toString();
     }
 
-    @Override
-    protected void tearDown() throws Exception {
-        ((Application) getInstrumentation().getTargetContext().getApplicationContext())
-                .unregisterActivityLifecycleCallbacks(mActivityMonitor);
-        super.tearDown();
-    }
-
+    @Test
     public void testPinWidgetNoConfig() throws Throwable {
         runTest("pinWidgetNoConfig", true, new ItemOperator() {
             @Override
@@ -96,6 +91,7 @@
         });
     }
 
+    @Test
     public void testPinWidgetNoConfig_customPreview() throws Throwable {
         // Command to set custom preview
         Intent command =  RequestPinItemActivity.getCommandIntent(
@@ -113,6 +109,7 @@
         }, command);
     }
 
+    @Test
     public void testPinWidgetWithConfig() throws Throwable {
         runTest("pinWidgetWithConfig", true, new ItemOperator() {
             @Override
@@ -125,6 +122,7 @@
         });
     }
 
+    @Test
     public void testPinShortcut() throws Throwable {
         // Command to set the shortcut id
         Intent command = RequestPinItemActivity.getCommandIntent(
@@ -149,7 +147,7 @@
         lockRotation(true);
 
         clearHomescreen();
-        startLauncher();
+        mActivityMonitor.startLauncher();
 
         // Open all apps and wait for load complete
         final UiObject2 appsContainer = openAllApps();
@@ -191,14 +189,14 @@
         }
 
         // Go back to home
-        mTargetContext.startActivity(getHomeIntent());
+        mActivityMonitor.returnToHome();
         assertTrue(Wait.atMost(new ItemSearchCondition(itemMatcher), DEFAULT_ACTIVITY_TIMEOUT));
     }
 
     /**
      * Condition for for an item
      */
-    private class ItemSearchCondition extends Condition implements Callable<Boolean> {
+    private class ItemSearchCondition extends Condition {
 
         private final ItemOperator mOp;
 
@@ -208,22 +206,7 @@
 
         @Override
         public boolean isTrue() throws Throwable {
-            return mMainThreadExecutor.submit(this).get();
-        }
-
-        @Override
-        public Boolean call() throws Exception {
-            // Find the resumed launcher
-            Launcher launcher = null;
-            for (Activity a : mActivityMonitor.resumed) {
-                if (a instanceof Launcher) {
-                    launcher = (Launcher) a;
-                }
-            }
-            if (launcher == null) {
-                return false;
-            }
-            return launcher.getWorkspace().getFirstMatch(mOp) != null;
+            return mMainThreadExecutor.submit(mActivityMonitor.itemExists(mOp)).get();
         }
     }
 }
diff --git a/tests/src/com/android/launcher3/util/SimpleActivityMonitor.java b/tests/src/com/android/launcher3/util/SimpleActivityMonitor.java
deleted file mode 100644
index 6154ab6..0000000
--- a/tests/src/com/android/launcher3/util/SimpleActivityMonitor.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- */
-package com.android.launcher3.util;
-
-import android.app.Activity;
-import android.app.Application.*;
-import android.os.Bundle;
-
-import java.util.ArrayList;
-
-/**
- * Simple monitor to keep a list of active activities.
- */
-public class SimpleActivityMonitor implements ActivityLifecycleCallbacks {
-
-    public final ArrayList<Activity> created = new ArrayList<>();
-    public final ArrayList<Activity> started = new ArrayList<>();
-    public final ArrayList<Activity> resumed = new ArrayList<>();
-
-    @Override
-    public void onActivityCreated(Activity activity, Bundle bundle) {
-        created.add(activity);
-    }
-
-    @Override
-    public void onActivityStarted(Activity activity) {
-        started.add(activity);
-    }
-
-    @Override
-    public void onActivityResumed(Activity activity) {
-        resumed.add(activity);
-    }
-
-    @Override
-    public void onActivityPaused(Activity activity) {
-        resumed.remove(activity);
-    }
-
-    @Override
-    public void onActivityStopped(Activity activity) {
-        started.remove(activity);
-    }
-
-    @Override
-    public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { }
-
-    @Override
-    public void onActivityDestroyed(Activity activity) {
-        created.remove(activity);
-    }
-}
diff --git a/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
new file mode 100644
index 0000000..edd152a
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/LauncherActivityRule.java
@@ -0,0 +1,132 @@
+/*
+ * 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.rule;
+
+import android.app.Activity;
+import android.app.Application;
+import android.app.Application.ActivityLifecycleCallbacks;
+import android.content.Intent;
+import android.os.Bundle;
+import android.support.test.InstrumentationRegistry;
+
+import com.android.launcher3.Launcher;
+import com.android.launcher3.Workspace.ItemOperator;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.util.concurrent.Callable;
+
+/**
+ * Test rule to get the current Launcher activity.
+ */
+public class LauncherActivityRule implements TestRule {
+
+    private Launcher mActivity;
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new MyStatement(base);
+    }
+
+    public Launcher getActivity() {
+        return mActivity;
+    }
+
+    public Callable<Boolean> itemExists(final ItemOperator op) {
+        return new Callable<Boolean>() {
+
+            @Override
+            public Boolean call() throws Exception {
+                Launcher launcher = getActivity();
+                if (launcher == null) {
+                    return false;
+                }
+                return launcher.getWorkspace().getFirstMatch(op) != null;
+            }
+        };
+    }
+
+    /**
+     * Starts the launcher activity in the target package.
+     */
+    public void startLauncher() {
+        InstrumentationRegistry.getInstrumentation().startActivitySync(getHomeIntent());
+    }
+
+    public void returnToHome() {
+        InstrumentationRegistry.getTargetContext().startActivity(getHomeIntent());
+        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
+    }
+
+    public static Intent getHomeIntent() {
+        return new Intent(Intent.ACTION_MAIN)
+                .addCategory(Intent.CATEGORY_HOME)
+                .setPackage(InstrumentationRegistry.getTargetContext().getPackageName())
+                .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+    }
+
+    private class MyStatement extends Statement implements ActivityLifecycleCallbacks {
+
+        private final Statement mBase;
+
+        public MyStatement(Statement base) {
+            mBase = base;
+        }
+
+        @Override
+        public void evaluate() throws Throwable {
+            Application app = (Application)
+                    InstrumentationRegistry.getTargetContext().getApplicationContext();
+            app.registerActivityLifecycleCallbacks(this);
+            try {
+                mBase.evaluate();
+            } finally {
+                app.unregisterActivityLifecycleCallbacks(this);
+            }
+        }
+
+        @Override
+        public void onActivityCreated(Activity activity, Bundle bundle) {
+            if (activity instanceof Launcher) {
+                mActivity = (Launcher) activity;
+            }
+        }
+
+        @Override
+        public void onActivityStarted(Activity activity) { }
+
+        @Override
+        public void onActivityResumed(Activity activity) { }
+
+        @Override
+        public void onActivityPaused(Activity activity) { }
+
+        @Override
+        public void onActivityStopped(Activity activity) { }
+
+        @Override
+        public void onActivitySaveInstanceState(Activity activity, Bundle bundle) { }
+
+        @Override
+        public void onActivityDestroyed(Activity activity) {
+            if (activity == mActivity) {
+                mActivity = null;
+            }
+        }
+    }
+}
diff --git a/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
new file mode 100644
index 0000000..dba2d71
--- /dev/null
+++ b/tests/src/com/android/launcher3/util/rule/ShellCommandRule.java
@@ -0,0 +1,90 @@
+/*
+ * 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.rule;
+
+import android.content.ComponentName;
+import android.content.pm.ActivityInfo;
+import android.os.ParcelFileDescriptor;
+import android.support.test.InstrumentationRegistry;
+
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * Test rule which executes a shell command at the start of the test.
+ */
+public class ShellCommandRule implements TestRule {
+
+    private final String mCmd;
+
+    public ShellCommandRule(String cmd) {
+        mCmd = cmd;
+    }
+
+    @Override
+    public Statement apply(Statement base, Description description) {
+        return new MyStatement(base, mCmd);
+    }
+
+    public static void runShellCommand(String command) throws IOException {
+        ParcelFileDescriptor pfd = InstrumentationRegistry.getInstrumentation().getUiAutomation()
+                .executeShellCommand(command);
+
+        // Read the input stream fully.
+        FileInputStream fis = new ParcelFileDescriptor.AutoCloseInputStream(pfd);
+        while (fis.read() != -1);
+        fis.close();
+    }
+
+    private static class MyStatement extends Statement {
+        private final Statement mBase;
+        private final String mCmd;
+
+        public MyStatement(Statement base, String cmd) {
+            mBase = base;
+            mCmd = cmd;
+        }
+
+        @Override
+        public void evaluate() throws Throwable {
+            runShellCommand(mCmd);
+            mBase.evaluate();
+        }
+    }
+
+    /**
+     * Grants the launcher permission to bind widgets.
+     */
+    public static ShellCommandRule grandWidgetBind() {
+        return new ShellCommandRule("appwidget grantbind --package "
+                + InstrumentationRegistry.getTargetContext().getPackageName());
+    }
+
+    /**
+     * Sets the target launcher as default launcher.
+     */
+    public static ShellCommandRule setDefaultLauncher() {
+        ActivityInfo launcher = InstrumentationRegistry.getTargetContext().getPackageManager()
+                .queryIntentActivities(LauncherActivityRule.getHomeIntent(), 0).get(0)
+                .activityInfo;
+        return new ShellCommandRule("cmd package set-home-activity " +
+                new ComponentName(launcher.packageName, launcher.name).flattenToString());
+    }
+}