merge in lmp-mr1-release history after reset to lmp-mr1-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 591d9b6..fb7ac3f 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -88,7 +88,25 @@
             android:stateNotNeeded="true"
             android:theme="@style/Theme"
             android:windowSoftInputMode="adjustPan"
-            android:screenOrientation="nosensor">
+            android:screenOrientation="nosensor"
+            android:enabled="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.HOME" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.MONKEY"/>
+            </intent-filter>
+        </activity>
+
+        <activity
+            android:name="com.android.launcher3.LauncherExtension"
+            android:launchMode="singleTask"
+            android:clearTaskOnLaunch="true"
+            android:stateNotNeeded="true"
+            android:theme="@style/Theme"
+            android:windowSoftInputMode="adjustPan"
+            android:screenOrientation="nosensor"
+            android:enabled="false">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.HOME" />
diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png
deleted file mode 100644
index c72d6a2..0000000
--- a/WallpaperPicker/res/drawable-hdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png
deleted file mode 100644
index 44c65ac..0000000
--- a/WallpaperPicker/res/drawable-hdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png
deleted file mode 100644
index 461bacb..0000000
--- a/WallpaperPicker/res/drawable-hdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png
deleted file mode 100644
index 13b325b..0000000
--- a/WallpaperPicker/res/drawable-mdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png
deleted file mode 100644
index 4e8196d..0000000
--- a/WallpaperPicker/res/drawable-mdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png
deleted file mode 100644
index eee69ec..0000000
--- a/WallpaperPicker/res/drawable-mdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-v21/ic_tick.xml b/WallpaperPicker/res/drawable-v21/ic_tick.xml
new file mode 100644
index 0000000..5b27027
--- /dev/null
+++ b/WallpaperPicker/res/drawable-v21/ic_tick.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:height="48dp"
+    android:viewportHeight="48"
+    android:viewportWidth="48"
+    android:width="48dp" >
+
+    <group>
+        <path
+            android:name="tick"
+            android:fillColor="#FFFFFFFF"
+            android:pathData="M18 32.34l-8.34-8.34-2.83 2.83 11.17 11.17 24-24-2.83-2.83z" />
+    </group>
+
+</vector>
\ No newline at end of file
diff --git a/WallpaperPicker/res/drawable-v21/wallpaper_tile_fg.xml b/WallpaperPicker/res/drawable-v21/wallpaper_tile_fg.xml
new file mode 100644
index 0000000..97cdcd6
--- /dev/null
+++ b/WallpaperPicker/res/drawable-v21/wallpaper_tile_fg.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2014 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+    android:color="#66FFFFFF" >
+
+    <item
+        android:id="@android:id/mask"
+        android:drawable="@android:color/white"/>
+    <item
+        android:bottom="23.25dp"
+        android:left="29.25dp"
+        android:right="29.25dp"
+        android:top="23.25dp">
+        <selector>
+            <item
+                android:drawable="@drawable/ic_tick"
+                android:state_selected="true"/>
+            <item
+                android:drawable="@drawable/ic_tick"
+                android:state_checked="true"/>
+        </selector>
+    </item>
+
+</ripple>
\ No newline at end of file
diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png
deleted file mode 100644
index 279e859..0000000
--- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png
deleted file mode 100644
index abe0e00..0000000
--- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png
deleted file mode 100644
index b047591..0000000
--- a/WallpaperPicker/res/drawable-xhdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png
deleted file mode 100644
index 1004c14..0000000
--- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_focused.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png
deleted file mode 100644
index 9658444..0000000
--- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_pressed.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png b/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png
deleted file mode 100644
index a3cd303..0000000
--- a/WallpaperPicker/res/drawable-xxhdpi/tile_picker_selected.9.png
+++ /dev/null
Binary files differ
diff --git a/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml b/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml
index c299f32..c66fa50 100644
--- a/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml
+++ b/WallpaperPicker/res/drawable/wallpaper_tile_fg.xml
@@ -15,9 +15,33 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_checked="true" android:drawable="@drawable/tile_picker_selected" />
-    <item android:state_focused="true" android:drawable="@drawable/tile_picker_focused" />
-    <item android:state_pressed="true" android:drawable="@drawable/tile_picker_pressed" />
-    <item android:state_selected="true" android:drawable="@drawable/tile_picker_selected" />
+    <item android:state_checked="true" >
+        <shape>
+            <stroke
+                android:width="2dp"
+                android:color="#FFFFFFFF" />
+            <solid android:color="#33FFFFFF"/>
+        </shape>
+    </item>
+    <item android:state_focused="true" >
+        <shape>
+            <stroke
+                android:width="2dp"
+                android:color="#FFFFFFFF" />
+        </shape>
+    </item>
+    <item android:state_pressed="true">
+        <shape android:shape="rectangle">
+            <solid android:color="#33FFFFFF"/>
+        </shape>
+    </item>
+    <item android:state_selected="true" >
+        <shape>
+            <stroke
+                android:width="2dp"
+                android:color="#FFFFFFFF" />
+            <solid android:color="#33FFFFFF"/>
+        </shape>
+    </item>
     <item android:drawable="@android:color/transparent" />
 </selector>
diff --git a/WallpaperPicker/res/values-v19/styles.xml b/WallpaperPicker/res/values-v19/styles.xml
index 85a989d..136cf01 100644
--- a/WallpaperPicker/res/values-v19/styles.xml
+++ b/WallpaperPicker/res/values-v19/styles.xml
@@ -18,14 +18,14 @@
 -->
 
 <resources>
-    <style name="Theme.WallpaperCropper" parent="@android:style/Theme.Holo">
+    <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
         <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
         <item name="android:windowFullscreen">true</item>
         <item name="android:windowActionBarOverlay">true</item>
         <item name="android:windowTranslucentNavigation">true</item>
     </style>
 
-    <style name="Theme" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
+    <style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
         <item name="android:windowTranslucentStatus">true</item>
         <item name="android:windowTranslucentNavigation">true</item>
     </style>
diff --git a/WallpaperPicker/res/values/styles.xml b/WallpaperPicker/res/values/styles.xml
index 16b11f2..f4008f1 100644
--- a/WallpaperPicker/res/values/styles.xml
+++ b/WallpaperPicker/res/values/styles.xml
@@ -18,7 +18,7 @@
 -->
 
 <resources>
-    <style name="Theme.WallpaperCropper" parent="@android:style/Theme.Holo">
+    <style name="Theme.WallpaperCropper" parent="@android:style/Theme.DeviceDefault">
         <item name="android:actionBarStyle">@style/WallpaperCropperActionBar</item>
         <item name="android:windowFullscreen">true</item>
         <item name="android:windowActionBarOverlay">true</item>
@@ -30,15 +30,15 @@
         <item name="android:windowShowWallpaper">true</item>
     </style>
 
-    <style name="WallpaperCropperActionBar" parent="android:style/Widget.Holo.ActionBar">
+    <style name="WallpaperCropperActionBar" parent="@android:style/Widget.DeviceDefault.ActionBar">
         <item name="android:displayOptions">showCustom</item>
         <item name="android:background">#88000000</item>
     </style>
 
-    <style name="Theme" parent="@android:style/Theme.Holo.Wallpaper.NoTitleBar">
+    <style name="Theme" parent="@android:style/Theme.DeviceDefault.Wallpaper.NoTitleBar">
     </style>
 
-    <style name="ActionBarSetWallpaperStyle" parent="@android:style/Widget.Holo.ActionButton">
+    <style name="ActionBarSetWallpaperStyle" parent="@android:style/Widget.DeviceDefault.ActionButton">
         <item name="android:textColor">#ffffffff</item>
     </style>
 </resources>
diff --git a/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
index 2bdf8f1..9f92bc1 100644
--- a/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
+++ b/WallpaperPicker/src/com/android/launcher3/SavedWallpaperImages.java
@@ -180,7 +180,6 @@
 
     static class ImageDb extends SQLiteOpenHelper {
         final static int DB_VERSION = 1;
-        final static String DB_NAME = "saved_wallpaper_images.db";
         final static String TABLE_NAME = "saved_wallpaper_images";
         final static String COLUMN_ID = "id";
         final static String COLUMN_IMAGE_THUMBNAIL_FILENAME = "image_thumbnail";
@@ -189,7 +188,8 @@
         Context mContext;
 
         public ImageDb(Context context) {
-            super(context, context.getDatabasePath(DB_NAME).getPath(), null, DB_VERSION);
+            super(context, context.getDatabasePath(LauncherFiles.WALLPAPER_IMAGES_DB).getPath(),
+                    null, DB_VERSION);
             // Store the context for later use
             mContext = context;
         }
@@ -197,8 +197,9 @@
         public static void moveFromCacheDirectoryIfNecessary(Context context) {
             // We used to store the saved images in the cache directory, but that meant they'd get
             // deleted sometimes-- move them to the data directory
-            File oldSavedImagesFile = new File(context.getCacheDir(), ImageDb.DB_NAME);
-            File savedImagesFile = context.getDatabasePath(ImageDb.DB_NAME);
+            File oldSavedImagesFile = new File(context.getCacheDir(),
+                    LauncherFiles.WALLPAPER_IMAGES_DB);
+            File savedImagesFile = context.getDatabasePath(LauncherFiles.WALLPAPER_IMAGES_DB);
             if (oldSavedImagesFile.exists()) {
                 oldSavedImagesFile.renameTo(savedImagesFile);
             }
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
index d5c7cd9..fa8ec64 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperCropActivity.java
@@ -202,7 +202,7 @@
     }
 
     public static String getSharedPreferencesKey() {
-        return WallpaperCropActivity.class.getName();
+        return LauncherFiles.WALLPAPER_CROP_PREFERENCES_KEY;
     }
 
     // As a ratio of screen height, the total distance we want the parallax effect to span
diff --git a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
index 0728537..09e0963 100644
--- a/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
+++ b/WallpaperPicker/src/com/android/launcher3/WallpaperPickerActivity.java
@@ -86,8 +86,6 @@
     public static final int PICK_LIVE_WALLPAPER = 7;
     private static final String TEMP_WALLPAPER_TILES = "TEMP_WALLPAPER_TILES";
     private static final String SELECTED_INDEX = "SELECTED_INDEX";
-    private static final String OLD_DEFAULT_WALLPAPER_THUMBNAIL_FILENAME = "default_thumb.jpg";
-    private static final String DEFAULT_WALLPAPER_THUMBNAIL_FILENAME = "default_thumb2.jpg";
     private static final int FLAG_POST_DELAY_MILLIS = 200;
 
     private View mSelectedTile;
@@ -999,16 +997,16 @@
 
     private File getDefaultThumbFile() {
         return new File(getFilesDir(), Build.VERSION.SDK_INT
-                + "_" + DEFAULT_WALLPAPER_THUMBNAIL_FILENAME);
+                + "_" + LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL);
     }
 
     private boolean saveDefaultWallpaperThumb(Bitmap b) {
         // Delete old thumbnails.
-        new File(getFilesDir(), OLD_DEFAULT_WALLPAPER_THUMBNAIL_FILENAME).delete();
-        new File(getFilesDir(), DEFAULT_WALLPAPER_THUMBNAIL_FILENAME).delete();
+        new File(getFilesDir(), LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL_OLD).delete();
+        new File(getFilesDir(), LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete();
 
         for (int i = Build.VERSION_CODES.JELLY_BEAN; i < Build.VERSION.SDK_INT; i++) {
-            new File(getFilesDir(), i + "_" + DEFAULT_WALLPAPER_THUMBNAIL_FILENAME).delete();
+            new File(getFilesDir(), i + "_" + LauncherFiles.DEFAULT_WALLPAPER_THUMBNAIL).delete();
         }
         return writeImageToFileAsJpeg(getDefaultThumbFile(), b);
     }
diff --git a/proguard.flags b/proguard.flags
index 0b28c0e..83a491d 100644
--- a/proguard.flags
+++ b/proguard.flags
@@ -57,3 +57,8 @@
   public float getAnimationProgress();
   public void setAnimationProgress(float);
 }
+
+-keep class com.android.launcher3.FastBitmapDrawable {
+  public int getBrightness();
+  public void setBrightness(int);
+}
diff --git a/protos/backup.proto b/protos/backup.proto
index 7ba2937..8ae1752 100644
--- a/protos/backup.proto
+++ b/protos/backup.proto
@@ -37,12 +37,36 @@
   required int64 checksum = 2;
 }
 
+message DeviceProfieData {
+  required float desktop_rows = 1;
+  required float desktop_cols = 2;
+  required float hotseat_count = 3;
+  required int32 allapps_rank = 4;
+}
+
 message Journal {
   required int32 app_version = 1;
+
+  // Time when the backup was created
   required int64 t = 2;
+
+  // Total bytes written during the last backup
+  // OBSOLETE: A state may contain entries which are already present in the backup
+  // and were not written in the last backup
   optional int64 bytes = 3;
+
+  // Total entries written during the last backup
+  // OBSOLETE: A state may contain entries which are already present in the backup
+  // and were not written in the last backup
   optional int32 rows = 4;
+
+  // Valid keys for this state
   repeated Key key = 5;
+
+  // Backup format version.
+  optional int32 backup_version = 6 [default = 1];
+
+  optional DeviceProfieData profile = 7;
 }
 
 message Favorite {
diff --git a/res/drawable-hdpi/hand.png b/res/drawable-hdpi/hand.png
deleted file mode 100644
index bd4f6df..0000000
--- a/res/drawable-hdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_home_search_normal_holo.png b/res/drawable-hdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index 3f64d68..0000000
--- a/res/drawable-hdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_home_voice_search_holo.png b/res/drawable-hdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index dae5446..0000000
--- a/res/drawable-hdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_pageindicator_current.png b/res/drawable-hdpi/ic_pageindicator_current.png
index 2e841f5..283f44d 100644
--- a/res/drawable-hdpi/ic_pageindicator_current.png
+++ b/res/drawable-hdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_pageindicator_default.png b/res/drawable-hdpi/ic_pageindicator_default.png
index 07ab948..47b9989 100644
--- a/res/drawable-hdpi/ic_pageindicator_default.png
+++ b/res/drawable-hdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-hdpi/search_frame.9.png b/res/drawable-hdpi/search_frame.9.png
deleted file mode 100644
index 15ca1f4..0000000
--- a/res/drawable-hdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_focused_holo.9.png b/res/drawable-hdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index 673e3bf..0000000
--- a/res/drawable-hdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_holo.9.png b/res/drawable-hdpi/tab_selected_holo.9.png
deleted file mode 100644
index d57df98..0000000
--- a/res/drawable-hdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png
deleted file mode 100644
index 4b312d9..0000000
--- a/res/drawable-hdpi/tab_selected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_selected_pressed_holo.9.png b/res/drawable-hdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index 6278eef..0000000
--- a/res/drawable-hdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_focused_holo.9.png b/res/drawable-hdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index 294991d..0000000
--- a/res/drawable-hdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_holo.9.png b/res/drawable-hdpi/tab_unselected_holo.9.png
deleted file mode 100644
index 19532ab..0000000
--- a/res/drawable-hdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png
deleted file mode 100644
index 5140b35..0000000
--- a/res/drawable-hdpi/tab_unselected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/tab_unselected_pressed_holo.9.png b/res/drawable-hdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index aadc6f8..0000000
--- a/res/drawable-hdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-hdpi/ic_home_voice_search_holo.png b/res/drawable-land-hdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 5a7fc99..0000000
--- a/res/drawable-land-hdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-mdpi/ic_home_voice_search_holo.png b/res/drawable-land-mdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index ee7dde5..0000000
--- a/res/drawable-land-mdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-xhdpi/ic_home_voice_search_holo.png b/res/drawable-land-xhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 56bbbbb..0000000
--- a/res/drawable-land-xhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 6ea7368..0000000
--- a/res/drawable-land-xxhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/hand.png b/res/drawable-mdpi/hand.png
deleted file mode 100644
index fe5a035..0000000
--- a/res/drawable-mdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_search_normal_holo.png b/res/drawable-mdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index 7367c38..0000000
--- a/res/drawable-mdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_home_voice_search_holo.png b/res/drawable-mdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index f211a7b..0000000
--- a/res/drawable-mdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_pageindicator_current.png b/res/drawable-mdpi/ic_pageindicator_current.png
index 08f43b4..b41e1bb 100644
--- a/res/drawable-mdpi/ic_pageindicator_current.png
+++ b/res/drawable-mdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_pageindicator_default.png b/res/drawable-mdpi/ic_pageindicator_default.png
index 635be4a..e36c25c 100644
--- a/res/drawable-mdpi/ic_pageindicator_default.png
+++ b/res/drawable-mdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-mdpi/search_frame.9.png b/res/drawable-mdpi/search_frame.9.png
deleted file mode 100644
index 058905b..0000000
--- a/res/drawable-mdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_focused_holo.9.png b/res/drawable-mdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index c9972e7..0000000
--- a/res/drawable-mdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_holo.9.png b/res/drawable-mdpi/tab_selected_holo.9.png
deleted file mode 100644
index 587337c..0000000
--- a/res/drawable-mdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png
deleted file mode 100644
index 284f534..0000000
--- a/res/drawable-mdpi/tab_selected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_selected_pressed_holo.9.png b/res/drawable-mdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index 155c4fc..0000000
--- a/res/drawable-mdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_focused_holo.9.png b/res/drawable-mdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index f0cecd1..0000000
--- a/res/drawable-mdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_holo.9.png b/res/drawable-mdpi/tab_unselected_holo.9.png
deleted file mode 100644
index a2dbf42..0000000
--- a/res/drawable-mdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png
deleted file mode 100644
index f1a2819..0000000
--- a/res/drawable-mdpi/tab_unselected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/tab_unselected_pressed_holo.9.png b/res/drawable-mdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index b1223fe..0000000
--- a/res/drawable-mdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/hand.png b/res/drawable-xhdpi/hand.png
deleted file mode 100644
index 35b678c..0000000
--- a/res/drawable-xhdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_home_search_normal_holo.png b/res/drawable-xhdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index 0fe1cd1..0000000
--- a/res/drawable-xhdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_home_voice_search_holo.png b/res/drawable-xhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index 1fc5cc8..0000000
--- a/res/drawable-xhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pageindicator_current.png b/res/drawable-xhdpi/ic_pageindicator_current.png
index 0e9a52f..8fa774d 100644
--- a/res/drawable-xhdpi/ic_pageindicator_current.png
+++ b/res/drawable-xhdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_pageindicator_default.png b/res/drawable-xhdpi/ic_pageindicator_default.png
index d0f14cd..8eb5eb0 100644
--- a/res/drawable-xhdpi/ic_pageindicator_default.png
+++ b/res/drawable-xhdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-xhdpi/search_frame.9.png b/res/drawable-xhdpi/search_frame.9.png
deleted file mode 100644
index 32a0714..0000000
--- a/res/drawable-xhdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_focused_holo.9.png b/res/drawable-xhdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index 03cfb09..0000000
--- a/res/drawable-xhdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_holo.9.png b/res/drawable-xhdpi/tab_selected_holo.9.png
deleted file mode 100644
index e4229f2..0000000
--- a/res/drawable-xhdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png b/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png
deleted file mode 100644
index 2412711..0000000
--- a/res/drawable-xhdpi/tab_selected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_selected_pressed_holo.9.png b/res/drawable-xhdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index e862cb1..0000000
--- a/res/drawable-xhdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_focused_holo.9.png b/res/drawable-xhdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index f3a5cbd..0000000
--- a/res/drawable-xhdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_holo.9.png b/res/drawable-xhdpi/tab_unselected_holo.9.png
deleted file mode 100644
index 9465173..0000000
--- a/res/drawable-xhdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png b/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png
deleted file mode 100644
index 1653600..0000000
--- a/res/drawable-xhdpi/tab_unselected_pressed_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png b/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index f1eb673..0000000
--- a/res/drawable-xhdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/hand.png b/res/drawable-xxhdpi/hand.png
deleted file mode 100644
index 88c2a88..0000000
--- a/res/drawable-xxhdpi/hand.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_search_normal_holo.png b/res/drawable-xxhdpi/ic_home_search_normal_holo.png
deleted file mode 100644
index a9523d3..0000000
--- a/res/drawable-xxhdpi/ic_home_search_normal_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_home_voice_search_holo.png b/res/drawable-xxhdpi/ic_home_voice_search_holo.png
deleted file mode 100644
index c9c0b50..0000000
--- a/res/drawable-xxhdpi/ic_home_voice_search_holo.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_pageindicator_current.png b/res/drawable-xxhdpi/ic_pageindicator_current.png
index b74e92e..22b290e 100644
--- a/res/drawable-xxhdpi/ic_pageindicator_current.png
+++ b/res/drawable-xxhdpi/ic_pageindicator_current.png
Binary files differ
diff --git a/res/drawable-xxhdpi/ic_pageindicator_default.png b/res/drawable-xxhdpi/ic_pageindicator_default.png
index e362ece..e608cae 100644
--- a/res/drawable-xxhdpi/ic_pageindicator_default.png
+++ b/res/drawable-xxhdpi/ic_pageindicator_default.png
Binary files differ
diff --git a/res/drawable-xxhdpi/search_bg_panel.9.png b/res/drawable-xxhdpi/search_bg_panel.9.png
deleted file mode 100644
index 85cae17..0000000
--- a/res/drawable-xxhdpi/search_bg_panel.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/search_frame.9.png b/res/drawable-xxhdpi/search_frame.9.png
deleted file mode 100644
index f297bf1..0000000
--- a/res/drawable-xxhdpi/search_frame.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_focused_holo.9.png b/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
deleted file mode 100644
index 2400c65..0000000
--- a/res/drawable-xxhdpi/tab_selected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_holo.9.png b/res/drawable-xxhdpi/tab_selected_holo.9.png
deleted file mode 100644
index 5067cbb..0000000
--- a/res/drawable-xxhdpi/tab_selected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
deleted file mode 100644
index 84c246d..0000000
--- a/res/drawable-xxhdpi/tab_selected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png b/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
deleted file mode 100644
index 939e0c3..0000000
--- a/res/drawable-xxhdpi/tab_unselected_focused_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_holo.9.png b/res/drawable-xxhdpi/tab_unselected_holo.9.png
deleted file mode 100644
index 62ca6cf..0000000
--- a/res/drawable-xxhdpi/tab_unselected_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png b/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
deleted file mode 100644
index 58ac0d6..0000000
--- a/res/drawable-xxhdpi/tab_unselected_pressed_holo.9.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable/tab_widget_indicator_selector.xml b/res/drawable/tab_widget_indicator_selector.xml
deleted file mode 100644
index d06f757..0000000
--- a/res/drawable/tab_widget_indicator_selector.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <!-- Non focused states -->
-    <item android:state_focused="false" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_holo" />
-
-    <!-- Focused states -->
-    <item android:state_focused="true" android:state_selected="false" android:state_pressed="false" android:drawable="@drawable/tab_unselected_focused_holo" />
-    <item android:state_focused="true" android:state_selected="true" android:state_pressed="false" android:drawable="@drawable/tab_selected_focused_holo" />
-
-    <!-- Pressed -->
-    <!--    Non focused states -->
-    <item android:state_focused="false" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_holo" />
-    <item android:state_focused="false" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_holo" />
-
-    <!--    Focused states -->
-    <item android:state_focused="true" android:state_selected="false" android:state_pressed="true" android:drawable="@drawable/tab_unselected_pressed_focused_holo" />
-    <item android:state_focused="true" android:state_selected="true" android:state_pressed="true" android:drawable="@drawable/tab_selected_pressed_focused_holo" />
-</selector>
diff --git a/res/layout-land/launcher.xml b/res/layout-land/launcher.xml
index 8cd8673..6f95bd5 100644
--- a/res/layout-land/launcher.xml
+++ b/res/layout-land/launcher.xml
@@ -15,20 +15,20 @@
 -->
 
 <!-- Full screen view projects under the status bar and contains the background -->
-<FrameLayout
+<com.android.launcher3.LauncherRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:id="@+id/launcher"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@drawable/workspace_bg">
+    android:background="@drawable/workspace_bg"
+    android:fitsSystemWindows="true">
 
     <com.android.launcher3.DragLayer
         android:id="@+id/drag_layer"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:fitsSystemWindows="true">
+        android:layout_height="match_parent">
 
         <com.android.launcher3.FocusIndicatorView
             android:id="@+id/focus_indicator"
@@ -63,4 +63,11 @@
             android:layout_height="match_parent"
             android:visibility="invisible" />
     </com.android.launcher3.DragLayer>
-</FrameLayout>
+
+    <ViewStub
+        android:id="@+id/launcher_overlay_stub"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:inflatedId="@+id/launcher_overlay"
+        android:layout="@layout/launcher_overlay" />
+</com.android.launcher3.LauncherRootView>
diff --git a/res/layout-land/longpress_cling.xml b/res/layout-land/longpress_cling.xml
index 93bbc07..9672dd8 100644
--- a/res/layout-land/longpress_cling.xml
+++ b/res/layout-land/longpress_cling.xml
@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:id="@+id/longpress_cling"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    launcher:layout_ignoreInsets="true"
     android:background="@color/cling_scrim_background"
     android:orientation="vertical" >
 
diff --git a/res/layout-land/migration_cling.xml b/res/layout-land/migration_cling.xml
index 307cba8..db93da8 100644
--- a/res/layout-land/migration_cling.xml
+++ b/res/layout-land/migration_cling.xml
@@ -15,9 +15,11 @@
      limitations under the License.
 -->
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:id="@+id/migration_cling"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    launcher:layout_ignoreInsets="true"
     android:background="#FF009688"
     android:baselineAligned="false"
     android:gravity="center_vertical" >
diff --git a/res/layout-land/qsb.xml b/res/layout-land/qsb.xml
deleted file mode 100644
index d56e380..0000000
--- a/res/layout-land/qsb.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical">
-   <!-- Global search icon -->
-   <com.android.launcher3.HolographicImageView
-        style="@style/SearchButton"
-        android:id="@+id/search_button"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentTop="true"
-        android:scaleType="center"
-        android:src="@drawable/ic_home_search_normal_holo"
-        android:adjustViewBounds="true"
-        android:onClick="onClickSearchButton"
-        android:focusable="true"
-        android:clickable="true"
-        android:contentDescription="@string/accessibility_search_button" />
-
-    <!-- Voice search icon -->
-    <com.android.launcher3.HolographicImageView
-        style="@style/SearchButton"
-        android:id="@+id/voice_button"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_alignParentBottom="true"
-        android:scaleType="center"
-        android:src="@drawable/ic_home_voice_search_holo"
-        android:adjustViewBounds="true"
-        android:onClick="onClickVoiceButton"
-        android:focusable="true"
-        android:clickable="true"
-        android:contentDescription="@string/accessibility_voice_search_button" />
-</LinearLayout>
diff --git a/res/layout-port/launcher.xml b/res/layout-port/launcher.xml
index 9e98d42..af30a32 100644
--- a/res/layout-port/launcher.xml
+++ b/res/layout-port/launcher.xml
@@ -15,14 +15,15 @@
 -->
 
 <!-- Full screen view projects under the status bar and contains the background -->
-<FrameLayout
+<com.android.launcher3.LauncherRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:id="@+id/launcher"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@drawable/workspace_bg">
+    android:background="@drawable/workspace_bg"
+    android:fitsSystemWindows="true">
 
     <com.android.launcher3.DragLayer
         android:id="@+id/drag_layer"
@@ -65,22 +66,17 @@
             android:id="@+id/search_drop_target_bar"
             layout="@layout/search_drop_target_bar" />
 
-        <!-- This is the search bar voice button proxy view.  It allows us to have a larger
-             touch target than the microphone constrained by the search bar bounds. -->
-        <com.android.launcher3.DrawableStateProxyView
-            android:id="@+id/voice_button_proxy"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout_gravity="top|end"
-            android:clickable="true"
-            android:onClick="onClickVoiceButton"
-            android:importantForAccessibility="no"
-            launcher:sourceViewId="@+id/voice_button" />
-
         <include layout="@layout/apps_customize_pane"
             android:id="@+id/apps_customize_pane"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:visibility="invisible" />
     </com.android.launcher3.DragLayer>
-</FrameLayout>
+
+    <ViewStub
+        android:id="@+id/launcher_overlay_stub"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:inflatedId="@+id/launcher_overlay"
+        android:layout="@layout/launcher_overlay" />
+</com.android.launcher3.LauncherRootView>
diff --git a/res/layout-port/longpress_cling.xml b/res/layout-port/longpress_cling.xml
index 8e35f5c..c0b5267 100644
--- a/res/layout-port/longpress_cling.xml
+++ b/res/layout-port/longpress_cling.xml
@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:id="@+id/longpress_cling"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    launcher:layout_ignoreInsets="true"
     android:background="@color/cling_scrim_background" >
 
     <FrameLayout
diff --git a/res/layout-port/migration_cling.xml b/res/layout-port/migration_cling.xml
index dde8dbc..81689d3 100644
--- a/res/layout-port/migration_cling.xml
+++ b/res/layout-port/migration_cling.xml
@@ -15,9 +15,11 @@
      limitations under the License.
 -->
 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:id="@+id/migration_cling"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    launcher:layout_ignoreInsets="true"
     android:background="#FF009688" >
 
     <RelativeLayout
diff --git a/res/layout-port/qsb.xml b/res/layout-port/qsb.xml
deleted file mode 100644
index 4c9963d..0000000
--- a/res/layout-port/qsb.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/search_frame">
-   <!-- Global search icon -->
-   <com.android.launcher3.HolographicLinearLayout
-        style="@style/SearchButton.WithPaddingStart"
-        launcher:sourceImageViewId="@+id/search_button"
-        android:id="@+id/search_button_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical"
-        android:layout_centerVertical="true"
-        android:layout_alignParentStart="true"
-        android:layout_toStartOf="@+id/voice_button_container"
-        android:onClick="onClickSearchButton"
-        android:focusable="true"
-        android:clickable="true"
-        android:contentDescription="@string/accessibility_search_button">
-       <ImageView
-            android:id="@+id/search_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_gravity="start"
-            android:scaleType="fitCenter"
-            android:src="@drawable/ic_home_search_normal_holo"
-            android:adjustViewBounds="true" />
-    </com.android.launcher3.HolographicLinearLayout>
-
-    <!-- Voice search icon -->
-    <com.android.launcher3.HolographicLinearLayout
-        style="@style/SearchButton"
-        launcher:sourceImageViewId="@+id/voice_button"
-        android:id="@+id/voice_button_container"
-        android:layout_width="@dimen/app_icon_size"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical"
-        android:layout_centerVertical="true"
-        android:layout_alignParentEnd="true"
-        android:paddingEnd="8dp"
-        android:paddingRight="8dp"
-        android:onClick="onClickVoiceButton"
-        android:focusable="true"
-        android:clickable="true"
-        android:contentDescription="@string/accessibility_voice_search_button">
-        <ImageView
-            android:id="@+id/voice_button"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="end"
-            android:scaleType="fitCenter"
-            android:src="@drawable/ic_home_voice_search_holo"
-            android:adjustViewBounds="true" />
-    </com.android.launcher3.HolographicLinearLayout>
-</RelativeLayout>
diff --git a/res/layout-sw600dp-port/longpress_cling.xml b/res/layout-sw600dp-port/longpress_cling.xml
index b42d697..c4573d5 100644
--- a/res/layout-sw600dp-port/longpress_cling.xml
+++ b/res/layout-sw600dp-port/longpress_cling.xml
@@ -1,9 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:id="@+id/longpress_cling"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
+    launcher:layout_ignoreInsets="true"
     android:background="@color/cling_scrim_background"
     android:orientation="vertical" >
 
diff --git a/res/layout-sw720dp/external_widget_drop_list_item.xml b/res/layout-sw720dp/external_widget_drop_list_item.xml
deleted file mode 100644
index 48e333b..0000000
--- a/res/layout-sw720dp/external_widget_drop_list_item.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<LinearLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-
-    android:layout_width="match_parent"
-    android:layout_height="64dp">
-    <ImageView
-        android:id="@+id/provider_icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:layout_marginStart="20dp"
-        android:maxWidth="32dp"
-        android:maxHeight="32dp"
-        android:scaleType="fitCenter"
-        android:src="@mipmap/ic_launcher_application" />
-    <TextView
-        android:id="@+id/provider"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_marginStart="5dp"
-        android:gravity="center_vertical"
-        android:textSize="18sp" />
-</LinearLayout>
diff --git a/res/layout-sw720dp/launcher.xml b/res/layout-sw720dp/launcher.xml
index 6261541..960ccf3 100644
--- a/res/layout-sw720dp/launcher.xml
+++ b/res/layout-sw720dp/launcher.xml
@@ -15,20 +15,20 @@
 -->
 
 <!-- Full screen view projects under the status bar and contains the background -->
-<FrameLayout
+<com.android.launcher3.LauncherRootView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:id="@+id/launcher"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:background="@drawable/workspace_bg">
+    android:background="@drawable/workspace_bg"
+    android:fitsSystemWindows="true">
 
     <com.android.launcher3.DragLayer
         android:id="@+id/drag_layer"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:fitsSystemWindows="true">
+        android:layout_height="match_parent">
 
         <com.android.launcher3.FocusIndicatorView
             android:id="@+id/focus_indicator"
@@ -66,20 +66,18 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center_horizontal" />
 
-        <com.android.launcher3.DrawableStateProxyView
-            android:id="@+id/voice_button_proxy"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            android:layout_gravity="top|end"
-            android:clickable="true"
-            android:onClick="onClickVoiceButton"
-            android:importantForAccessibility="no"
-            launcher:sourceViewId="@+id/voice_button" />
-
         <include layout="@layout/apps_customize_pane"
             android:id="@+id/apps_customize_pane"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:visibility="invisible" />
     </com.android.launcher3.DragLayer>
-</FrameLayout>
+
+    <ViewStub
+        android:id="@+id/launcher_overlay_stub"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:inflatedId="@+id/launcher_overlay"
+        android:layout="@layout/launcher_overlay" />
+
+</com.android.launcher3.LauncherRootView>
diff --git a/res/layout-sw720dp/market_button.xml b/res/layout-sw720dp/market_button.xml
deleted file mode 100644
index 7eaeafa..0000000
--- a/res/layout-sw720dp/market_button.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/MarketButton"
-    android:onClick="onClickAppMarketButton"
-    android:gravity="center"
-    android:paddingLeft="32dp"
-    android:paddingRight="32dp"
-    android:drawablePadding="10dp"
-    android:background="@drawable/tab_widget_indicator_selector"
-    android:text="@string/market"
-    android:contentDescription="@string/market"
-    android:textColor="@color/workspace_all_apps_and_delete_zone_text_color"
-    android:textStyle="bold"
-    android:textSize="14sp"
-    android:textAllCaps="true"
-    android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
-    android:shadowDx="0.0"
-    android:shadowDy="0.0"
-    android:shadowRadius="2.0"
-    android:focusable="true"
-    android:clickable="true" />
diff --git a/res/layout-sw720dp/qsb.xml b/res/layout-sw720dp/qsb.xml
deleted file mode 100644
index 4c9963d..0000000
--- a/res/layout-sw720dp/qsb.xml
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<RelativeLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:background="@drawable/search_frame">
-   <!-- Global search icon -->
-   <com.android.launcher3.HolographicLinearLayout
-        style="@style/SearchButton.WithPaddingStart"
-        launcher:sourceImageViewId="@+id/search_button"
-        android:id="@+id/search_button_container"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical"
-        android:layout_centerVertical="true"
-        android:layout_alignParentStart="true"
-        android:layout_toStartOf="@+id/voice_button_container"
-        android:onClick="onClickSearchButton"
-        android:focusable="true"
-        android:clickable="true"
-        android:contentDescription="@string/accessibility_search_button">
-       <ImageView
-            android:id="@+id/search_button"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_gravity="start"
-            android:scaleType="fitCenter"
-            android:src="@drawable/ic_home_search_normal_holo"
-            android:adjustViewBounds="true" />
-    </com.android.launcher3.HolographicLinearLayout>
-
-    <!-- Voice search icon -->
-    <com.android.launcher3.HolographicLinearLayout
-        style="@style/SearchButton"
-        launcher:sourceImageViewId="@+id/voice_button"
-        android:id="@+id/voice_button_container"
-        android:layout_width="@dimen/app_icon_size"
-        android:layout_height="match_parent"
-        android:layout_gravity="center_vertical"
-        android:layout_centerVertical="true"
-        android:layout_alignParentEnd="true"
-        android:paddingEnd="8dp"
-        android:paddingRight="8dp"
-        android:onClick="onClickVoiceButton"
-        android:focusable="true"
-        android:clickable="true"
-        android:contentDescription="@string/accessibility_voice_search_button">
-        <ImageView
-            android:id="@+id/voice_button"
-            android:layout_width="match_parent"
-            android:layout_height="match_parent"
-            android:layout_gravity="end"
-            android:scaleType="fitCenter"
-            android:src="@drawable/ic_home_voice_search_holo"
-            android:adjustViewBounds="true" />
-    </com.android.launcher3.HolographicLinearLayout>
-</RelativeLayout>
diff --git a/res/layout/apps_customize_pane.xml b/res/layout/apps_customize_pane.xml
index bf5f71b..e42576f 100644
--- a/res/layout/apps_customize_pane.xml
+++ b/res/layout/apps_customize_pane.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.AppsCustomizeTabHost
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:clipChildren="false">
 
     <LinearLayout
diff --git a/res/layout/apps_customize_widget.xml b/res/layout/apps_customize_widget.xml
index e299b32..a8344e3 100644
--- a/res/layout/apps_customize_widget.xml
+++ b/res/layout/apps_customize_widget.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.PagedViewWidget
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:layout_width="match_parent"
     android:layout_height="match_parent"
@@ -66,7 +66,7 @@
         android:background="@color/widget_text_panel"
         android:orientation="horizontal">
         <!-- The name of the widget. -->
-        <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        <TextView
             android:id="@+id/widget_name"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
@@ -85,7 +85,7 @@
 
         <!-- The original dimensions of the widget (can't be the same text as above due to different
              style. -->
-        <TextView xmlns:android="http://schemas.android.com/apk/res/android"
+        <TextView
             android:id="@+id/widget_dims"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
diff --git a/res/layout/drop_target_bar.xml b/res/layout/drop_target_bar.xml
deleted file mode 100644
index f38a500..0000000
--- a/res/layout/drop_target_bar.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT 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">
-    <FrameLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        style="@style/DropTargetButtonContainer"
-        android:layout_weight="1">
-        <!-- Delete target -->
-        <com.android.launcher3.DeleteDropTarget
-            style="@style/DropTargetButton"
-            android:id="@+id/delete_target_text"
-            android:text="@string/delete_zone_label_workspace"
-            android:drawableStart="@drawable/remove_target_selector" />
-    </FrameLayout>
-    <FrameLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        style="@style/DropTargetButtonContainer"
-        android:layout_weight="1">
-        <!-- Info target -->
-        <com.android.launcher3.InfoDropTarget
-            style="@style/DropTargetButton"
-            android:id="@+id/info_target_text"
-            android:text="@string/info_target_label"
-            android:drawableStart="@drawable/info_target_selector" />
-    </FrameLayout>
-</merge>
diff --git a/res/layout/hotseat.xml b/res/layout/hotseat.xml
index dc9ed2a..7bef889 100644
--- a/res/layout/hotseat.xml
+++ b/res/layout/hotseat.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.Hotseat
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
+    xmlns:launcher="http://schemas.android.com/apk/res-auto">
     <com.android.launcher3.CellLayout
         android:id="@+id/layout"
         android:layout_width="wrap_content"
diff --git a/res/layout/tab_widget_indicator.xml b/res/layout/launcher_overlay.xml
similarity index 78%
rename from res/layout/tab_widget_indicator.xml
rename to res/layout/launcher_overlay.xml
index de7c50e..b35a2d8 100644
--- a/res/layout/tab_widget_indicator.xml
+++ b/res/layout/launcher_overlay.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!-- Copyright (C) 2008 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -14,6 +14,7 @@
      limitations under the License.
 -->
 
-<com.android.launcher3.AccessibleTabView
+<com.android.launcher3.InsettableFrameLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/TabIndicator.AppsCustomize" />
+    android:layout_width="match_parent"
+    android:layout_height="match_parent" />
diff --git a/res/layout/launcher_overlay_example.xml b/res/layout/launcher_overlay_example.xml
new file mode 100644
index 0000000..7d92d4f
--- /dev/null
+++ b/res/layout/launcher_overlay_example.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<FrameLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    launcher:layout_ignoreInsets="true">
+
+    <FrameLayout
+        android:id="@+id/search_overlay"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:background="#ff00ff00"
+        android:visibility="invisible" />
+
+    <FrameLayout
+        android:id="@+id/search_box"
+        android:layout_width="match_parent"
+        android:layout_height="48dp"
+        android:layout_marginLeft="8dp"
+        android:layout_marginRight="8dp"
+        android:layout_marginTop="36dp"
+        android:background="#ffff0000" />
+</FrameLayout>
diff --git a/res/layout/market_button.xml b/res/layout/market_button.xml
deleted file mode 100644
index 41e6ec7..0000000
--- a/res/layout/market_button.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-<TextView
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    style="@style/MarketButton"
-    android:onClick="onClickAppMarketButton"
-    android:gravity="center"
-    android:paddingLeft="16dp"
-    android:paddingRight="16dp"
-    android:background="@drawable/tab_widget_indicator_selector"
-    android:contentDescription="@string/market"
-    android:shadowColor="@color/workspace_all_apps_and_delete_zone_text_shadow_color"
-    android:shadowDx="0.0"
-    android:shadowDy="0.0"
-    android:shadowRadius="2.0"
-    android:focusable="true"
-    android:clickable="true" />
diff --git a/res/layout/overview_panel.xml b/res/layout/overview_panel.xml
index 558900c..4b7423e 100644
--- a/res/layout/overview_panel.xml
+++ b/res/layout/overview_panel.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
+<!--
+     Copyright (C) 2013 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,47 +14,50 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<FrameLayout
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="wrap_content"
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:layout_gravity="center_horizontal|bottom"
-    android:orientation="horizontal">
+    android:gravity="top"
+    android:orientation="horizontal" >
 
     <TextView
         android:id="@+id/wallpaper_button"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_gravity="start|top"
-        android:text="@string/wallpaper_button_text"
+        android:layout_weight="1"
         android:drawablePadding="4dp"
         android:drawableTop="@drawable/wallpaper_button"
-        android:gravity="center_horizontal"
         android:fontFamily="sans-serif-condensed"
+        android:gravity="center_horizontal"
+        android:text="@string/wallpaper_button_text"
         android:textAllCaps="true"
         android:textSize="12sp" />
+
     <TextView
         android:id="@+id/widget_button"
-        android:layout_width="wrap_content"
+        android:layout_width="0dp"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_horizontal|top"
-        android:text="@string/widget_button_text"
+        android:layout_weight="1"
         android:drawablePadding="4dp"
-        android:gravity="center_horizontal"
         android:drawableTop="@drawable/widget_button"
         android:fontFamily="sans-serif-condensed"
-        android:textAllCaps="true"
-        android:textSize="12sp"/>
-    <TextView
-        android:id="@+id/settings_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="end|top"
-        android:text="@string/settings_button_text"
-        android:drawablePadding="4dp"
         android:gravity="center_horizontal"
-        android:drawableTop="@drawable/setting_button"
-        android:fontFamily="sans-serif-condensed"
+        android:text="@string/widget_button_text"
         android:textAllCaps="true"
         android:textSize="12sp" />
-</FrameLayout>
+
+    <TextView
+        android:id="@+id/settings_button"
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_weight="1"
+        android:drawablePadding="4dp"
+        android:drawableTop="@drawable/setting_button"
+        android:fontFamily="sans-serif-condensed"
+        android:gravity="center_horizontal"
+        android:text="@string/settings_button_text"
+        android:textAllCaps="true"
+        android:textSize="12sp" />
+
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/page_indicator.xml b/res/layout/page_indicator.xml
index 14eff75..68fe3dd 100644
--- a/res/layout/page_indicator.xml
+++ b/res/layout/page_indicator.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.PageIndicator
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:animateLayoutChanges="true"
     launcher:windowSize="@integer/config_maxNumberOfPageIndicatorsToShow">
 </com.android.launcher3.PageIndicator>
diff --git a/res/layout/page_indicator_marker.xml b/res/layout/page_indicator_marker.xml
index 7c0c389..686d275 100644
--- a/res/layout/page_indicator_marker.xml
+++ b/res/layout/page_indicator_marker.xml
@@ -15,7 +15,7 @@
 -->
 <com.android.launcher3.PageIndicatorMarker
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="16dp"
     android:layout_height="16dp"
     android:layout_gravity="center_vertical">
diff --git a/res/layout/search_drop_target_bar.xml b/res/layout/search_drop_target_bar.xml
index 2d51b93..af2d0163 100644
--- a/res/layout/search_drop_target_bar.xml
+++ b/res/layout/search_drop_target_bar.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!--
+     Copyright (C) 2011 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -13,21 +14,45 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<com.android.launcher3.SearchDropTargetBar
-    xmlns:android="http://schemas.android.com/apk/res/android"
-    android:orientation="horizontal"
-    android:focusable="false"
+<com.android.launcher3.SearchDropTargetBar xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:focusable="false"
+    android:orientation="horizontal" >
 
     <!-- Drag specific targets container -->
+
     <LinearLayout
         android:id="@+id/drag_target_bar"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:layout_gravity="center">
+        android:layout_gravity="center" >
 
-        <include
-            layout="@layout/drop_target_bar" />
+        <FrameLayout
+            style="@style/DropTargetButtonContainer"
+            android:layout_weight="1" >
+
+            <!-- Delete target -->
+
+            <com.android.launcher3.DeleteDropTarget
+                android:id="@+id/delete_target_text"
+                style="@style/DropTargetButton"
+                android:drawableStart="@drawable/remove_target_selector"
+                android:text="@string/delete_zone_label_workspace" />
+        </FrameLayout>
+
+        <FrameLayout
+            style="@style/DropTargetButtonContainer"
+            android:layout_weight="1" >
+
+            <!-- Info target -->
+
+            <com.android.launcher3.InfoDropTarget
+                android:id="@+id/info_target_text"
+                style="@style/DropTargetButton"
+                android:drawableStart="@drawable/info_target_selector"
+                android:text="@string/info_target_label" />
+        </FrameLayout>
     </LinearLayout>
-</com.android.launcher3.SearchDropTargetBar>
+
+</com.android.launcher3.SearchDropTargetBar>
\ No newline at end of file
diff --git a/res/layout/user_folder.xml b/res/layout/user_folder.xml
index 4e5303a..ed8d43e 100644
--- a/res/layout/user_folder.xml
+++ b/res/layout/user_folder.xml
@@ -16,7 +16,7 @@
 
 <com.android.launcher3.Folder
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:orientation="vertical"
@@ -45,6 +45,7 @@
         android:hint="@string/folder_hint_text"
         android:textSize="14sp"
         android:textColor="#ff777777"
+        android:textColorHint="#ff808080"
         android:textColorHighlight="#ffCCCCCC"
         android:textCursorDrawable="@null"
         android:gravity="center_horizontal"
diff --git a/res/layout/workspace_screen.xml b/res/layout/workspace_screen.xml
index 855cf39..83b319b 100644
--- a/res/layout/workspace_screen.xml
+++ b/res/layout/workspace_screen.xml
@@ -16,7 +16,7 @@
 
 <com.android.launcher3.CellLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3"
+    xmlns:launcher="http://schemas.android.com/apk/res-auto"
 
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
diff --git a/res/mipmap-hdpi/ic_launcher_application.png b/res/mipmap-hdpi/ic_launcher_application.png
deleted file mode 100644
index b9aa101..0000000
--- a/res/mipmap-hdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_application.png b/res/mipmap-mdpi/ic_launcher_application.png
deleted file mode 100644
index 4771b85..0000000
--- a/res/mipmap-mdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_application.png b/res/mipmap-xhdpi/ic_launcher_application.png
deleted file mode 100644
index 932f0f7..0000000
--- a/res/mipmap-xhdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_application.png b/res/mipmap-xxhdpi/ic_launcher_application.png
deleted file mode 100644
index 7fc739a..0000000
--- a/res/mipmap-xxhdpi/ic_launcher_application.png
+++ /dev/null
Binary files differ
diff --git a/res/values-af-land/strings.xml b/res/values-af-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-af-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 4a4bb78..f37f08f 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android-kernprogramme"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Program is nie geïnstalleer nie."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Program is nie beskikbaar nie"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Afgelaaide program in veiligmodus gedeaktiveer"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Legstukke gedeaktiveer in Veiligmodus"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Legstukke"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Legstukke"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Wys Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Raak en hou om \'n legstuk op te tel."</string>
-    <string name="market" msgid="2619650989819296998">"Winkel"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Kan nie item op hierdie Tuisskerm laat los nie."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Kies legstuk om te skep"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Verwyder"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Deïnstalleer"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Programinligting"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Soek"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Stemsoektog"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Programme"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Verwyder"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Deïnstalleer opdatering"</string>
diff --git a/res/values-am-land/strings.xml b/res/values-am-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-am-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index d77744c..1a25f66 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android ዋና መተግበሪያዎች"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"ፍርግሞች"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ፍርግሞች"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"ማህደረ ማስታወሻ አሳይ"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"ፍርግም ለማንሳት ይንኩ እና ይያዙት"</string>
-    <string name="market" msgid="2619650989819296998">"ግዛ"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"ንጥሉን እዚህ የመነሻ ማያ ገጽ ላይ ማኖር አልተቻለም።"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ለመፍጠር መግብር ይምረጡ"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"አስወግድ"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"አራግፍ"</string>
     <string name="info_target_label" msgid="8053346143994679532">"የመተግበሪያ መረጃ"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"ፍለጋ"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"የድምፅ ፍለጋ"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"መተግበሪያዎች"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"አስወግድ"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"ዝማኔ አራግፍ"</string>
@@ -96,7 +95,7 @@
     <string name="migration_cling_copy_apps" msgid="946331230090919440">"አዶዎችን ይቅዱ"</string>
     <string name="migration_cling_use_default" msgid="2626475813981258626">"እንደ አዲስ ይጀምሩ"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"ቦታዎን ያደራጁ"</string>
-    <string name="workspace_cling_move_item" msgid="528201129978005352">"የግድግዳ ወረቀት፣ ምግብሮችን እና ቅንብሮችን ለማቀናበር ጀርባውን ይንኩ እና ይያዙት።"</string>
+    <string name="workspace_cling_move_item" msgid="528201129978005352">"ልጣፍ ፣ ምግብሮችን እና ቅንብሮችን ለማቀናበር ጀርባውን ይንኩ እና ይያዙት።"</string>
     <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"የግድግዳ ወረቀቶች፣ ንዑስ ፕሮግራሞች እና ቅንብሮች"</string>
     <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"ለማበጀት ጀርባውን ነክተው ይያዙት"</string>
     <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ገባኝ"</string>
diff --git a/res/values-ar-land/strings.xml b/res/values-ar-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-ar-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 8b6aa02..592be58 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"‏تطبيقات Android الأساسية"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"الأدوات"</string>
     <string name="widget_adder" msgid="3201040140710381657">"الأدوات"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"عرض الذاكرة"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"المس مع الاستمرار لاختيار إحدى الأدوات."</string>
-    <string name="market" msgid="2619650989819296998">"تسوق"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"تعذر إسقاط العنصر على هذه الشاشة الرئيسية."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"اختيار أداة لإنشائها"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"إزالة"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"إزالة"</string>
     <string name="info_target_label" msgid="8053346143994679532">"معلومات عن التطبيق"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"بحث"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"البحث الصوتي"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"التطبيقات"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"إزالة"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"إزالة التحديث"</string>
diff --git a/res/values-bg-land/strings.xml b/res/values-bg-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-bg-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index dcd1930..3f710db 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Основни приложения на Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"Приспособления"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Приспособления"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Показване на паметта"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Докоснете и задръжте за избор на приспособление."</string>
-    <string name="market" msgid="2619650989819296998">"Пазаруване"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Не можа да се премести на този начален екран."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Избор на приспособл. за създаване"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Премахване"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Деинсталиране"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Информация за приложението"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Търсене"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Гласово търсене"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Приложения"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Премахване"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Деинст. на актуализацията"</string>
diff --git a/res/values-bn-rBD/strings.xml b/res/values-bn-rBD/strings.xml
index f60f1c5..1434201 100644
--- a/res/values-bn-rBD/strings.xml
+++ b/res/values-bn-rBD/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android প্রাথমিক অ্যাপ্লিকেশানগুলি"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"উইজেটগুলি"</string>
     <string name="widget_adder" msgid="3201040140710381657">"উইজেটগুলি"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"মেম দেখান"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"একটি উইজেট তুলতে তা স্পর্শ করে ধরে রাখুন৷"</string>
-    <string name="market" msgid="2619650989819296998">"দোকান"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"এই হোম স্ক্রীনে আইটেম রাখা যায়নি৷"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"তৈরি করেতে উইজেট চয়ন করুন"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"সরান"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"আনইনস্টল করুন"</string>
     <string name="info_target_label" msgid="8053346143994679532">"অ্যাপ্লিকেশানের তথ্য"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"অনুসন্ধান করুন"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ভয়েস অনুসন্ধান"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"অ্যাপ্লিকেশানগুলি"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"সরান"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"আপডেট আনইনস্টল করুন"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"হোম সেটিংস এবং শর্টকাটগুলি লেখে"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"হোমে অ্যাপ্লিকেশানটিকে সেটিংস এবং শর্টকাটগুলি পরিবর্তন করতে দেয়৷"</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="dream_name" msgid="1530253749244328964">"রকেট লঞ্চার"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"নামবিহীন ফোল্ডার"</string>
@@ -96,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"নতুন করে শুরু করুন"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"আপনার স্থান সংগঠিত করুন"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"ওয়ালপেপার, উইজেট এবং সেটিংস পরিচালনা করতে পটভূমি স্পর্শ করে ধরে রাখুন৷"</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"ওয়ালপেপার, উইজেট এবং সেটিংস"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"কাস্টমাইজ করার জন্য পটভূমি স্পর্শ করে ধরে থাকুন"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"বুঝেছি"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"এখানে একটি ফোল্ডার আছে"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"এটির মতো একটি তৈরি করতে, একটি অ্যাপ্লিকেশান স্পর্শ করে ধরে রাখুন, এবং তারপরে এটিকে অন্য একটির উপরে সরিয়ে নিয়ে যান৷"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ঠিক আছে"</string>
diff --git a/res/values-ca-land/strings.xml b/res/values-ca-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-ca-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 6d10235..89e582a 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Aplicacions principals d\'Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"L\'aplicació no s\'ha instal·lat."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"L\'aplicació no està disponible."</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'aplicació que has baixat està desactivada al mode segur."</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"En Mode segur, els widgets estan desactivats."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostra la memòria"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén premut un widget per triar-lo."</string>
-    <string name="market" msgid="2619650989819296998">"Compra"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"No s\'ha pogut deixar anar l\'element a Inici."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Tria el widget que vulguis crear"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Suprimeix"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstal·la"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Informació de l\'aplicació"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Cerca"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Cerca per veu"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicacions"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Suprimeix"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstal·la l\'actualització"</string>
diff --git a/res/values-cs-land/strings.xml b/res/values-cs-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-cs-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index f729a46..69ec22c 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikace není nainstalována."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Aplikace není k dispozici."</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Stažená aplikace je v nouzovém režimu zakázána"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"V Bezpečném režimu jsou widgety zakázány."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgety"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgety"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Zobrazit Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Widget vyberete dotykem a podržením."</string>
-    <string name="market" msgid="2619650989819296998">"Obchod"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Na tuto plochu položku nelze přesunout."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Vyberte widget k vytvoření"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Odstranit"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Odinstalovat"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Informace o aplikaci"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Hledat"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Hlasové vyhledávání"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikace"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Odstranit"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Odinstalovat aktualizaci"</string>
diff --git a/res/values-da-land/strings.xml b/res/values-da-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-da-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 85159b2..5fa6aa6 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Kerneapps i Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installeret."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Appen er ikke tilgængelig"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloadet app er deaktiveret i sikker tilstand"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets er deaktiveret i Beskyttet tilstand"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Vis Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Tryk på en widget, og hold den nede for at vælge."</string>
-    <string name="market" msgid="2619650989819296998">"Køb i Google Play Butik"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Elementet kunne ikke trækkes til startskærmen."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Vælg den widget, du vil oprette"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Fjern"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Afinstaller"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Oplysninger om appen"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Søg"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Stemmesøgning"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Fjern"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Afinstaller opdatering"</string>
diff --git a/res/values-de-land/strings.xml b/res/values-de-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-de-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index 698a254..059983e 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"App ist nicht installiert."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"App nicht verfügbar"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Heruntergeladene App im abgesicherten Modus deaktiviert"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets im abgesicherten Modus deaktiviert"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Speicher anzeigen"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Zum Hinzufügen Widget berühren und halten"</string>
-    <string name="market" msgid="2619650989819296998">"Einkaufen"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Element wurde nicht auf diesem Startbildschirm abgelegt."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Widget zum Erstellen auswählen"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Entfernen"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Deinstallieren"</string>
     <string name="info_target_label" msgid="8053346143994679532">"App-Info"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Suchen"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Sprachsuche"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Entfernen"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Update deinstallieren"</string>
diff --git a/res/values-el-land/strings.xml b/res/values-el-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-el-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 3eec27d..12f0dfe 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Βασικές εφαρμογές Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"Γραφικά στοιχεία"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Γραφικά στοιχεία"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Εμφάνιση Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Αγγίξτε παρατεταμένα για να πάρετε ένα γραφ.στοιχ."</string>
-    <string name="market" msgid="2619650989819296998">"Αγορά"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Αδυναμία τοποθέτησης στοιχείου στην Αρχική οθόνη."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Επιλ. γραφ. στοιχείο για δημιουργία"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Κατάργηση"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Κατάργηση εγκατάστασης"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Πληροφορίες εφαρμογής"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Αναζήτηση"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Φωνητική αναζήτηση"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Εφαρμογές"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Κατάργηση"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Κατάργηση εγκατάστασης ενημέρωσης"</string>
diff --git a/res/values-en-rGB-land/strings.xml b/res/values-en-rGB-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-en-rGB-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 615e5c9..0d004fe 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"App isn\'t available"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloaded app disabled in Safe mode"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets disabled in Safe mode"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Show Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Touch &amp; hold to pick up a widget."</string>
-    <string name="market" msgid="2619650989819296998">"Shop"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Couldn\'t drop item on this Home screen."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Choose widget to create"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Remove"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Uninstall"</string>
     <string name="info_target_label" msgid="8053346143994679532">"App info"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Search"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Voice Search"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Remove"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Uninstall update"</string>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 615e5c9..0d004fe 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"App isn\'t installed."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"App isn\'t available"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Downloaded app disabled in Safe mode"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets disabled in Safe mode"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Show Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Touch &amp; hold to pick up a widget."</string>
-    <string name="market" msgid="2619650989819296998">"Shop"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Couldn\'t drop item on this Home screen."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Choose widget to create"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Remove"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Uninstall"</string>
     <string name="info_target_label" msgid="8053346143994679532">"App info"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Search"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Voice Search"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Remove"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Uninstall update"</string>
diff --git a/res/values-es-land/strings.xml b/res/values-es-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-es-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-es-rUS-land/strings.xml b/res/values-es-rUS-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-es-rUS-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 31afa3e..4408080 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Aplicaciones básicas de Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"No se instaló la aplicación."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"La aplicación no está disponible."</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicación descargada inhabilitada en modo seguro"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets inhabilitados en modo seguro"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar memoria"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén presionado el widget que desees elegir."</string>
-    <string name="market" msgid="2619650989819296998">"Comprar"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Error al soltar elemento en la pantalla principal"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Elegir los widgets para crear"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Eliminar"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Información de la aplicación"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Buscar"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Búsqueda por voz"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicaciones"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Eliminar"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar actualización"</string>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 4e91412..898d0ea 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Aplicaciones básicas de Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"La aplicación no está instalada."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"La aplicación no está disponible"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicación descargada inhabilitada en modo seguro"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets inhabilitados en modo seguro"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar memoria"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén pulsado el widget que quieras seleccionar."</string>
-    <string name="market" msgid="2619650989819296998">"Tienda"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Error al arrastrar elemento a pantalla de inicio."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Selecciona widget a añadir"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Eliminar"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Información de la aplicación"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Buscar"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Búsqueda por voz"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicaciones"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Eliminar"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar actualización"</string>
diff --git a/res/values-et-rEE/strings.xml b/res/values-et-rEE/strings.xml
index fa352a1..76b20ab 100644
--- a/res/values-et-rEE/strings.xml
+++ b/res/values-et-rEE/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Androidi tuumrakendused"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Rakendus pole installitud."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Rakendus ei ole saadaval"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Allalaetud rakendus on turvarežiimis keelatud"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Turvarežiimis on vidinad keelatud"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Vidinad"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Vidinad"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mälu kuvamine"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidina valimiseks vajutage ja hoidke seda all."</string>
-    <string name="market" msgid="2619650989819296998">"Pood"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Üksust ei saanud sellele avaekraanile tuua."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Valige loomiseks vidin"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Eemalda"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalli"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Rakenduse teave"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Otsing"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Häälotsing"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Rakendused"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Eemalda"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalli värskendus"</string>
diff --git a/res/values-eu-rES/strings.xml b/res/values-eu-rES/strings.xml
index 4a4c959..e02479c 100644
--- a/res/values-eu-rES/strings.xml
+++ b/res/values-eu-rES/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android-en nukleoko aplikazioak"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikazioa instalatu gabe dago."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Ez dago erabilgarri aplikazioa"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Deskargatutako aplikazioa modu seguruan desgaitu da"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgetak desgaitu egin dira modu seguruan"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgetak"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgetak"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Erakutsi memoria"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Eduki ukituta widgeta aukeratzeko."</string>
-    <string name="market" msgid="2619650989819296998">"Denda"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Ezin izan da elementua hasierako pantailan jaregin."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Aukeratu sortu beharreko widgeta"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Kendu"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalatu"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Aplikazioaren informazioa"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Bilaketa"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ahots bidezko bilaketa"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikazioak"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Kendu"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalatu eguneratzea"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"Idatzi hasierako ezarpenak eta lasterbideak"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Hasierako pantailako ezarpenak eta lasterbideak aldatzea baimentzen die aplikazioei."</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Arazo bat izan da widgeta kargatzean"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Konfigurazioa"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Sistema-aplikazioa da hau eta ezin da desinstalatu."</string>
     <string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Izenik gabeko karpeta"</string>
@@ -86,7 +86,7 @@
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"%1$d/%2$d aplikazio-orria"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"%1$d/%2$d widget-orria"</string>
     <string name="first_run_cling_title" msgid="2459738000155917941">"Ongi etorri"</string>
-    <string name="first_run_cling_description" msgid="6447072552696253358">"Senti zaitez etxean bezala."</string>
+    <string name="first_run_cling_description" msgid="6447072552696253358">"Pertsonalizatu hasierako pantaila nahieran."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Sortu pantaila gehiago aplikazioak eta karpetak ezartzeko"</string>
@@ -96,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"HASI HUTSETIK"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Antolatu zure txokoa"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Eduki ukituta atzeko planoa horma-paperak, widgetak eta ezarpenak kudeatzeko."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Horma-paperak, widgetak eta ezarpenak"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Pertsonalizatzeko, eduki ukituta atzeko planoa"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ADOS"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Hortxe duzu karpeta"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Horrelako bat sortzeko, eduki ukituta aplikazio bat eta eraman beste baten gainera."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Ados"</string>
diff --git a/res/values-fa-land/strings.xml b/res/values-fa-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-fa-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 13f40e2..924cccf 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"‏برنامه‌های Android Core"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"ابزارک‌ها"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ابزارک‌ها"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"‏نمایش Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"برای انتخاب ابزارک لمس کنید و نگه دارید."</string>
-    <string name="market" msgid="2619650989819296998">"فروشگاه"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"این مورد را نمی‌توان در این صفحه اصلی رها کرد."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"انتخاب ابزارکی که باید ایجاد شود"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"حذف"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"حذف نصب"</string>
     <string name="info_target_label" msgid="8053346143994679532">"اطلاعات برنامه"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"جستجو"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"جستجوی شفاهی"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"برنامه‌ها"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"حذف"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"حذف نصب به‌روزرسانی"</string>
diff --git a/res/values-fi-land/strings.xml b/res/values-fi-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-fi-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 3990a16..a5da03f 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Androidin ydinsovellukset"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Sovellusta ei ole asennettu."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Sovellus ei ole käytettävissä"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Ladattu sovellus poistettiin käytöstä suojatussa tilassa"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgetit poistettu käytöstä vikasietotilassa"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgetit"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgetit"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Näytä muisti"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Valitse widget painamalla sitä pitkään."</string>
-    <string name="market" msgid="2619650989819296998">"Kauppa"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Kohteen lisääminen tähän aloitusruutuun epäonnistui."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Valitse luotava widget"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Poista"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Poista"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Sovelluksen tiedot"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Haku"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Puhehaku"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Sovellukset"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Poista"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Poista päivitys"</string>
diff --git a/res/values-fr-land/strings.xml b/res/values-fr-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-fr-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index f428350..62a2b89 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Applications de base Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Application indisponible"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'application téléchargée est désactivée en mode sécurisé."</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets désactivés en mode sans échec"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Afficher la mémoire"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Maintenez un doigt sur le widget pour l\'ajouter."</string>
-    <string name="market" msgid="2619650989819296998">"Magasiner"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Imposs. de déposer l\'élément sur l\'écran d\'accueil"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Sélectionnez le widget à créer"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Supprimer"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Désinstaller"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Détails de l\'application"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Rechercher"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Recherche vocale"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Applications"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Supprimer"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Désinstaller la mise à jour"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 31448f1..d23b6a4 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Applications de base Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"L\'application n\'est pas installée."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Application indisponible"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'application téléchargée est désactivée en mode sécurisé."</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Les widgets sont désactivés en mode sécurisé."</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Afficher la mémoire"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"App. de manière prolongée pour sélectionner widget."</string>
-    <string name="market" msgid="2619650989819296998">"Boutique"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Impossible de déposer élément sur écran d\'accueil."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Sélectionner le widget à créer"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Supprimer"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Désinstaller"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Informations sur l\'application"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Rechercher"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Recherche vocale"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Applications"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Supprimer"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Désinstaller la mise à jour"</string>
diff --git a/res/values-gl-rES/strings.xml b/res/values-gl-rES/strings.xml
index c053b07..96a53dc 100644
--- a/res/values-gl-rES/strings.xml
+++ b/res/values-gl-rES/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Aplicacións básicas de Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"A aplicación non está instalada"</string>
-    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Desactivouse a aplicación descargada no modo seguro"</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"A aplicación non está dispoñible"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"A aplicación que descargaches está desactivada no modo seguro"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Os widgets están desactivados no modo seguro"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar memoria"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Mantén premido un widget para seleccionalo."</string>
-    <string name="market" msgid="2619650989819296998">"Tenda"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Non se puido engadir á pantalla de inicio."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Escolle o widget que queiras crear"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Eliminar"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Información da aplicación"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Buscar"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Busca de voz"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicacións"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Eliminar"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar actualización"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"modificar a configuración e os atallos da pantalla de inicio"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite a unha aplicación cambiar a configuración e os atallos da pantalla de inicio."</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Produciuse un problema ao cargar o widget"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Configuración"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Esta aplicación é do sistema e non se pode desinstalar."</string>
     <string name="dream_name" msgid="1530253749244328964">"Lanzacohetes"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Cartafol sen nome"</string>
@@ -96,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"COMEZAR DE CERO"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Organiza o espazo"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Mantén premido o fondo para xestionar o fondo de pantalla e máis."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Fondos pantalla, widgets e configuración"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Mantén tocado o segundo plano para personalizar"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"DE ACORDO"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Isto é un cartafol"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Para crear un igual, mantén premida a aplicación e móvea sobre outra."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Aceptar"</string>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 9058b78..9372489 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -24,23 +24,24 @@
     <string name="uid_name" msgid="7820867637514617527">"Android के मुख्य ऐप्लिकेशन"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"विजेट"</string>
-    <string name="widget_adder" msgid="3201040140710381657">"विजेट"</string>
-    <string name="toggle_weight_watcher" msgid="5645299835184636119">"स्मृति दिखाएं"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"विजेट सुरक्षित मोड में अक्षम हैं"</string>
+    <string name="widgets_tab_label" msgid="2921133187116603919">"शॉर्टकट"</string>
+    <string name="widget_adder" msgid="3201040140710381657">"शॉर्टकट"</string>
+    <string name="toggle_weight_watcher" msgid="5645299835184636119">"मेमोरी दिखाएं"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"विजेट को चुनने के लिए स्‍पर्श करके रखें."</string>
-    <string name="market" msgid="2619650989819296998">"खरीदारी करें"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"आइटम को इस होम स्‍क्रीन पर नहीं छोड़ा जा सका."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"बनाने के लिए विजेट चुनें"</string>
     <string name="rename_folder_label" msgid="3727762225964550653">"फ़ोल्‍डर का नाम"</string>
     <string name="rename_folder_title" msgid="3771389277707820891">"फ़ोल्‍डर का नाम बदलें"</string>
     <string name="rename_action" msgid="5559600076028658757">"ठीक"</string>
-    <string name="cancel_action" msgid="7009134900002915310">"रद्द करें"</string>
+    <string name="cancel_action" msgid="7009134900002915310">"रहने दें"</string>
     <string name="menu_item_add_item" msgid="1264911265836810421">"होम स्‍क्रीन में जोड़ें"</string>
     <string name="group_applications" msgid="3797214114206693605">"ऐप्लिकेशन"</string>
     <string name="group_shortcuts" msgid="6012256992764410535">"शॉर्टकट"</string>
-    <string name="group_widgets" msgid="1569030723286851002">"विजेट"</string>
+    <string name="group_widgets" msgid="1569030723286851002">"शॉर्टकट"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"आपकी होम स्‍क्रीन पर स्थान शेष नहीं है."</string>
     <string name="out_of_space" msgid="4691004494942118364">"इस होम स्‍क्रीन पर स्थान शेष नहीं है."</string>
     <string name="hotseat_out_of_space" msgid="7448809638125333693">"पसंदीदा ट्रे में और स्थान नहीं है"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"निकालें"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"अनइंस्टॉल करें"</string>
     <string name="info_target_label" msgid="8053346143994679532">"ऐप्लिकेशन की जानकारी"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"खोजें"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"बोलकर खोजें"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"ऐप्लिकेशन"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"निकालें"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"अपडेट अनइंस्‍टॉल करें"</string>
@@ -85,7 +84,7 @@
     <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="apps_customize_apps_scroll_format" msgid="370005296147130238">"ऐप्लिकेशन पृष्ठ %2$d में से %1$d"</string>
-    <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"विजेट पृष्ठ %2$d में से %1$d"</string>
+    <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"शॉर्टकट %2$d में से %1$d"</string>
     <string name="first_run_cling_title" msgid="2459738000155917941">"स्वागत है"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"जैसा चाहें वैसा उपयोग करें."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
@@ -96,8 +95,8 @@
     <string name="migration_cling_copy_apps" msgid="946331230090919440">"आइकन की प्रतिलिपि बनाएं"</string>
     <string name="migration_cling_use_default" msgid="2626475813981258626">"फिर से शुरू करें"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"अपने स्थान को व्यवस्थित करें"</string>
-    <string name="workspace_cling_move_item" msgid="528201129978005352">"वॉलपेपर, विजेट और सेटिंग प्रबंधित करने के लिए पृष्ठभूमि को स्पर्श करके रखें."</string>
-    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"वॉलपेपर, विजेट और सेटिंग"</string>
+    <string name="workspace_cling_move_item" msgid="528201129978005352">"वॉलपेपर, शॉर्टकट और सेटिंग प्रबंधित करने के लिए पृष्ठभूमि को स्पर्श करके रखें."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"वॉलपेपर, शॉर्टकट और सेटिंग"</string>
     <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"पृष्ठभूमि कस्टमाइज़ करने के लिए स्पर्श करके रखें"</string>
     <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"समझ लिया"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"यहां एक फ़ोल्डर है"</string>
@@ -109,7 +108,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="8119458837558863227">"सेटिंग"</string>
     <string name="package_state_enqueued" msgid="6227252464303085641">"प्रतीक्षा में"</string>
diff --git a/res/values-hr-land/strings.xml b/res/values-hr-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-hr-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index c881077..702b474 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Matične aplikacije za Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacija nije instalirana."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Aplikacija nije dostupna"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Preuzeta aplikacija onemogućena je u Sigurnom načinu rada"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgeti su onemogućeni u Sigurnom načinu rada"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgeti"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgeti"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Prikaži mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Dodirnite i držite kako biste podigli widget."</string>
-    <string name="market" msgid="2619650989819296998">"Kupi"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Stavka nije ispuštena na ovaj početni zaslon."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Odabir widgeta za stvaranje"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Ukloni"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Deinstaliraj"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Informacije o aplikaciji"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Pretraži"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Glasovno pretraživanje"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikacije"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Ukloni"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Deinstalacija ažuriranja"</string>
diff --git a/res/values-hu-land/strings.xml b/res/values-hu-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-hu-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 08d3095..513548a 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Alap Android-alkalmazások"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Az alkalmazás nincs telepítve."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Az alkalmazás nem érhető el"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"A letöltött alkalmazás Csökkentett módban ki van kapcsolva"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"A modulok ki vannak kapcsolva Csökkentett módban"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Modulok"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Modulok"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem. megjelenítése"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Modul felvételéhez érintse meg, és tartsa lenyomva"</string>
-    <string name="market" msgid="2619650989819296998">"Vásárlás"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Nem lehet elemeket dobni erre a kezdőképernyőre."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"A létrehozáshoz válasszon modult"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Eltávolítás"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Eltávolítás"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Alkalmazásinformáció"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Keresés"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Hangalapú keresés"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Alkalmazások"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Eltávolítás"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Eltávolítja a frissítést"</string>
diff --git a/res/values-hy-rAM/strings.xml b/res/values-hy-rAM/strings.xml
index 4ec39c8..940c14b 100644
--- a/res/values-hy-rAM/strings.xml
+++ b/res/values-hy-rAM/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"Վիջեթներ"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Վիջեթներ"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Ցուցադրել մեմը"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Հպեք և պահեք՝ վիջեթն ընտրելու համար:"</string>
-    <string name="market" msgid="2619650989819296998">"Խանութ"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Հնարավոր չէ տեղադրել տարրն այս հիմնական էկրանին:"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Ստեղծելու համար ընտրեք վիջեթը"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Հեռացնել"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Ապատեղադրել"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Ծրագրի տեղեկություններ"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Որոնել"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ձայնային որոնում"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Ծրագրեր"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Հեռացնել"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Ապատեղադրել թարմացումը"</string>
diff --git a/res/values-in-land/strings.xml b/res/values-in-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-in-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 137e3cc..b0c5d13 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Aplikasi Inti Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikasi tidak dipasang."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Aplikasi tidak tersedia"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplikasi yang diunduh dinonaktifkan dalam mode Aman"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widget dinonaktifkan dalam mode Aman"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Tampilkan Memori"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Sentuh lama untuk memilih widget."</string>
-    <string name="market" msgid="2619650989819296998">"Belanja"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Tidak dapat melepas item ke layar Utama ini."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Pilih widget untuk membuat"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Hapus"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Copot pemasangan"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Info aplikasi"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Telusuri"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Penelusuran Suara"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikasi"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Hapus"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Copot pemasangan pembaruan"</string>
diff --git a/res/values-is-rIS/strings.xml b/res/values-is-rIS/strings.xml
index 71f0ede..a3fa0bc 100644
--- a/res/values-is-rIS/strings.xml
+++ b/res/values-is-rIS/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Kjarnaforrit Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Forritið er ekki uppsett."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Forritið er ekki í boði"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Sótt forrit er óvirkt í öryggisstillingu"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Græjur eru óvirkar í öruggri stillingu"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Græjur"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Græjur"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Sýna minni"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Haltu fingri á græju til að grípa hana."</string>
-    <string name="market" msgid="2619650989819296998">"Verslun"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Ekki er hægt að sleppa atriði á þennan heimaskjá."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Veldu græju til að búa til"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Fjarlægja"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Eyða"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Upplýsingar um forrit"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Leita"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Raddleit"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Forrit"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Fjarlægja"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Fjarlægja uppfærslu"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"skrifa stillingar og flýtileiðir heimaskjás"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Leyfir forriti að breyta stillingum og flýtileiðum heimaskjás."</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Vandamál við að hlaða græju"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Uppsetning"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Þetta er kerfisforrit sem ekki er hægt að fjarlægja."</string>
     <string name="dream_name" msgid="1530253749244328964">"Eldflaugapallur"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Ónefnd mappa"</string>
@@ -96,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"BYRJA UPP Á NÝTT"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Settu hlutina á sína staði"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Haltu inni á bakgrunni til að stjórna veggfóðri, græjum og stillingum."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Veggfóður, græjur og stillingar"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Haltu fingri á bakgrunninum til að sérsníða hann"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ÉG SKIL"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Hér er mappa"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Til að búa til svona skaltu draga forrit yfir á annað forrit."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Í lagi"</string>
diff --git a/res/values-it-land/strings.xml b/res/values-it-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-it-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index b01b251..d78d032 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Applicazioni di base Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"App non installata."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"App non disponibile"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"L\'app scaricata è stata disattivata in modalità provvisoria"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widget disabilitati in modalità provvisoria"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostra Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Tocca e tieni premuto per scegliere un widget."</string>
-    <string name="market" msgid="2619650989819296998">"Acquista"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Rilascio elemento in schermata Home non riuscito."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Scegli il widget da creare"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Rimuovi"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Disinstalla"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Informazioni app"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Cerca"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ricerca vocale"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"App"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Rimuovi"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Disinstalla aggiornamento"</string>
diff --git a/res/values-iw-land/strings.xml b/res/values-iw-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-iw-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 6318207..61fb53e 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"‏אפליקציות הליבה של Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"רכיבי ווידג\'ט"</string>
     <string name="widget_adder" msgid="3201040140710381657">"רכיבי ווידג\'ט"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"הצג זכרון"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"גע נגיעה רציפה בווידג\'ט כדי לבחור בו."</string>
-    <string name="market" msgid="2619650989819296998">"קנה"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"לא ניתן היה לשחרר את הפריט במסך דף הבית הזה."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"בחר ווידג\'ט ליצירה"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"הסר"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"הסר התקנה"</string>
     <string name="info_target_label" msgid="8053346143994679532">"פרטי אפליקציה"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"חפש"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"חיפוש קולי"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"אפליקציות"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"הסר"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"הסר את התקנת העדכון"</string>
diff --git a/res/values-ja-land/strings.xml b/res/values-ja-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-ja-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 232845a..ec872b8 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"ウィジェット"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ウィジェット"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"メモリーを表示"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"ウィジェットを追加するには押し続けます。"</string>
-    <string name="market" msgid="2619650989819296998">"ショップ"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$dx%2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"このホーム画面にアイテムをドロップできませんでした"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"作成するウィジェットの選択"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"削除"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"アンインストール"</string>
     <string name="info_target_label" msgid="8053346143994679532">"アプリ情報"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"検索"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"音声検索"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"アプリ"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"削除"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"更新をアンインストール"</string>
diff --git a/res/values-ka-rGE/strings.xml b/res/values-ka-rGE/strings.xml
index 2fb51f5..b96d3d2 100644
--- a/res/values-ka-rGE/strings.xml
+++ b/res/values-ka-rGE/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android-ის ბირთვის აპები"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"ვიჯეტები"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ვიჯეტები"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem-ის ჩვენება"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"შეეხეთ და დააყოვნეთ ვიჯეტის ასარჩევად."</string>
-    <string name="market" msgid="2619650989819296998">"მაღაზია"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"ერთეულის მთავარ ეკრანზე ჩაგდება ვერ მოხერხდა."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"აირჩიეთ ვიჯეტი შესაქმნელად"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"წაშლა"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"დეინსტალაცია"</string>
     <string name="info_target_label" msgid="8053346143994679532">"აპის შესახებ"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"ძიება"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ხმოვანი ძიება"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"აპები"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"წაშლა"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"განახლების დეინსტალაცია"</string>
diff --git a/res/values-kk-rKZ/strings.xml b/res/values-kk-rKZ/strings.xml
index 288129a..c5b5a62 100644
--- a/res/values-kk-rKZ/strings.xml
+++ b/res/values-kk-rKZ/strings.xml
@@ -24,13 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core қолданбалары"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Қолданба орнатылмаған."</string>
-    <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
-    <skip />
+    <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="widgets_tab_label" msgid="2921133187116603919">"Виджеттер"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Виджеттер"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Жадты көрсету"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетті таңдау үшін түртіп, мықтап ұстаңыз."</string>
-    <string name="market" msgid="2619650989819296998">"Дүкен"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Элементті осы Негізгі Экранға тастау орындалмады."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Жасақтау үшін виджет таңдау"</string>
@@ -58,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Алып тастау"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Алмау"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Қолданба ақпары"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Іздеу"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Дауыс арқылы іздеу"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Қолданбалар"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Алып тастау"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Жаңартуды алмау"</string>
@@ -78,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"Негізгі экран параметрлері мен төте пернелерін жазу"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Қолданбаға Негізгі экрандағы параметрлер мен төте пернелерді өзгерту мүмкіндігін береді."</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="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Атауы жоқ қалта"</string>
@@ -97,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"ЖАҢАДАН БАСТАУ"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Кеңістікті реттеу"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Артқы фонды, виджеттерді және параметрлерді басқару үшін артқы шебін түртіп, мықтап ұстаңыз."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Тұсқағаздар, виджеттер және параметрлер"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Теңшеу үшін фонды түртіп, ұстап тұрыңыз"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ТҮСІНДІМ"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Міне, қалта."</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Осы сияқты қалта жасау үшін, қолданбаны түртіп, мықтап ұстаңыз, одан кейін екіншісінің үстінен жылжытыңыз."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Жарайды"</string>
diff --git a/res/values-km-rKH/strings.xml b/res/values-km-rKH/strings.xml
index bcd6060..3a1c82d 100644
--- a/res/values-km-rKH/strings.xml
+++ b/res/values-km-rKH/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"កម្មវិធី​​សំខាន់​ៗ​របស់ Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"ធាតុ​ក្រាហ្វិក"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ធាតុ​ក្រាហ្វិក"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"បង្ហាញ​ Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"ប៉ះ &amp; សង្កត់ ដើម្បី​ជ្រើស​ធាតុ​ក្រាហ្វិក។"</string>
-    <string name="market" msgid="2619650989819296998">"ហាងទំនិញ"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"មិន​អាច​ទម្លាក់​ធាតុ​លើ​អេក្រង់​ដើម​នេះ​ទេ"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ជ្រើស​ធាតុ​ក្រាហ្វិក ដើម្បី​​​បង្កើត"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"លុប​ចេញ"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"លុប"</string>
     <string name="info_target_label" msgid="8053346143994679532">"ព័ត៌មាន​កម្មវិធី"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"ស្វែងរក"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ស្វែងរក​តាម​សំឡេង"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"កម្មវិធី"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"លុប​ចេញ"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"លុប​បច្ចុប្បន្នភាព"</string>
@@ -86,7 +85,7 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"អេក្រង់​ដើម %1$d នៃ %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"ទំព័រ​កម្មវិធី %1$d នៃ %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"ទំព័រ​ធាតុ​ក្រាហ្វិក ​%1$d នៃ %2$d"</string>
-    <string name="first_run_cling_title" msgid="2459738000155917941">"សូម​ស្វាគមន៍​"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"សូម​ស្វាគមន៍"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"ធ្វើ​ដោយ​ខ្លួន​ឯង​នៅ​លើ​អេក្រង់​ដើម។"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
diff --git a/res/values-kn-rIN/strings.xml b/res/values-kn-rIN/strings.xml
index e84ece0..7a07051 100644
--- a/res/values-kn-rIN/strings.xml
+++ b/res/values-kn-rIN/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"ವಿಜೆಟ್‌ಗಳು"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ವಿಜೆಟ್‌ಗಳು"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"ಸ್ಮರಣೆ ತೋರಿಸು"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"ವಿಜೆಟ್ ಅನ್ನು ಆರಿಸಿಕೊಳ್ಳಲು ಸ್ಪರ್ಶಿಸಿ &amp; ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
-    <string name="market" msgid="2619650989819296998">"ಶಾಪ್‌"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"ಈ ಮುಖಪುಟದ ಪರದೆಯಲ್ಲಿ ಐಟಂ ಅನ್ನು ಬಿಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ರಚಿಸಲು ವಿಜೆಟ್‌ ಆಯ್ಕೆಮಾಡಿ"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"ತೆಗೆದುಹಾಕು"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"ಅಸ್ಥಾಪಿಸು"</string>
     <string name="info_target_label" msgid="8053346143994679532">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"ಹುಡುಕು"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ಧ್ವನಿ ಹುಡುಕಾಟ"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"ಅಪ್ಲಿಕೇಶನ್‌ಗಳು"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"ತೆಗೆದುಹಾಕು"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"ನವೀಕರಣವನ್ನು ಅಸ್ಥಾಪಿಸು"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"ಮುಖಪುಟದ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬರೆಯಿರಿ"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"ಮುಖಪುಟದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್‌ಗಳು ಮತ್ತು ಶಾರ್ಟ್‌ಕಟ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್‌ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ."</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="dream_name" msgid="1530253749244328964">"ರಾಕೆಟ್ ಲಾಂಚರ್"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"ಹೆಸರಿಲ್ಲದ ಫೋಲ್ಡರ್"</string>
@@ -96,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"ಹೊಸದಾಗಿ ಪ್ರಾರಂಭಿಸು"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"ನಿಮ್ಮ ಸ್ಥಳವನ್ನು ವ್ಯವಸ್ಥಿತಗೊಳಿಸಿ"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"ವಾಲ್‌ಪೇಪರ್‌, ವಿಜೆಟ್‌ಗಳು ಮತ್ತು ಸೆಟ್ಟಿಂಗ್‌ಗಳನ್ನು ನಿರ್ವಹಿಸಲು ಹಿನ್ನೆಲೆಯನ್ನು ಸ್ಪರ್ಶಿಸಿ &amp; ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"ವಾಲ್‌ಪೇಪರ್‌ಗಳು, ವಿಜೆಟ್‌ಗಳು, &amp; ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"ಕಸ್ಟಮೈಸ್ ಮಾಡಲು ಹಿನ್ನೆಲೆಯನ್ನು ಸ್ಪರ್ಶಿಸಿ &amp; ಒತ್ತಿ ಹಿಡಿಯಿರಿ"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ಅರ್ಥವಾಯಿತು"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"ಇಲ್ಲೊಂದು ಫೋಲ್ಡರ್ ಇದೆ"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"ಈ ರೀತಿ ರಚಿಸಲು, ಸ್ಪರ್ಶಿಸಿ &amp; ಆಪ್‌ ಹಿಡಿದುಕೊಂಡು ಮತ್ತೊಂದರ ಮೇಲೆ ಸರಿಸಿ."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ಸರಿ"</string>
diff --git a/res/values-ko-land/strings.xml b/res/values-ko-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-ko-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 41c854e..c73b431 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android 핵심 앱"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"위젯"</string>
     <string name="widget_adder" msgid="3201040140710381657">"위젯"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"메모리 표시"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"위젯을 선택하려면 길게 터치하세요."</string>
-    <string name="market" msgid="2619650989819296998">"쇼핑하기"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"홈 화면에 항목을 놓을 수 없습니다."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"만들 위젯 선택"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"삭제"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"제거"</string>
     <string name="info_target_label" msgid="8053346143994679532">"앱 정보"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"검색"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"음성 검색"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"앱"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"삭제"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"업데이트 제거"</string>
diff --git a/res/values-ky-rKG/strings.xml b/res/values-ky-rKG/strings.xml
index 5b50555..a8a605b 100644
--- a/res/values-ky-rKG/strings.xml
+++ b/res/values-ky-rKG/strings.xml
@@ -24,13 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core колдонмолору"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Колдонмо орнотулган эмес."</string>
-    <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
-    <skip />
+    <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="widgets_tab_label" msgid="2921133187116603919">"Виджеттер"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Виджеттер"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Мемди көргөзүү"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетти тандаш үчүн, басып туруңуз"</string>
-    <string name="market" msgid="2619650989819296998">"Дүкөн"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Муну бул Үй экранына ыргытуу мүмкүн эмес."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Түзүлүүчү виджетти тандаңыз"</string>
@@ -58,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Алып салуу"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Чечип салуу"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Колдонмо тууралуу"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Издөө"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Үн менен издөө"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Колдонмолор"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Алып салуу"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Жаңыртууну чечип салуу"</string>
@@ -78,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"Үйдүн тууралоолорун жана тез чакырмаларын жазуу"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Колдонмого Үйдүн тууралоолорун жана тез чакырмаларын өзгөртүүгө уруксат берет."</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="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Аты жок фолдер"</string>
@@ -97,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"ТАЗАСЫН БАШТОО"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Өз мейкиндигиңизди уюштуруңуз"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Тушкагаздарды, виджеттерди жана тууралоолорду башкаруу үчүн фонду басып туруңуз."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Тушкагаздар, виджеттер &amp; жөндөөлөр"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Өзгөчөлөштүрүү үчүн фонго тийип &amp; коё бербей туруңуз"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ТҮШҮНДҮМ"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Мынакей фолдер"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Башкасын түзүш үчүн колдонмону басып туруп, башканын жанына жылдырыңыз."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-land/strings.xml b/res/values-land/strings.xml
deleted file mode 100644
index ec4c7e7..0000000
--- a/res/values-land/strings.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR 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">
-    <!-- Manifest configuration. -->
-    <skip />
-</resources>
diff --git a/res/values-land/styles.xml b/res/values-land/styles.xml
index 87a7444..8a255c9 100644
--- a/res/values-land/styles.xml
+++ b/res/values-land/styles.xml
@@ -18,31 +18,25 @@
 -->
 
 <resources>
-<!-- Search Bar -->
-    <style name="SearchButton">
-    </style>
+
+    <!-- Search Bar -->
+    <style name="SearchButton"></style>
+
     <style name="DropTargetButtonContainer">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">wrap_content</item>
     </style>
-    <style name="DropTargetButton">
-        <item name="android:layout_width">wrap_content</item>
+
+    <!-- This style applies to the drop target when it is shown in the sidebar -->
+    <style name="DropTargetButton" parent="DropTargetButton.Base">
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:layout_gravity">center</item>
         <item name="android:gravity">center</item>
+        <item name="android:drawablePadding">0dp</item>
         <item name="android:paddingTop">@dimen/toolbar_button_vertical_padding</item>
         <item name="android:paddingBottom">@dimen/toolbar_button_vertical_padding</item>
         <item name="android:paddingLeft">@dimen/toolbar_button_horizontal_padding</item>
         <item name="android:paddingRight">@dimen/toolbar_button_horizontal_padding</item>
         <item name="android:shadowColor">#DD000000</item>
-        <item name="android:shadowDx">0.0</item>
-        <item name="android:shadowDy">1.0</item>
-        <item name="android:shadowRadius">4.0</item>
     </style>
 
-<!-- AppsCustomize -->
-    <style name="TabIndicator.AppsCustomize">
-        <item name="android:maxWidth">200dp</item>
-    </style>
-</resources>
-
+</resources>
\ No newline at end of file
diff --git a/res/values-lo-rLA/strings.xml b/res/values-lo-rLA/strings.xml
index 1d953ff..65f01b7 100644
--- a/res/values-lo-rLA/strings.xml
+++ b/res/values-lo-rLA/strings.xml
@@ -24,19 +24,20 @@
     <string name="uid_name" msgid="7820867637514617527">"ແອັບພລິເຄຊັນຫຼັກຂອງ Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"ແອັບຯບໍ່ໄດ້ຖືກຕິດຕັ້ງ."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"ແອັບຯ​ໃຊ້​ບໍ່​ໄດ້"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"ແອັບຯ​ທີ່​ດາວ​ໂຫລດ​ແລ້ວ​ຖືກ​ປິດ​ການ​ນຳ​ໃຊ້​ໃນ Safe mode"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"​ວິດ​ເຈັດ​ຖືກ​ປິດ​ໃນ Safe mode"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"ວິດເຈັດ"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ວິດເຈັດ"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"ສະແດງຄວາມຈຳ"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"ສຳພັດຄ້າງໄວ້ ເພື່ອຈັບວິດເຈັດ."</string>
-    <string name="market" msgid="2619650989819296998">"ຮ້ານຄ້າ"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"ບໍ່ສາມາດວາງລາຍການໃສ່ໜ້າຈໍຫຼັກນີ້ໄດ້"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ເລືອກວິດເຈັດເພື່ອສ້າງມັນ"</string>
     <string name="rename_folder_label" msgid="3727762225964550653">"ຊື່ໂຟນເດີ"</string>
     <string name="rename_folder_title" msgid="3771389277707820891">"ປ່ຽນຊື່ໂຟນເດີ"</string>
     <string name="rename_action" msgid="5559600076028658757">"ຕົກລົງ"</string>
-    <string name="cancel_action" msgid="7009134900002915310">"ຍົກ​ເລີກ​"</string>
+    <string name="cancel_action" msgid="7009134900002915310">"ຍົກ​ເລີກ"</string>
     <string name="menu_item_add_item" msgid="1264911265836810421">"ເພີ່ມໃສ່ໜ້າຈໍຫຼັກ"</string>
     <string name="group_applications" msgid="3797214114206693605">"ແອັບຯ"</string>
     <string name="group_shortcuts" msgid="6012256992764410535">"ທາງລັດ"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"ລຶບ"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"ຖອນ​ການ​ຕິດ​ຕັ້ງ"</string>
     <string name="info_target_label" msgid="8053346143994679532">"ຂໍ້ມູນແອັບຯ"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"ຊອກຫາ"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ຊອກຫາດ້ວຍສຽງ"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"ແອັບຯ"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"ລຶບ"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"ຖອນອັບເດດ"</string>
@@ -118,7 +117,7 @@
     <string name="package_state_unknown" msgid="7592128424511031410">"​ບໍ່​ຮູ້​ຈັກ"</string>
     <string name="package_state_error" msgid="7672093962724223588">"ບໍ່​ໄດ້​ກູ້​ຂໍ້ມູນ​ມາ​ເທື່ອ"</string>
     <string name="abandoned_clean_all" msgid="5256770727689657618">"ລຶບ​ທັງ​ໝົດ"</string>
-    <string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ​"</string>
+    <string name="abandoned_clean_this" msgid="7610119707847920412">"ລຶບ"</string>
     <string name="abandoned_search" msgid="891119232568284442">"ຊອກຫາ"</string>
     <string name="abandoned_promises_title" msgid="7096178467971716750">"ແອັບຯ​ນີ້​ຍັງ​ບໍ່​ໄດ້​ຕິດ​ຕັ້ງ​ເທື່ອ"</string>
     <string name="abandoned_promise_explanation" msgid="3990027586878167529">"​ແອັບຯ​ສຳ​ລັບ​ໄອ​ຄອນ​ນີ້​ຍັງ​ບໍ່ໄດ້​ຕິດ​ຕັ້ງ​ເທື່ອ. ທ່ານ​ສາ​ມາດ​ລຶບ​ມັນ​ອອກ ຫຼື​ຊອກ​ຫາ​ແອັບຯ ແລ້ວ​ຕິດ​ຕັ້ງ​ມັນ​ໄດ້​ດ້ວຍ​ຕົນ​ເອງ."</string>
diff --git a/res/values-lt-land/strings.xml b/res/values-lt-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-lt-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index f7db792..897c2fd 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Pagrindinės „Android“ programos"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Programa neįdiegta."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Programa nepasiekiama"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Atsisiųsta programa išjungta Saugos režimu"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Valdikliai išjungti Saugiame režime"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Valdikliai"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Valdikliai"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Rodyti atmintinę"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Palieskite ir laikykite, kad pasirinkt. valdiklį."</string>
-    <string name="market" msgid="2619650989819296998">"Apsipirkti"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Nepavyko nuvilkti elemento į šį pagrindinį ekraną."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Pasirinkite norimą kurti valdiklį"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Pašalinti"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Pašalinti"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Programos informacija"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Ieškoti"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Paieška balsu"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Programos"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Pašalinti"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Pašalinti naujinį"</string>
diff --git a/res/values-lv-land/strings.xml b/res/values-lv-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-lv-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index 75eb054..13a4760 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android pamatlietotnes"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Lietotne nav instalēta."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Lietotne nav pieejama."</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Lejupielādētā lietotne ir atspējota drošajā režīmā."</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Logrīki atspējoti drošajā režīmā"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Logrīki"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Logrīki"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Rādīt atmiņu"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Lai izvēlētos logrīku, pieskarieties un turiet to."</string>
-    <string name="market" msgid="2619650989819296998">"Iepirkties"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Nevarēja nomest vienumu šajā sākuma ekrānā."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Izveidojamā logrīka izvēle"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Noņemt"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Atinstalēt"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Lietotnes informācija"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Meklēt"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Meklēšana ar balsi"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Lietotnes"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Noņemt"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Atinstalēt atjauninājumu"</string>
diff --git a/res/values-mk-rMK/strings.xml b/res/values-mk-rMK/strings.xml
index 0d77571..dcc55d7 100644
--- a/res/values-mk-rMK/strings.xml
+++ b/res/values-mk-rMK/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Основни апликации на Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"Виџети"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Виџети"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Прикажи „Мени“"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Допри и задржи за да се избере виџетот."</string>
-    <string name="market" msgid="2619650989819296998">"Продавница"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Не можеше да се спушти елемент на овој екран на почетната страница."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Избери виџет за да се создаде"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Отстрани"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Деинсталирај"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Информации за апликацијата"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Пребарај"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Гласовно пребарување"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Апликации"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Отстрани"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Деинсталирај ажурирање"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"напиши подесувања и кратенки на почетна страница"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Овозможува апликацијата да ги менува подесувањата и кратенките на почетната страница."</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="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Неименувана папка"</string>
@@ -91,11 +91,14 @@
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Создади повеќе екрани за апликации и папки"</string>
     <string name="migration_cling_title" msgid="9181776667882933767">"Копирај икони за апликација"</string>
-    <string name="migration_cling_description" msgid="2752413805582227644">"Увези икони и папки од старите екрани на почетната страница?"</string>
+    <string name="migration_cling_description" msgid="2752413805582227644">"Зачувај икони и папки од твоите стари почетни страни?"</string>
     <string name="migration_cling_copy_apps" msgid="946331230090919440">"КОПИРАЈ ИКОНИ"</string>
     <string name="migration_cling_use_default" msgid="2626475813981258626">"СТАРТУВАЈ ОД ПОЧЕТОК"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Организирајте го вашиот простор"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Допри и задржи ја заднината за управување со тапети, виџети и подесувања."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Тапети, додатоци и поставки"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Допрете и задржете на заднината за да приспособите"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"СФАТИВ"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Еве папка"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"За да создадете ваква, допрете и држете ја апликацијата, а потоа поместете ја врз другата."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Во ред"</string>
diff --git a/res/values-ml-rIN/strings.xml b/res/values-ml-rIN/strings.xml
index 32329f1..cf5efaa 100644
--- a/res/values-ml-rIN/strings.xml
+++ b/res/values-ml-rIN/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core അപ്ലിക്കേഷനുകൾ"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"വിജറ്റുകൾ"</string>
     <string name="widget_adder" msgid="3201040140710381657">"വിജറ്റുകൾ"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"മെമ്മറി കാണിക്കുക"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"ഒരു വിജറ്റ് ചേർക്കുന്നതിന് അത് സ്‌പർശിച്ച് പിടിക്കുക."</string>
-    <string name="market" msgid="2619650989819296998">"ഷോപ്പുചെയ്യുക"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"ഹോം സ്‌ക്രീനിൽ ഇനം വലിച്ചിടാനായില്ല."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"സൃഷ്‌ടിക്കുന്നതിന് വിജറ്റ് തിരഞ്ഞെടുക്കുക"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"നീക്കംചെയ്യുക"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"അണ്‍ഇസ്റ്റാളുചെയ്യുക"</string>
     <string name="info_target_label" msgid="8053346143994679532">"അപ്ലിക്കേഷൻ വിവരം"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"തിരയുക"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"വോയ്‌സ് തിരയൽ"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"അപ്ലിക്കേഷനുകൾ"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"നീക്കംചെയ്യുക"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"അപ്‌ഡേറ്റ് അൺഇൻസ്റ്റാളുചെയ്യുക"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"ഹോം ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും റൈറ്റുചെയ്യുക"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"ഹോമിലെ ക്രമീകരണങ്ങളും കുറുക്കുവഴികളും മാറ്റാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</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="dream_name" msgid="1530253749244328964">"റോക്കറ്റ് ലോഞ്ചർ"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"പേരുനൽകാത്ത ഫോൾഡർ"</string>
@@ -96,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"പുതുതായി ആരംഭിക്കുക"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"നിങ്ങളുടെ ഇടം ഓർഗനൈസുചെയ്യുക"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"വാൾപേപ്പർ, വിജറ്റുകൾ, ക്രമീകരണങ്ങൾ എന്നിവ നിയന്ത്രിക്കുന്നതിന് പശ്ചാത്തലം സ്‌പർശിച്ച് പിടിക്കുക."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"വാൾപേപ്പറുകൾ, വിജറ്റുകൾ, ക്രമീകരണങ്ങൾ എന്നിവ"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"ഇഷ്‌ടാനുസൃതമാക്കുന്നതിന് പശ്‌ചാത്തലം സ്‌പർശിച്ചുപിടിക്കുക"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"മനസ്സിലായി"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"ഇവിടെയൊരു ഫോൾഡർ ഉണ്ട്"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"ഇതുപോലൊന്ന് സൃഷ്‌ടിക്കുന്നതിന്, ഒരു അപ്ലിക്കേഷൻ സ്‌പർശിച്ച് പിടിച്ചുകൊണ്ട് അത് മറ്റൊന്നിലേക്ക് നീക്കുക."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ശരി"</string>
diff --git a/res/values-mn-rMN/strings.xml b/res/values-mn-rMN/strings.xml
index 34fb794..f258b4c 100644
--- a/res/values-mn-rMN/strings.xml
+++ b/res/values-mn-rMN/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Андройд үндсэн апп"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Апп суугаагүй байна."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Апп-г ашиглах боломжгүй"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Татаж авсан апп-г Аюулгүй горим дотроос идэвхгүйжүүлсэн"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Safe горимд виджетүүдийг идэвхгүйжүүлсэн"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Виджет"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Виджет"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Мем харуулах"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Виджетийг авах бол хүрээд барина уу."</string>
-    <string name="market" msgid="2619650989819296998">"Дэлгүүр"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Энэ Нүүр дэлгэцэнд буулгах боломжгүй."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Үүсгэх виджетээ сонгоно уу"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Устгах"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Устгах"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Апп мэдээлэл"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Хайх"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Дуун хайлт"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Апп"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Устгах"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Шинэчлэлийг устгах"</string>
diff --git a/res/values-mr-rIN/strings.xml b/res/values-mr-rIN/strings.xml
index 2e51e7b..098e830 100644
--- a/res/values-mr-rIN/strings.xml
+++ b/res/values-mr-rIN/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"विजेट"</string>
     <string name="widget_adder" msgid="3201040140710381657">"विजेट"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem दर्शवा"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"विजेट निवडण्यासाठी स्पर्श करा आणि धरून ठेवा."</string>
-    <string name="market" msgid="2619650989819296998">"खरेदी करा"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"या मुख्य स्क्रीनवर आयटम ड्रॉप करू शकलो नाही."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"तयार करण्यासाठी विजेट निवडा"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"काढा"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"विस्थापित करा"</string>
     <string name="info_target_label" msgid="8053346143994679532">"अॅप माहिती"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"शोधा"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"व्हॉइस शोध"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"अॅप्स"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"काढा"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"अद्यतन विस्थापित करा"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"मुख्यपृष्ठ सेटिंग्ज आणि शॉर्टकट लिहा"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"मुख्यपृष्ठातील सेटिंग्ज आणि शॉर्टकट बदलण्यास अॅप ला अनुमती देते."</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="dream_name" msgid="1530253749244328964">"रॉकेट लाँचर"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"अनामित फोल्डर"</string>
@@ -96,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"नव्याने प्रारंभ करा"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"आपले स्थान व्यवस्थापित करा"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"वॉलपेपर, विजेट आणि सेटिंग्ज व्यवस्थापित करण्यासाठी पार्श्वभूमीस स्पर्श करा आणि धरून ठेवा."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"वॉलपेपर, विजेट आणि सेटिंग्ज"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"सानुकूल करण्यासाठी पार्श्वभूमीस स्पर्श करा आणि धरुन ठेवा"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"समजले"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"येथे एक फोल्डर आहे"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"यासारखे एखादे तयार करण्यासाठी अॅप ला स्पर्श करा आणि धरून ठेवा, नंतर तो दुसर्‍यावर हलवा."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ठीक"</string>
diff --git a/res/values-ms-land/strings.xml b/res/values-ms-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-ms-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ms-rMY/strings.xml b/res/values-ms-rMY/strings.xml
index 3c58762..532b6ad 100644
--- a/res/values-ms-rMY/strings.xml
+++ b/res/values-ms-rMY/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Apl Teras Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Apl tidak dipasang."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Apl tidak tersedia"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Apl yang dimuat turun dilumpuhkan dalam mod Selamat"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widget dilumpuhkan dalam mod Selamat"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widget"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widget"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Papar Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Sentuh &amp; tahan untuk mengambil widget."</string>
-    <string name="market" msgid="2619650989819296998">"Beli-belah"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Tidak dapat melepaskan item pada Skrin Utama."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Pilih widget yang hendak dibuat"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Alih keluar"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Nyahpasang"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Maklumat apl"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Cari"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Carian Suara"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apl"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Alih keluar"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Nyahpasang kemas kini"</string>
diff --git a/res/values-my-rMM/strings.xml b/res/values-my-rMM/strings.xml
index 8048b02..6688035 100644
--- a/res/values-my-rMM/strings.xml
+++ b/res/values-my-rMM/strings.xml
@@ -24,19 +24,20 @@
     <string name="uid_name" msgid="7820867637514617527">"Androidပင်မ အပ်ပလီကေးရှင်းများ"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"အပ်ပလီကေးရှင်း မထည့်သွင်းထားပါ"</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"App လက်လှမ်း မမှီပါ"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"ဒေါင်းလုဒ် appကို လုံခြုံရေး မုဒ်ထဲမှာ ပိတ်ထား"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"လုံခြုံရေး မုဒ်ထဲမှာ ဝီဂျက်များကို ပိတ်ထား"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"ဝဒ်ဂျက်များ"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ဝဒ်ဂျက်များ"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem ကိုပြရန်"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"ဝဒ်ဂျက်တစ်ခုကို ကောက်ယူရန် ဖိနှိပ်ထားပါ"</string>
-    <string name="market" msgid="2619650989819296998">"စျေးဝယ်ရန်"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"ပင်မမျက်နှာစာတွင် အရာများ ချ လို့ မရတော့ပါ"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"ဝဒ်ဂျက်တစ်ခုအား ပြုဖန်တီးရန် ရွေးပါ"</string>
     <string name="rename_folder_label" msgid="3727762225964550653">"အကန့်အမည်"</string>
     <string name="rename_folder_title" msgid="3771389277707820891">"အကန့်အမည်ပြောင်းရန်"</string>
     <string name="rename_action" msgid="5559600076028658757">"ကောင်းပြီ"</string>
-    <string name="cancel_action" msgid="7009134900002915310">"ပယ်ဖျက်သည်"</string>
+    <string name="cancel_action" msgid="7009134900002915310">"ထားတော့"</string>
     <string name="menu_item_add_item" msgid="1264911265836810421">"ပင်မမျက်နှာစာသို့ ထည့်ပါ"</string>
     <string name="group_applications" msgid="3797214114206693605">"အပ်ပလီကေးရှင်းများ"</string>
     <string name="group_shortcuts" msgid="6012256992764410535">"အတိုကောက်မှတ်သားမှုများ"</string>
@@ -57,11 +58,9 @@
     <string name="delete_target_label" msgid="1822697352535677073">"ဖယ်ရှာခြင်း"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"ဖယ်ရှားခြင်း"</string>
     <string name="info_target_label" msgid="8053346143994679532">"အပ်ပလီကေးရှင်း အချက်အလက်များ"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"ရှာဖွေခြင်း"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"အသံဖြင့် ရှာဖွေခြင်း"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"အပ်ပလီကေးရှင်းများ"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"ဖယ်ရှာခြင်း"</string>
-    <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"အဆင့်မြှင့်ခြင်းကို ဖယ်ရှားပါ"</string>
+    <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"အဆင့်မြှင့်ခြင်းကို ဖယ်ရှားပါ"</string>
     <string name="cab_menu_delete_app" msgid="7435191475867183689">"အပ်ပလီကေးရှင်းကို ဖယ်ရှားပါ"</string>
     <string name="cab_menu_app_info" msgid="8593722221450362342">"အပ်ပလီကေးရှင်း အသေးစိတ် အချက်အလက်"</string>
     <string name="cab_app_selection_text" msgid="374688303047985416">"အပ်ပလီကေးရှင်းတစ်ခု ရွေးချယ်ထားပြီး"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"ပင်မမျက်နှာစာ အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများအား ရေးသားခြင်း"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"ပင်မမျက်နှာစာတွင် ရှိသော အပြင်အဆင် နှင့် အတိုကောက်မှတ်သားမှုများ ကို အပ်ပလီကေးရှင်းအား ပြောင်းခွင့်ပြုခြင်း"</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="dream_name" msgid="1530253749244328964">"ဒုံပျံ ပစ်လွှတ်သောအရာ"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"အမည်မရှိအကန့်"</string>
@@ -85,8 +85,8 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"ပင်မစာမျက်နှာ %1$d မှ %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"အပ်ပလီကေးရှင်းပြ စာမျက်နှာ %1$d မှ %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"ဝဒ်ဂျက်ပြ စာမျက်နှာ %1$d မှ %2$d"</string>
-    <string name="first_run_cling_title" msgid="2459738000155917941">"ကြိုဆိုပါသည်"</string>
-    <string name="first_run_cling_description" msgid="6447072552696253358">"ကိုယ့်အိမ်ကိုယ့်ယာလို သဘောထားပါ"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"မင်္ဂလာပါ"</string>
+    <string name="first_run_cling_description" msgid="6447072552696253358">"ကိုယ့်အိမ်လို သဘောထားပါ"</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
     <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"အပ်ပလီကေးရှင်း နှင့် အကန့်များအတွက် ဖန်သားပြင်မှာ ထပ်ထည့်ပါ"</string>
@@ -96,10 +96,13 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"START FRESH"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"စနစ်တကျဖြစ်အောင် ပြုလုပ်ပါ"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"နောက်ခံကို ဖိကိုင်၍ နောက်ခံပုံ၊ဝဒ်ဂျက်များ၊အပြင်အဆင်များကို ထိန်းချုပ်ပါ"</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"နောက်ခံများ၊ ဝီဂျက်များ&amp; ဆက်တင်များ"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"နောက်ခံကို စိတ်တိုင်းကျ ပြုလုပ်ရန် ထိလျက် &amp; ကိုင်ထားပါ"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ရပြီ"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"ဒီမှာ အကန့်တစ်ခုဖြစ်ပါသည်"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"ဤကဲ့သို့လုပ်ရန်အတွက်၊ အပ်ပလီကေးရှင်းတစ်ခုကို ဖိကိုင်ပြီး နောက်တစ်ခုပေါ်သို့ ရွှေ့လိုက်ပါ"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ကောင်းပြီ"</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_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="1884479294466410023">"အကန့်ကို ပိတ်ရန် ဖိကိုင်ပါ"</string>
     <string name="folder_tap_to_rename" msgid="9191075570492871147">"အမည်ပြောင်းခြင်း အတည်ပြုရန် ဖိကိုင်ပါ"</string>
     <string name="folder_closed" msgid="4100806530910930934">"ပိတ်ထားသောအကန့်"</string>
@@ -108,7 +111,7 @@
     <string name="widget_button_text" msgid="2880537293434387943">"ဝဒ်ဂျက်များ"</string>
     <string name="wallpaper_button_text" msgid="8404103075899945851">"နောက်ခံများ"</string>
     <string name="settings_button_text" msgid="8119458837558863227">"အပြင်အဆင်များ"</string>
-    <string name="package_state_enqueued" msgid="6227252464303085641">"စောင့်နေ"</string>
+    <string name="package_state_enqueued" msgid="6227252464303085641">"စောင့်နေ"</string>
     <string name="package_state_downloading" msgid="4088770468458724721">"ဒေါင်းလုဒ် လုပ်နေ"</string>
     <string name="package_state_installing" msgid="7588193972189849870">"တပ်ဆင်နေ"</string>
     <string name="package_state_unknown" msgid="7592128424511031410">"မသိရ"</string>
diff --git a/res/values-nb-land/strings.xml b/res/values-nb-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-nb-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index ff8280e..a9bbe08 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Kjerneapper for Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Appen er ikke installert."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Appen er ikke tilgjengelig"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"En nedlastet app er deaktivert i sikker modus"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Moduler er deaktivert i sikker modus"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Moduler"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Moduler"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Vis minne"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Trykk og hold inne for å plukke opp en modul."</string>
-    <string name="market" msgid="2619650989819296998">"Butikk"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Kunne ikke slippe elementet på denne startsiden."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Velg modul for oppretting"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Fjern"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Avinstaller"</string>
     <string name="info_target_label" msgid="8053346143994679532">"App-info"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Søk"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Talesøk"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apper"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Fjern"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Avinstaller oppdateringen"</string>
diff --git a/res/values-ne-rNP/strings.xml b/res/values-ne-rNP/strings.xml
index fe75ea7..815873d 100644
--- a/res/values-ne-rNP/strings.xml
+++ b/res/values-ne-rNP/strings.xml
@@ -24,13 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android मूल अनुप्रयोगहरू"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"अनुप्रयोग स्थापित छैन।"</string>
-    <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
-    <skip />
+    <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="widgets_tab_label" msgid="2921133187116603919">"विजेटहरू"</string>
     <string name="widget_adder" msgid="3201040140710381657">"विजेटहरू"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem देखाउनुहोस्"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"एउटा विजेटलाई टिप्नको लागि टच गरेर होल्ड गर्नुहोस्।"</string>
-    <string name="market" msgid="2619650989819296998">"पसल"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"यो गृह स्क्रिनमा वस्तु खसाउन सकिँदैन।"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"सृजना गर्नको लागि विजेट छान्नुहोस्"</string>
@@ -58,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"हटाउनुहोस्"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"हटाउनुहोस्"</string>
     <string name="info_target_label" msgid="8053346143994679532">"अनुप्रयोग जानकारी"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"खोज्नुहोस्"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ध्वनि खोज"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"अनुप्रयोगहरू"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"हटाउनुहोस्"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"अद्यावधिक अस्थापित गर्नुहोस्"</string>
@@ -78,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"गृह सेटिङहरू र सर्टकटहरू लेख्नुहोस्"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"गृहमा एउटा अनुप्रयोगलाई सेटिङ र सर्टकट बदल्न अनुमति दिनुहोस्।"</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="dream_name" msgid="1530253749244328964">"रकेट लन्चर"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"बेनाम फोल्डर"</string>
@@ -99,6 +98,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"START FRESH"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"आफ्नो ठाउँ व्यवस्थापन गर्नुहोस्"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"वालपेपर, विजेट र सेटिङ्स प्रबन्ध गर्न पृष्ठभूमिलाई टच गरेर होल्ड गर्नुहोस्।"</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"वालपेपरहरू, विजेट; सेटिङहरू"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"छुनुहोस् ; अनुकूलन पृष्ठभूमि होल्ड गर्नुहोस्"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"बुझियो"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"यहाँ एउटा फोल्डर छ"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"यस्तै एक किसिमका सिर्जना गर्न, अनुप्रयोगलाई टच गरेर होल्ड गर्नुहोस्, त्यसपछि यसलाई अर्को माथि सार्नुहोस्।"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ठिक छ"</string>
diff --git a/res/values-nl-land/strings.xml b/res/values-nl-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-nl-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 470eb87..8a32fd1 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android-kernapps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"App is niet geïnstalleerd."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"App is niet beschikbaar"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Gedownloade app uitgeschakeld in veilige modus"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets uitgeschakeld in Veilige modus"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Geheugen weergeven"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Blijf aanraken om een widget toe te voegen."</string>
-    <string name="market" msgid="2619650989819296998">"Winkelen"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Kan item niet neerzetten in dit startscherm."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Widget selecteren om te maken"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Verwijderen"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Verwijderen"</string>
     <string name="info_target_label" msgid="8053346143994679532">"App-info"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Zoeken"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Gesproken zoekopdracht"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Verwijderen"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Update verwijderen"</string>
diff --git a/res/values-pl-land/strings.xml b/res/values-pl-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-pl-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 61a51e0..4eabae9 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Główne aplikacje Androida"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacja nie jest zainstalowana."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Aplikacja niedostępna"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Pobrana aplikacja została wyłączona w trybie awaryjnym"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widżety są wyłączone w trybie bezpiecznym"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widżety"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widżety"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Pokaż pamięć"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Aby dodać widżet, kliknij go i przytrzymaj."</string>
-    <string name="market" msgid="2619650989819296998">"Sklep"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Nie można upuścić elementu na tym ekranie głównym."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Wybierz widżet, który chcesz dodać"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Usuń"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Odinstaluj"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Informacje o aplikacji"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Szukaj"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Wyszukiwanie głosowe"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikacje"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Usuń"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Odinstaluj aktualizację"</string>
diff --git a/res/values-port/styles.xml b/res/values-port/styles.xml
deleted file mode 100644
index ab6a1eb..0000000
--- a/res/values-port/styles.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources>
-<!-- AppsCustomize -->
-    <style name="TabIndicator.AppsCustomize">
-        <item name="android:maxWidth">130dp</item>
-    </style>
-</resources>
diff --git a/res/values-pt-land/strings.xml b/res/values-pt-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-pt-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-pt-rPT-land/strings.xml b/res/values-pt-rPT-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-pt-rPT-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 2fe062a..4397ebf 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Aplicações principais do Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"A aplicação não está instalada."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"A aplicação não está disponível"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicação transferida desativada no Modo de segurança"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets desativados no Modo de segurança"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Prima sem soltar para escolher um widget."</string>
-    <string name="market" msgid="2619650989819296998">"Comprar"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Não foi possível largar o item neste Ecrã Principal."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Escolher um widget para criar"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Remover"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Informações da aplicação"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Pesquisar"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Pesquisa por Voz"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicações"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Remover"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar atualização"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index 20b193a..07c8214 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -21,15 +21,16 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="application_name" msgid="5181331383435256801">"Launcher3"</string>
     <string name="home" msgid="7658288663002113681">"Início"</string>
-    <string name="uid_name" msgid="7820867637514617527">"Principais aplicativos do Android"</string>
+    <string name="uid_name" msgid="7820867637514617527">"Principais apps do Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="activity_not_found" msgid="8071924732094499514">"O aplicativo não está instalado."</string>
+    <string name="activity_not_found" msgid="8071924732094499514">"O app não está instalado."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"O app não está disponível"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"App transferido por download desativado no modo de segurança"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets desativados no modo de segurança"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgets"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgets"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mostrar memória"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Toque e pressione para selecionar um widget."</string>
-    <string name="market" msgid="2619650989819296998">"Comprar"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Não foi possível soltar o item nesta tela inicial."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Selecione um widget para criar"</string>
@@ -38,7 +39,7 @@
     <string name="rename_action" msgid="5559600076028658757">"Ok"</string>
     <string name="cancel_action" msgid="7009134900002915310">"Cancelar"</string>
     <string name="menu_item_add_item" msgid="1264911265836810421">"Adicionar à tela inicial"</string>
-    <string name="group_applications" msgid="3797214114206693605">"Aplicativos"</string>
+    <string name="group_applications" msgid="3797214114206693605">"Apps"</string>
     <string name="group_shortcuts" msgid="6012256992764410535">"Atalhos"</string>
     <string name="group_widgets" msgid="1569030723286851002">"Widgets"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"Não há mais espaço nas telas iniciais."</string>
@@ -49,49 +50,47 @@
     <string name="shortcut_uninstalled" msgid="8176767991305701821">"O atalho \"<xliff:g id="NAME">%s</xliff:g>\" foi removido."</string>
     <string name="shortcut_duplicate" msgid="9167217446062498127">"O atalho \"<xliff:g id="NAME">%s</xliff:g>\" já existe."</string>
     <string name="title_select_shortcut" msgid="6680642571148153868">"Selecione um atalho"</string>
-    <string name="title_select_application" msgid="3280812711670683644">"Selecione um aplicativo"</string>
-    <string name="all_apps_button_label" msgid="9110807029020582876">"Aplicativos"</string>
+    <string name="title_select_application" msgid="3280812711670683644">"Selecione um app"</string>
+    <string name="all_apps_button_label" msgid="9110807029020582876">"Apps"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"Início"</string>
     <string name="delete_zone_label_workspace" msgid="4009607676751398685">"Remover"</string>
     <string name="delete_zone_label_all_apps" msgid="8083826390278958980">"Desinstalar"</string>
     <string name="delete_target_label" msgid="1822697352535677073">"Remover"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Desinstalar"</string>
-    <string name="info_target_label" msgid="8053346143994679532">"Informações do aplicativo"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Pesquisar"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Pesquisa por voz"</string>
-    <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicativos"</string>
+    <string name="info_target_label" msgid="8053346143994679532">"Informações do app"</string>
+    <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Remover"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Desinstalar atualização"</string>
-    <string name="cab_menu_delete_app" msgid="7435191475867183689">"Desinstalar aplicativo"</string>
-    <string name="cab_menu_app_info" msgid="8593722221450362342">"Detalhes do aplicativo"</string>
-    <string name="cab_app_selection_text" msgid="374688303047985416">"Um aplicativo selecionado"</string>
+    <string name="cab_menu_delete_app" msgid="7435191475867183689">"Desinstalar app"</string>
+    <string name="cab_menu_app_info" msgid="8593722221450362342">"Detalhes do app"</string>
+    <string name="cab_app_selection_text" msgid="374688303047985416">"Um app selecionado"</string>
     <string name="cab_widget_selection_text" msgid="1833458597831541241">"Um widget selecionado"</string>
     <string name="cab_folder_selection_text" msgid="7999992513806132118">"Uma pasta selecionada"</string>
     <string name="cab_shortcut_selection_text" msgid="2103811025667946450">"Um atalho selecionado"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"instalar atalhos"</string>
-    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que um aplicativo adicione atalhos sem intervenção do usuário."</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"Permite que um app adicione atalhos sem intervenção do usuário."</string>
     <string name="permlab_uninstall_shortcut" msgid="864595034498083837">"desinstalar atalhos"</string>
-    <string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"Permite que o aplicativo remova atalhos sem a intervenção do usuário."</string>
+    <string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"Permite que o app remova atalhos sem a intervenção do usuário."</string>
     <string name="permlab_read_settings" msgid="1941457408239617576">"ler configurações e atalhos da tela inicial"</string>
-    <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite que o aplicativo leia as configurações e os atalhos na tela inicial."</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"Permite que o app leia as configurações e os atalhos na tela inicial."</string>
     <string name="permlab_write_settings" msgid="3574213698004620587">"gravar configurações e atalhos da tela inicial"</string>
-    <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que o aplicativo altere as configurações e os atalhos na tela inicial."</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"Permite que o app altere as configurações e os atalhos na tela inicial."</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Problema ao carregar o widget"</string>
     <string name="gadget_setup_text" msgid="8274003207686040488">"Configuração"</string>
-    <string name="uninstall_system_app_text" msgid="4172046090762920660">"Este é um aplicativo do sistema e não pode ser desinstalado."</string>
+    <string name="uninstall_system_app_text" msgid="4172046090762920660">"Este é um app do sistema e não pode ser desinstalado."</string>
     <string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Pasta sem nome"</string>
     <string name="workspace_description_format" msgid="2950174241104043327">"Tela inicial %1$d"</string>
     <string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Tela inicial %1$d de %2$d"</string>
-    <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Página de aplicativos, %1$d de %2$d"</string>
+    <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Página de apps, %1$d de %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Página de widgets, %1$d de %2$d"</string>
     <string name="first_run_cling_title" msgid="2459738000155917941">"Bem-vindo"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Fique à vontade."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
-    <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Crie mais telas para aplicativos e pastas"</string>
-    <string name="migration_cling_title" msgid="9181776667882933767">"Copiar ícones de aplicativos"</string>
+    <string name="first_run_cling_create_screens_hint" msgid="6950729526680114157">"Crie mais telas para apps e pastas"</string>
+    <string name="migration_cling_title" msgid="9181776667882933767">"Copiar ícones de apps"</string>
     <string name="migration_cling_description" msgid="2752413805582227644">"Importar ícones e pastas de suas telas iniciais antigas?"</string>
     <string name="migration_cling_copy_apps" msgid="946331230090919440">"COPIAR ÍCONES"</string>
     <string name="migration_cling_use_default" msgid="2626475813981258626">"COMEÇAR DO ZERO"</string>
@@ -101,7 +100,7 @@
     <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Toque e mantenha pressionado o segundo plano para personalizar"</string>
     <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"ENTENDI"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Aqui está uma pasta"</string>
-    <string name="folder_cling_create_folder" msgid="6158215559475836131">"Para criar uma pasta como esta, mantenha pressionado um aplicativo e mova-o para cima de outro."</string>
+    <string name="folder_cling_create_folder" msgid="6158215559475836131">"Para criar uma pasta como esta, mantenha pressionado um app e mova-o para cima de outro."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"Ok"</string>
     <string name="folder_opened" msgid="94695026776264709">"Pasta aberta, <xliff:g id="WIDTH">%1$d</xliff:g> por <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
     <string name="folder_tap_to_close" msgid="1884479294466410023">"Toque para fechar a pasta"</string>
@@ -120,6 +119,6 @@
     <string name="abandoned_clean_all" msgid="5256770727689657618">"Remover tudo"</string>
     <string name="abandoned_clean_this" msgid="7610119707847920412">"Remover"</string>
     <string name="abandoned_search" msgid="891119232568284442">"Pesquisar"</string>
-    <string name="abandoned_promises_title" msgid="7096178467971716750">"Este aplicativo não está instalado"</string>
-    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"O aplicativo deste ícone não está instalado. Você pode remover o ícone, ou procurar o aplicativo e instalá-lo manualmente."</string>
+    <string name="abandoned_promises_title" msgid="7096178467971716750">"Este app não está instalado"</string>
+    <string name="abandoned_promise_explanation" msgid="3990027586878167529">"O app deste ícone não está instalado. Você pode remover o ícone, ou procurar o app e instalá-lo manualmente."</string>
 </resources>
diff --git a/res/values-rm-land/strings.xml b/res/values-rm-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-rm-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ro-land/strings.xml b/res/values-ro-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-ro-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 04aebc8..54cb46c 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplicația nu este instalată."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Aplicația nu este disponibilă"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Aplicația descărcată este dezactivată în modul de siguranță"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgeturile sunt dezactivate în modul de siguranță"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgeturi"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgeturi"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Afișați memoria"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Atingeți lung un widget pentru a-l alege."</string>
-    <string name="market" msgid="2619650989819296998">"Cumpărați"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Nu se poate plasa articolul pe ecranul de pornire."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Alegeți widgetul de creat"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Eliminați"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Dezinstalați"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Informații despre aplicație"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Căutați"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Căutare vocală"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplicații"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Eliminați"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Dezinstalați actualizarea"</string>
diff --git a/res/values-ru-land/strings.xml b/res/values-ru-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-ru-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index b1d7713..70ef0f5 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Основные приложения Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"Виджеты"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Виджеты"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Сведения о памяти"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Чтобы выбрать виджет, нажмите на значок и удерживайте его."</string>
-    <string name="market" msgid="2619650989819296998">"Google Play"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d x %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Не удалось добавить элемент на главный экран"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Выберите виджет"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Удалить"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Удалить"</string>
     <string name="info_target_label" msgid="8053346143994679532">"О приложении"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Поиск"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Голосовой поиск"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Приложения"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Удалить"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Удалить обновление"</string>
diff --git a/res/values-si-rLK/strings.xml b/res/values-si-rLK/strings.xml
index d334da9..ab3abb8 100644
--- a/res/values-si-rLK/strings.xml
+++ b/res/values-si-rLK/strings.xml
@@ -24,13 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android මධ්‍ය යෙදුම්"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"යෙදුම ස්ථාපනය කර නැත."</string>
-    <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
-    <skip />
+    <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="widgets_tab_label" msgid="2921133187116603919">"විජට්"</string>
     <string name="widget_adder" msgid="3201040140710381657">"විජට්"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Mem පෙන්වන්න"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"විජට් එක ස්පර්ශ කර අහුලා ගැනීමට අල්ලාගෙන සිටින්න."</string>
-    <string name="market" msgid="2619650989819296998">"සාප්පුයාම"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"මෙම මුල් පිටු තිරය වෙත අයිතමය ඇද හෙළිය නොහැකි විය."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"සැදීමට විජට් එක තෝරන්න"</string>
@@ -58,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"ඉවත් කරන්න"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"අස්ථාපනය කරන්න"</string>
     <string name="info_target_label" msgid="8053346143994679532">"යෙදුම් තොරතුරු"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"සොයන්න"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"හඬ සෙවීම"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"යෙදුම්"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"ඉවත් කරන්න"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"යාවත්කාලිනය අස්ථාපනය කරන්න"</string>
@@ -78,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"මුල් පිටු සැකසීම් සහ කෙටිමං ලියන්න"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"මුල් පිටුවේ සැකසීම් සහ කෙටිමං ඉවත් කිරීමට යෙදුමට අවසර දෙයි."</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="dream_name" msgid="1530253749244328964">"රොකට් ආරම්භකය"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"නම් නොකළ ෆෝල්ඩරය"</string>
@@ -97,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"අලුතින් පටන්ගන්න"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"ඔබගේ ඉඩ සංවිධානය කරගන්න"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"බිතුපත, විජට් සහ සැකසීම් කළමනාකරණය කිරීමට පසුබිම ස්පර්ශ කර අල්ලාගෙන සිටින්න."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"වෝල්පේපර, විජට්, සහ සැකසීම්"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"පසුබිම අභිරුචිකරණය කිරීමට ස්පර්ශ කර අල්ලා සිටින්න"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"තේරුණා"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"මෙන්න ෆෝල්ඩරයක්"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"මෙවැනි එකක් තැනීමට, යෙදුමක් තට්ටු කර අල්ලාගෙන සිටින්න, අනතුරුව එය තවත් එකක් උඩින් ගෙන යන්න."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"හරි"</string>
diff --git a/res/values-sk-land/strings.xml b/res/values-sk-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-sk-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index a003679..3f41f2d 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikácia nie je nainštalovaná."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Aplikácia nie je k dispozícii"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Stiahnutá aplikácia je v núdzovom režime zakázaná"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Miniaplikácie sú v núdzovom režime zakázané"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Miniaplikácie"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Miniaplikácie"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Zobraziť pamäť"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Miniaplikáciu pridáte stlačením a podržaním."</string>
-    <string name="market" msgid="2619650989819296998">"Obchod"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Položku sa nepodarilo presunúť na túto plochu."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Zvoľte miniaplikáciu na vytvorenie"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Odstrániť"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Odinštalovať"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Informácie o aplikácii"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Vyhľadať"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Hlasové vyhľadávanie"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikácie"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Odstrániť"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Odinštalovať aktualizáciu"</string>
@@ -86,7 +85,7 @@
     <string name="workspace_scroll_format" msgid="8458889198184077399">"Plocha %1$d z %2$d"</string>
     <string name="apps_customize_apps_scroll_format" msgid="370005296147130238">"Stránka aplikácií %1$d z %2$d"</string>
     <string name="apps_customize_widgets_scroll_format" msgid="3106209519974971521">"Stránka miniaplikácií %1$d z %2$d"</string>
-    <string name="first_run_cling_title" msgid="2459738000155917941">"Vitajte"</string>
+    <string name="first_run_cling_title" msgid="2459738000155917941">"Vitajte!"</string>
     <string name="first_run_cling_description" msgid="6447072552696253358">"Cíťte sa tu ako doma."</string>
     <string name="first_run_cling_custom_content_hint" msgid="6090628589029352439"></string>
     <string name="first_run_cling_search_bar_hint" msgid="5909062802402452582"></string>
@@ -94,7 +93,7 @@
     <string name="migration_cling_title" msgid="9181776667882933767">"Kopírovanie ikon aplikácií"</string>
     <string name="migration_cling_description" msgid="2752413805582227644">"Chcete importovať ikony a priečinky zo starých plôch?"</string>
     <string name="migration_cling_copy_apps" msgid="946331230090919440">"SKOPÍROVAŤ IKONY"</string>
-    <string name="migration_cling_use_default" msgid="2626475813981258626">"ZAČAŤ S PREDVOLENÝM ROZLOŽENÍM"</string>
+    <string name="migration_cling_use_default" msgid="2626475813981258626">"ZAČAŤ ODZNOVA"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Usporiadajte svoj priestor"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Ak chcete spravovať tapetu, miniaplikácie a nastavenia, dotknite sa pozadia a podržte."</string>
     <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Pozadia, miniaplikácie a nastavenia"</string>
diff --git a/res/values-sl-land/strings.xml b/res/values-sl-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-sl-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 9c5bebd..d5a34d5 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Osnovne aplikacije sistema Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Aplikacija ni nameščena."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Aplikacija ni na voljo"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Prenesena aplikacija je onemogočena v Varnem načinu"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Pripomočki so onemogočeni v varnem načinu"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Pripomočki"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Pripomočki"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Pokaži pomnilnik"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Za izbiro pripomočka se ga dotaknite in pridržite."</string>
-    <string name="market" msgid="2619650989819296998">"Nakup"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Elementa ni mogoče spustiti na začetni zaslon."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Izberite pripomoček za ustvarjanje"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Odstrani"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Odstrani"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Podatki o aplikaciji"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Iskanje"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Glasovno iskanje"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Aplikacije"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Odstrani"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Odstrani posodobitev"</string>
diff --git a/res/values-sr-land/strings.xml b/res/values-sr-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-sr-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 421f8d3..9f40890 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Основне Android апликације"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"Виџети"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Виџети"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Прикажи меморију"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Додирните и задржите да бисте изабрали виџет."</string>
-    <string name="market" msgid="2619650989819296998">"Купујте"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d×%2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Није могуће отпустити ставку на почетни екран."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Избор виџета за прављење"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Уклони"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Деинсталирај"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Информације о апликацији"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Претражи"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Гласовна претрага"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Апликације"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Уклони"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Деинсталирај ажурирање"</string>
diff --git a/res/values-sv-land/strings.xml b/res/values-sv-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-sv-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index e149c9e..25f4d26 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Appen är inte installerad."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Appen är inte tillgänglig"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Den hämtade appen inaktiverades i säkert läge"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Widgets är inaktiverade i felsäkert läge"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widgetar"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widgetar"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Visa Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Tryck länge om du vill flytta en widget."</string>
-    <string name="market" msgid="2619650989819296998">"Butik"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Objektet kunde inte släppas på startskärmen."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Ange vilken widget du vill använda"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Ta bort"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Avinstallera"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Info om appen"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Sök"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Röstsökning"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Appar"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Ta bort"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Avinstallera uppdatering"</string>
diff --git a/res/values-sw-land/strings.xml b/res/values-sw-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-sw-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 07d0913..fa81061 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Programu Msingi za Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Programu haijasakinishwa."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Programu haipatikani"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Programu iliyopakuliwa imezimwa katika Hali Salama"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Wijeti zimezimwa katika hali ya Usalama"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Wijeti"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Wijeti"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Onyesha Kumbukumbu"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Gusa na ushikilie ili kuteua wijeti."</string>
-    <string name="market" msgid="2619650989819296998">"Nunua"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Haikuweza kudondosha kipengee kwenye skrini hii ya Kwanza."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Chagua wijeti ili uunde"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Ondoa"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Ondoa"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Maelezo ya programu"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Tafuta"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Kutafuta kwa Kutamka"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Programu"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Ondoa"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Ondoa sasisho"</string>
diff --git a/res/values-sw340dp-port/styles.xml b/res/values-sw340dp-port/styles.xml
index 24f4ba2..8ac3b5e 100644
--- a/res/values-sw340dp-port/styles.xml
+++ b/res/values-sw340dp-port/styles.xml
@@ -24,9 +24,4 @@
         <item name="android:paddingTop">@dimen/toolbar_button_vertical_padding</item>
         <item name="android:paddingBottom">@dimen/toolbar_button_vertical_padding</item>
     </style>
-
-<!-- AppsCustomize -->
-    <style name="TabIndicator.AppsCustomize">
-        <item name="android:maxWidth">150dp</item>
-    </style>
 </resources>
diff --git a/res/values-sw340dp/dimens.xml b/res/values-sw340dp/dimens.xml
index 69d6e58..c9f2981 100644
--- a/res/values-sw340dp/dimens.xml
+++ b/res/values-sw340dp/dimens.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 The Android Open Source Project
+<!--
+     Copyright (C) 2011 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
@@ -15,6 +16,9 @@
 -->
 
 <resources>
+
     <!-- Drag padding to add to the bottom of drop targets -->
     <dimen name="drop_target_drag_padding">20dp</dimen>
-</resources>
+    <dimen name="drop_target_text_size">16sp</dimen>
+
+</resources>
\ No newline at end of file
diff --git a/res/values-sw720dp-port/styles.xml b/res/values-sw720dp-port/styles.xml
deleted file mode 100644
index 57f07ac..0000000
--- a/res/values-sw720dp-port/styles.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
--->
-
-<resources>
-    <style name="TabIndicator.AppsCustomize">
-        <item name="android:maxWidth">180dp</item>
-    </style>
-</resources>
diff --git a/res/values-sw720dp/styles.xml b/res/values-sw720dp/styles.xml
index 71f0304..cbc1e29 100644
--- a/res/values-sw720dp/styles.xml
+++ b/res/values-sw720dp/styles.xml
@@ -18,33 +18,22 @@
 -->
 
 <resources>
-<!-- Workspace -->
-    <style name="TabIndicator.AppsCustomize">
-        <item name="android:paddingLeft">32dp</item>
-        <item name="android:paddingRight">32dp</item>
-        <item name="android:textSize">14sp</item>
-        <item name="android:maxWidth">240dp</item>
-    </style>
 
-    <style name="SearchButton">
-    </style>
+    <!-- Workspace -->
+    <style name="SearchButton"></style>
+
     <style name="DropTargetButtonContainer">
         <item name="android:layout_width">0dp</item>
         <item name="android:layout_height">match_parent</item>
     </style>
-    <style name="DropTargetButton">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">match_parent</item>
-        <item name="android:layout_gravity">center</item>
-        <item name="android:gravity">center_vertical</item>
-        <item name="android:drawablePadding">7.5dp</item>
+
+    <style name="DropTargetButton" parent="DropTargetButton.Base">
         <item name="android:paddingLeft">60dp</item>
         <item name="android:paddingRight">60dp</item>
-        <item name="android:textColor">#FFFFFFFF</item>
-        <item name="android:textSize">16sp</item>
         <item name="android:shadowColor">#393939</item>
         <item name="android:shadowDx">0.0</item>
         <item name="android:shadowDy">0.0</item>
         <item name="android:shadowRadius">2.0</item>
     </style>
-</resources>
+
+</resources>
\ No newline at end of file
diff --git a/res/values-ta-rIN/strings.xml b/res/values-ta-rIN/strings.xml
index f3aef1c..9dba6f6 100644
--- a/res/values-ta-rIN/strings.xml
+++ b/res/values-ta-rIN/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android முக்கியப் பயன்பாடுகள்"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"விட்ஜெட்கள்"</string>
-    <string name="widget_adder" msgid="3201040140710381657">"விட்ஜெட்கள்"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"பாதுகாப்புப் பயன்முறையில் விட்ஜெட்கள் முடக்கப்பட்டுள்ளன"</string>
+    <string name="widgets_tab_label" msgid="2921133187116603919">"ஷார்ட்கட்ஸ்"</string>
+    <string name="widget_adder" msgid="3201040140710381657">"ஷார்ட்கட்ஸ்"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"நினைவகத்தைக் காட்டு"</string>
-    <string name="long_press_widget_to_add" msgid="7699152356777458215">"விட்ஜெட்டைத் தேர்வுசெய்ய தொட்டுப் &amp; பிடிக்கவும்."</string>
-    <string name="market" msgid="2619650989819296998">"ஷாப்"</string>
+    <string name="long_press_widget_to_add" msgid="7699152356777458215">"விட்ஜெட்டைத் தேர்வுசெய்ய தொட்டுப் பிடிக்கவும்."</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"உருப்படியை இந்த முகப்புத் திரையில் விட முடியவில்லை."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"உருவாக்குவதற்கு விட்ஜெட்டைத் தேர்வுசெய்யவும்"</string>
@@ -40,7 +41,7 @@
     <string name="menu_item_add_item" msgid="1264911265836810421">"முகப்புத் திரையில் சேர்"</string>
     <string name="group_applications" msgid="3797214114206693605">"பயன்பாடுகள்"</string>
     <string name="group_shortcuts" msgid="6012256992764410535">"குறுக்குவழிகள்"</string>
-    <string name="group_widgets" msgid="1569030723286851002">"விட்ஜெட்கள்"</string>
+    <string name="group_widgets" msgid="1569030723286851002">"ஷார்ட்கட்ஸ்"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"உங்கள் முகப்புத் திரைகளில் வேறு இடம் இல்லை."</string>
     <string name="out_of_space" msgid="4691004494942118364">"முகப்புத் திரையில் இடமில்லை."</string>
     <string name="hotseat_out_of_space" msgid="7448809638125333693">"பிடித்தவை ட்ரேயில் இடமில்லை"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"அகற்று"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"நிறுவல் நீக்கு"</string>
     <string name="info_target_label" msgid="8053346143994679532">"பயன்பாட்டுத் தகவல்"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"தேடு"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"குரல் தேடல்"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"பயன்பாடுகள்"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"அகற்று"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"புதுப்பிப்பை நிறுவல் நீக்கு"</string>
@@ -72,11 +71,12 @@
     <string name="permdesc_install_shortcut" msgid="923466509822011139">"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளைச் சேர்க்கப் பயன்பாட்டை அனுமதிக்கிறது."</string>
     <string name="permlab_uninstall_shortcut" msgid="864595034498083837">"குறுக்குவழிகளை நிறுவல் நீக்குதல்"</string>
     <string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"பயனரின் அனுமதி இல்லாமல் குறுக்குவழிகளை அகற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
-    <string name="permlab_read_settings" msgid="1941457408239617576">"முகப்பின் அமைப்புகள் மற்றும் குறுக்குவழிகளைப் படித்தல்"</string>
-    <string name="permdesc_read_settings" msgid="5833423719057558387">"முகப்பில் உள்ள அமைப்புகள் மற்றும் குறுக்குவழிகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது."</string>
-    <string name="permlab_write_settings" msgid="3574213698004620587">"முகப்பின் அமைப்புகள் மற்றும் குறுக்குவழிகளை எழுதுதல்"</string>
-    <string name="permdesc_write_settings" msgid="5440712911516509985">"முகப்பில் உள்ள அமைப்புகள் மற்றும் குறுக்குவழிகளை மாற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
+    <string name="permlab_read_settings" msgid="1941457408239617576">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளைப் படித்தல்"</string>
+    <string name="permdesc_read_settings" msgid="5833423719057558387">"முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது."</string>
+    <string name="permlab_write_settings" msgid="3574213698004620587">"முகப்பின் அமைப்பு மற்றும் குறுக்குவழிகளை எழுதுதல்"</string>
+    <string name="permdesc_write_settings" msgid="5440712911516509985">"முகப்பில் உள்ள அமைப்பு மற்றும் குறுக்குவழிகளை மாற்ற பயன்பாட்டை அனுமதிக்கிறது."</string>
     <string name="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="dream_name" msgid="1530253749244328964">"ராக்கெட் லாஞ்சர்"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"பெயரிடப்படாத கோப்புறை"</string>
@@ -95,9 +95,12 @@
     <string name="migration_cling_copy_apps" msgid="946331230090919440">"ஐகான்களை நகலெடு"</string>
     <string name="migration_cling_use_default" msgid="2626475813981258626">"புதிதாகத் தொடங்கு"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"இடத்தை ஒழுங்கமைக்கவும்"</string>
-    <string name="workspace_cling_move_item" msgid="528201129978005352">"வால்பேப்பர், விட்ஜெட்கள் மற்றும் அமைப்புகளை நிர்வகிப்பதற்கு பின்புலத்தைத் தொட்டுப் &amp; பிடிக்கவும்."</string>
+    <string name="workspace_cling_move_item" msgid="528201129978005352">"வால்பேப்பர், விட்ஜெட்கள், அமைப்பை நிர்வகிக்க பின்புலத்தைத் தொட்டுப் பிடிக்கவும்."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"வால்பேப்பர்கள், விட்ஜெட்கள் &amp; அமைப்புகள்"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"தனிப்பயனாக்க, பின்னணியைத் தொட்டுப் பிடிக்கவும்"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"புரிந்தது"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"இதோ கோப்புறை"</string>
-    <string name="folder_cling_create_folder" msgid="6158215559475836131">"இதுபோன்ற ஒன்றை உருவாக்கப் பயன்பாட்டைத் தொட்டுப் &amp; பிடிக்கவும், பிறகு அதை வேறொன்றிற்கு நகர்த்தவும்."</string>
+    <string name="folder_cling_create_folder" msgid="6158215559475836131">"இதுபோன்ற ஒன்றை உருவாக்க பயன்பாட்டைத் தொட்டுப் பிடிக்கவும், பிறகு அதை வேறொன்றிற்கு நகர்த்தவும்."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"சரி"</string>
     <string name="folder_opened" msgid="94695026776264709">"திறக்கப்பட்டக் கோப்புறை, <xliff:g id="WIDTH">%1$d</xliff:g> x <xliff:g id="HEIGHT">%2$d</xliff:g>"</string>
     <string name="folder_tap_to_close" msgid="1884479294466410023">"கோப்புறையை மூட, தொடவும்"</string>
@@ -105,9 +108,9 @@
     <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="8119458837558863227">"அமைப்புகள்"</string>
+    <string name="settings_button_text" msgid="8119458837558863227">"அமைப்பு"</string>
     <string name="package_state_enqueued" msgid="6227252464303085641">"காத்திருக்கிறது"</string>
     <string name="package_state_downloading" msgid="4088770468458724721">"பதிவிறக்குகிறது"</string>
     <string name="package_state_installing" msgid="7588193972189849870">"நிறுவுகிறது"</string>
diff --git a/res/values-te-rIN/strings.xml b/res/values-te-rIN/strings.xml
index b48d6b8..bfbc792 100644
--- a/res/values-te-rIN/strings.xml
+++ b/res/values-te-rIN/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android ప్రధాన అనువర్తనాలు"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"అనువర్తనం ఇన్‌స్టాల్ చేయబడలేదు."</string>
-    <string name="safemode_shortcut_error" msgid="9160126848219158407">"సురక్షిత మోడ్‌లో డౌన్‌లోడ్ చేసిన అనువర్తనం నిలిపివేయబడింది"</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="widgets_tab_label" msgid="2921133187116603919">"విడ్జెట్‌లు"</string>
     <string name="widget_adder" msgid="3201040140710381657">"విడ్జెట్‌లు"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"మెమరీ చూపు"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"విడ్జెట్‌ను ఎంచుకోవడానికి తాకి &amp; నొక్కి పెట్టండి."</string>
-    <string name="market" msgid="2619650989819296998">"షాపింగ్ చేయి"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"ఈ హోమ్ స్క్రీన్‌లో అంశాన్ని వదలడం సాధ్యపడలేదు."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"సృష్టించాల్సిన విడ్జెట్ ఎంచుకోండి"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"తీసివేయి"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"అన్ఇన్‌స్టాల్ చేయి"</string>
     <string name="info_target_label" msgid="8053346143994679532">"అనువర్తన సమాచారం"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"శోధించు"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"వాయిస్ శోధన"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"అనువర్తనాలు"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"తీసివేయి"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"నవీకరణను అన్‌ఇన్‌స్టాల్ చేయి"</string>
@@ -77,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"హోమ్ సెట్టింగ్‌లు మరియు సత్వరమార్గాలను వ్రాయడం"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"హోమ్‌లో సెట్టింగ్‌లు మరియు సత్వరమార్గాలను మార్చడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</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="dream_name" msgid="1530253749244328964">"రాకెట్ లాంచర్"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"పేరు లేని ఫోల్డర్"</string>
@@ -96,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"తాజాగా ప్రారంభించు"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"మీ స్థలాన్ని నిర్వహించండి"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"వాల్‌., విడ్జె., సెట్టి. నిర్వ. నేపథ్యం తాకి &amp; నొక్కి పెట్టండి."</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"వాల్‌పేపర్‌లు, విడ్జెట్‌లు &amp; సెట్టింగ్‌లు"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"అనుకూలీకరించడానికి నేపథ్యాన్ని నొక్కి &amp; ఉంచండి"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"అర్థమైంది"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"ఇక్కడ ఫోల్డర్ ఉంది"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"ఇలాంటిది సృష్టించడానికి అనువర్తనాన్ని తాకి &amp; నొక్కి పెట్టండి, ఆపై మరోదాని పైన ఉంచండి."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"సరే"</string>
diff --git a/res/values-th-land/strings.xml b/res/values-th-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-th-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index beed898..0fc20d2 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"แอปหลักของ Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"วิดเจ็ต"</string>
     <string name="widget_adder" msgid="3201040140710381657">"วิดเจ็ต"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"แสดง Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"แตะค้างเพื่อรับวิดเจ็ต"</string>
-    <string name="market" msgid="2619650989819296998">"เลือกซื้อ"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"ไม่สามารถวางรายการลงในหน้าจอหลักนี้"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"เลือกวิดเจ็ตที่จะสร้าง"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"ลบ"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"ถอนการติดตั้ง"</string>
     <string name="info_target_label" msgid="8053346143994679532">"ข้อมูลแอป"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"ค้นหา"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"ค้นหาด้วยเสียง"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"แอป"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"ลบ"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"ถอนการติดตั้งการอัปเดต"</string>
diff --git a/res/values-tl-land/strings.xml b/res/values-tl-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-tl-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 7c6acd2..4d2f1d4 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Core Apps"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Hindi naka-install ang app."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Hindi available ang app"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Naka-disable ang na-download na app sa Safe mode"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Naka-disable ang mga widget sa Safe mode"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Mga Widget"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Mga Widget"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Ipakita ang Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Pindutin nang matagal upang kumuha ng widget."</string>
-    <string name="market" msgid="2619650989819296998">"Mamili"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Hindi ma-drop ang item sa Home screen na ito."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Pumili ng widget na gagawin"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Alisin"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"I-uninstall"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Impormasyon ng app"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Hanapin"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Paghahanap Gamit ang Boses"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Apps"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Alisin"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"I-uninstall ang update"</string>
diff --git a/res/values-tr-land/strings.xml b/res/values-tr-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-tr-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 6c0bb69..6c78f6f 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android Çekirdek Uygulamaları"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Uygulama yüklü değil."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Uygulama kullanılamıyor"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"İndirilen uygulama Güvenli modda devre dışı bırakıldı"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Güvenli modda widget\'lar devre dışı"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Widget\'lar"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Widget\'lar"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Belleği Göster"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Widget seçmek için dokunun ve basılı tutun."</string>
-    <string name="market" msgid="2619650989819296998">"Mağaza"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Öğe bu Ana ekrana bırakılamadı."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Oluşturmak için widget seçin"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Kaldır"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Yüklemeyi kaldır"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Uygulama bilgileri"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Ara"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Sesli Arama"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Uygulamalar"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Kaldır"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Güncellemeyi kaldır"</string>
diff --git a/res/values-uk-land/strings.xml b/res/values-uk-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-uk-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 52f3761..71e1816 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -23,13 +23,14 @@
     <string name="home" msgid="7658288663002113681">"Головний екран"</string>
     <string name="uid_name" msgid="7820867637514617527">"Базові програми Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
-    <string name="activity_not_found" msgid="8071924732094499514">"Програму не встановлено."</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="widgets_tab_label" msgid="2921133187116603919">"Віджети"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Віджети"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Показати пам’ять"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Натисніть і утримуйте, щоб вибрати віджет."</string>
-    <string name="market" msgid="2619650989819296998">"Магазин"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Не вдалося додати елемент на цей головний екран."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Вибрати віджет для створення"</string>
@@ -38,7 +39,7 @@
     <string name="rename_action" msgid="5559600076028658757">"OК"</string>
     <string name="cancel_action" msgid="7009134900002915310">"Скасувати"</string>
     <string name="menu_item_add_item" msgid="1264911265836810421">"Додати на головний екран"</string>
-    <string name="group_applications" msgid="3797214114206693605">"Програми"</string>
+    <string name="group_applications" msgid="3797214114206693605">"Додатки"</string>
     <string name="group_shortcuts" msgid="6012256992764410535">"Ярлики"</string>
     <string name="group_widgets" msgid="1569030723286851002">"Віджети"</string>
     <string name="completely_out_of_space" msgid="6106288382070760318">"На головних екранах більше немає місця."</string>
@@ -50,16 +51,14 @@
     <string name="shortcut_duplicate" msgid="9167217446062498127">"Ярлик \"<xliff:g id="NAME">%s</xliff:g>\" уже існує."</string>
     <string name="title_select_shortcut" msgid="6680642571148153868">"Вибрати ярлик"</string>
     <string name="title_select_application" msgid="3280812711670683644">"Вибрати програму"</string>
-    <string name="all_apps_button_label" msgid="9110807029020582876">"Програми"</string>
+    <string name="all_apps_button_label" msgid="9110807029020582876">"Додатки"</string>
     <string name="all_apps_home_button_label" msgid="252062713717058851">"Головний екран"</string>
     <string name="delete_zone_label_workspace" msgid="4009607676751398685">"Вилучити"</string>
     <string name="delete_zone_label_all_apps" msgid="8083826390278958980">"Видалити"</string>
     <string name="delete_target_label" msgid="1822697352535677073">"Вилучити"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Видалити"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Про програму"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Пошук"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Голосовий пошук"</string>
-    <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Програми"</string>
+    <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Додатки"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Вилучити"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Видалити оновлення"</string>
     <string name="cab_menu_delete_app" msgid="7435191475867183689">"Видалити програму"</string>
diff --git a/res/values-ur-rPK/strings.xml b/res/values-ur-rPK/strings.xml
index 33b502e..ba1d3fa 100644
--- a/res/values-ur-rPK/strings.xml
+++ b/res/values-ur-rPK/strings.xml
@@ -24,13 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"‏Android کور ایپس"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"ایپ انسٹال نہیں ہے۔"</string>
-    <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
-    <skip />
+    <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="widgets_tab_label" msgid="2921133187116603919">"ویجیٹس"</string>
     <string name="widget_adder" msgid="3201040140710381657">"ویجیٹس"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"‏Mem دکھائیں"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"کوئی ویجیٹ منتخب کرنے کیلئے ٹچ کریں اور پکڑے رہیں۔"</string>
-    <string name="market" msgid="2619650989819296998">"خریداری کریں"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"آئٹم کو اس ہوم اسکرین پر ڈراپ نہیں کیا جا سکا۔"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"بنانے کیلئے ویجیٹ منتخب کریں"</string>
@@ -58,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"ہٹائیں"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"اَن انسٹال کریں"</string>
     <string name="info_target_label" msgid="8053346143994679532">"ایپ کی معلومات"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"تلاش کریں"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"صوتی تلاش"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"ایپس"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"ہٹائیں"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"اپ ڈیٹ اَن انسٹال کریں"</string>
@@ -78,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"ہوم ترتیبات اور شارٹ کٹس کو لکھیں"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"ایپ کو ہوم میں ترتیبات اور شارٹ کٹس کو تبدیل کرنے کی اجازت دیتا ہے۔"</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="dream_name" msgid="1530253749244328964">"راکٹ لانچر"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"بلا نام فولڈر"</string>
@@ -97,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"نئے سرے سے شروع کریں"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"اپنی جگہ کو منظم کریں"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"وال پیپر، ویجیٹس اور ترتیبات کا نظم کرنے کیلئے پس منظر کو ٹچ کریں اور پکڑ کر رکھیں۔"</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"وال پیپرز، ویجیٹس اور ترتیبات"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"حسب ضرورت بنانے کیلئے پس منظر کو ٹچ کریں اور دبائے رکھیں"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"سمجھ آ گئی"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"یہ ہے ایک فولڈر"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"اس طرح کا ایک بنانے کیلئے، کسی ایپ کو ٹچ کریں اور پکڑ کر رکھیں، پھر اسے کسی دوسرے میں منتقل کریں۔"</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"ٹھیک ہے"</string>
diff --git a/res/values-uz-rUZ/strings.xml b/res/values-uz-rUZ/strings.xml
index 791f6c8..a3c5670 100644
--- a/res/values-uz-rUZ/strings.xml
+++ b/res/values-uz-rUZ/strings.xml
@@ -24,13 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Androidga asoslangan dasturlar"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Ilova o‘rnatilmadi."</string>
-    <!-- no translation found for safemode_shortcut_error (9160126848219158407) -->
-    <skip />
+    <string name="activity_not_available" msgid="7456344436509528827">"Ilova mavjud emas"</string>
+    <string name="safemode_shortcut_error" msgid="9160126848219158407">"Yuklab olingan ilova xavfsiz rejimda o‘chirib qo‘yildi"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Xavfsiz rejimda vidjetlar o‘chirib qo‘yilgan"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Vidjetlar"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Vidjetlar"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Xotirani ko‘rsatish"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Vidjetni tanlash uchun bosib turing."</string>
-    <string name="market" msgid="2619650989819296998">"Do‘kon"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Elementni ushbu \"Uy\" ekraniga tashlab bo‘lmadi."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Yaratish uchun vidjet tanlang"</string>
@@ -58,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"O‘chirish"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"O‘chirish"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Ilova ma’lumoti"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Izlash"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ovozli qidiruv"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Ilovalar"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"O‘chirish"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Yangilashni o‘chirish"</string>
@@ -78,6 +76,7 @@
     <string name="permlab_write_settings" msgid="3574213698004620587">"Uy sozlamalari va yorliqlarini yozish"</string>
     <string name="permdesc_write_settings" msgid="5440712911516509985">"Ilovaga \"Uy\" ekranidagi yorliqlar va sozlamalrni o‘zgartirish uchun ruxsat beradi."</string>
     <string name="gadget_error_text" msgid="6081085226050792095">"Vidjetni yuklashda muammo"</string>
+    <string name="gadget_setup_text" msgid="8274003207686040488">"Sozlash"</string>
     <string name="uninstall_system_app_text" msgid="4172046090762920660">"Bu tizim ilovasi, shuning uchun o‘chirib bo‘lmaydi."</string>
     <string name="dream_name" msgid="1530253749244328964">"Rocket Launcher"</string>
     <string name="folder_hint_text" msgid="6617836969016293992">"Nomsiz jild"</string>
@@ -97,6 +96,9 @@
     <string name="migration_cling_use_default" msgid="2626475813981258626">"YANGIDAN BOSHLASH"</string>
     <string name="workspace_cling_title" msgid="5626202359865825661">"Joylaringizni boshqaring"</string>
     <string name="workspace_cling_move_item" msgid="528201129978005352">"Fon rasmi, vidjet va sozlamalarni boshqarish uchun orqa fonga bosib turing"</string>
+    <string name="workspace_cling_longpress_title" msgid="9173998993909018310">"Orqa fon rasmlari, vidjet va sozlamalar"</string>
+    <string name="workspace_cling_longpress_description" msgid="4119994475505235248">"Orqa fonni moslashtirish uchun uni bosing va ushlab turing"</string>
+    <string name="workspace_cling_longpress_dismiss" msgid="368660286867640874">"OK"</string>
     <string name="folder_cling_title" msgid="3894908818693254164">"Mana sizga jild"</string>
     <string name="folder_cling_create_folder" msgid="6158215559475836131">"Bunga o‘xshaganini yaratish uchun bosib turing, keyin boshqasiga o‘ting."</string>
     <string name="cling_dismiss" msgid="8962359497601507581">"OK"</string>
diff --git a/res/values-v17/styles.xml b/res/values-v17/styles.xml
index 71c4bfa..11d2a1f 100644
--- a/res/values-v17/styles.xml
+++ b/res/values-v17/styles.xml
@@ -3,7 +3,4 @@
     <style name="PagedViewWidgetImageView">
         <item name="android:paddingStart">@dimen/app_widget_preview_padding_left</item>
     </style>
-    <style name="SearchButton.WithPaddingStart">
-        <item name="android:paddingStart">8dp</item>
-    </style>
 </resources>
diff --git a/res/values-vi-land/strings.xml b/res/values-vi-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-vi-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 4891230..5bc1627 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Ứng dụng lõi Android"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Ứng dụng chưa được cài đặt."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Ứng dụng không có sẵn"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Ứng dụng đã tải xuống bị tắt ở chế độ An toàn"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Tiện ích con bị vô hiệu hóa ở chế độ an toàn"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Tiện ích con"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Tiện ích con"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Hiển thị bộ nhớ"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Chạm và giữ để chọn tiện ích con."</string>
-    <string name="market" msgid="2619650989819296998">"Mua"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Không thể thả mục vào Màn hình chính này."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Chọn tiện ích con để tạo"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Xóa"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Gỡ cài đặt"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Thông tin ứng dụng"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Tìm kiếm"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Tìm kiếm bằng giọng nói"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Ứng dụng"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Xóa"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Gỡ cài đặt cập nhật"</string>
diff --git a/res/values-zh-rCN-land/strings.xml b/res/values-zh-rCN-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-zh-rCN-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 3365581..b7c42fe 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android 核心应用"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"小部件"</string>
     <string name="widget_adder" msgid="3201040140710381657">"小部件"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"显示内存空间"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"触摸并按住小部件即可选择。"</string>
-    <string name="market" msgid="2619650989819296998">"商店"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"无法将相关内容拖放到此主屏幕上。"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"选择要创建的小部件"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"删除"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"卸载"</string>
     <string name="info_target_label" msgid="8053346143994679532">"应用信息"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"搜索"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"语音搜索"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"应用"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"删除"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"卸载更新内容"</string>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index e1c2063..2eb7008 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android 核心應用程式"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"小工具"</string>
     <string name="widget_adder" msgid="3201040140710381657">"小工具"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"顯示記憶體"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"輕觸並按住小工具即可選取。"</string>
-    <string name="market" msgid="2619650989819296998">"商店"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"無法將項目拖放至主畫面。"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"選擇要建立的小工具"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"移除"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"解除安裝"</string>
     <string name="info_target_label" msgid="8053346143994679532">"應用程式資料"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"搜尋"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"語音搜尋"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"應用程式"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"移除"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"解除安裝更新"</string>
@@ -69,9 +68,9 @@
     <string name="cab_folder_selection_text" msgid="7999992513806132118">"已選取 1 個資料夾"</string>
     <string name="cab_shortcut_selection_text" msgid="2103811025667946450">"已選取 1 個捷徑"</string>
     <string name="permlab_install_shortcut" msgid="5632423390354674437">"安裝捷徑"</string>
-    <string name="permdesc_install_shortcut" msgid="923466509822011139">"允許應用程式無需用戶許可也可新增捷徑。"</string>
+    <string name="permdesc_install_shortcut" msgid="923466509822011139">"允許應用程式無需使用者許可也可新增捷徑。"</string>
     <string name="permlab_uninstall_shortcut" msgid="864595034498083837">"解除安裝捷徑"</string>
-    <string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"允許應用程式無需用戶許可也可移除捷徑。"</string>
+    <string name="permdesc_uninstall_shortcut" msgid="5134129545001836849">"允許應用程式無需使用者許可也可移除捷徑。"</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>
diff --git a/res/values-zh-rTW-land/strings.xml b/res/values-zh-rTW-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-zh-rTW-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 2d40059..52e7583 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Android 核心應用程式"</string>
     <string name="folder_name" msgid="7371454440695724752"></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="widgets_tab_label" msgid="2921133187116603919">"小工具"</string>
     <string name="widget_adder" msgid="3201040140710381657">"小工具"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"顯示記憶體"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"輕觸並按住小工具即可選取。"</string>
-    <string name="market" msgid="2619650989819296998">"購物"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"無法將項目拖放至這個主螢幕上。"</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"選擇要建立的小工具"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"移除"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"解除安裝"</string>
     <string name="info_target_label" msgid="8053346143994679532">"應用程式資訊"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"搜尋"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"語音搜尋"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"應用程式"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"移除"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"解除安裝更新"</string>
diff --git a/res/values-zu-land/strings.xml b/res/values-zu-land/strings.xml
deleted file mode 100644
index b976926..0000000
--- a/res/values-zu-land/strings.xml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- 
-/*
-* Copyright (C) 2011 The Android Open Source Project
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="delete_target_label" msgid="4155210680095864979"></string>
-    <string name="delete_target_uninstall_label" msgid="1839407506844917298"></string>
-    <string name="info_target_label" msgid="1424400595004570393"></string>
-</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index 89cd5cc..aea09e8 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -24,12 +24,13 @@
     <string name="uid_name" msgid="7820867637514617527">"Izinhlelo zokusebenza ze-Android Core"</string>
     <string name="folder_name" msgid="7371454440695724752"></string>
     <string name="activity_not_found" msgid="8071924732094499514">"Uhlelo lokusebenza alufakiwe."</string>
+    <string name="activity_not_available" msgid="7456344436509528827">"Uhlelo lokusebenza alutholakali"</string>
     <string name="safemode_shortcut_error" msgid="9160126848219158407">"Uhlelo lokusebenza olulandiwe lukhutshaziwe kumodi ephephile"</string>
+    <string name="safemode_widget_error" msgid="4863470563535682004">"Amawijethi akhutshaziwe kwimodi yokuphepha"</string>
     <string name="widgets_tab_label" msgid="2921133187116603919">"Amawijethi"</string>
     <string name="widget_adder" msgid="3201040140710381657">"Amawijethi"</string>
     <string name="toggle_weight_watcher" msgid="5645299835184636119">"Bonisa i-Mem"</string>
     <string name="long_press_widget_to_add" msgid="7699152356777458215">"Thinta uphinde ubambe ukuze uphakamise iwijethi."</string>
-    <string name="market" msgid="2619650989819296998">"Thenga"</string>
     <string name="widget_dims_format" msgid="2370757736025621599">"%1$d × %2$d"</string>
     <string name="external_drop_widget_error" msgid="3165821058322217155">"Ayikwazanga ukwehlisela into kulesi sikrini se-Ikhaya."</string>
     <string name="external_drop_widget_pick_title" msgid="3486317258037690630">"Khetha iwijethi ongayidala"</string>
@@ -57,8 +58,6 @@
     <string name="delete_target_label" msgid="1822697352535677073">"Susa"</string>
     <string name="delete_target_uninstall_label" msgid="5100785476250872595">"Khipha"</string>
     <string name="info_target_label" msgid="8053346143994679532">"Ulwazi lohlelo lokusebenza"</string>
-    <string name="accessibility_search_button" msgid="1628520399424565142">"Sesha"</string>
-    <string name="accessibility_voice_search_button" msgid="4637324840434406584">"Ukusesha ngezwi"</string>
     <string name="accessibility_all_apps_button" msgid="2603132375383800483">"Izinhlelo zokusebenza"</string>
     <string name="accessibility_delete_button" msgid="6466114477993744621">"Susa"</string>
     <string name="delete_zone_label_all_apps_system_app" msgid="449755632749610895">"Khipha isibuyekezo"</string>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 65f8f22..3331cde 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -18,13 +18,6 @@
 
 <resources>
 
-    <!-- DrawableStateProxyView specific attributes. These attributes are used to customize
-         a DrawableStateProxyView view in XML files. -->
-    <declare-styleable name="DrawableStateProxyView">
-        <!-- The source view to delegate touch presses events to. -->
-        <attr name="sourceViewId" format="integer" />
-    </declare-styleable>
-
     <!-- Page Indicator specific attributes. -->
     <declare-styleable name="PageIndicator">
         <attr name="windowSize" format="integer"  />
@@ -76,13 +69,6 @@
         <attr name="strokeWidth" format="float" />
     </declare-styleable>
 
-    <!-- HolographicLinearLayout specific attributes. -->
-    <declare-styleable name="HolographicLinearLayout">
-        <!-- The source view to generate and apply the drawable states to/from -->
-        <attr name="sourceImageViewId" format="integer" />
-        <attr name="stateHotwordOn" format="boolean" />
-    </declare-styleable>
-
     <!-- PagedView specific attributes. These attributes are used to customize
          a PagedView view in XML files. -->
     <declare-styleable name="PagedView">
@@ -130,12 +116,14 @@
         <attr name="title" format="reference" />
         <attr name="uri" format="string" />
     </declare-styleable>
+
     <declare-styleable name="Extra">
         <attr name="key" format="string" />
         <attr name="value" format="string" />
     </declare-styleable>
     <declare-styleable name="Include">
         <attr name="workspace" format="reference" />
+        <attr name="folderItems" format="reference" />
     </declare-styleable>
 
     <declare-styleable name="PreloadIconDrawable">
@@ -143,4 +131,8 @@
         <attr name="ringOutset" format="dimension" />
         <attr name="indicatorSize" format="dimension" />
     </declare-styleable>
+
+    <declare-styleable name="InsettableFrameLayout_Layout">
+        <attr name="layout_ignoreInsets" format="boolean" />
+    </declare-styleable>
 </resources>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 29837ea..2daf9fe 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -29,8 +29,6 @@
 
     <color name="appwidget_error_color">#FCCC</color>
 
-    <color name="workspace_all_apps_and_delete_zone_text_color">#CCFFFFFF</color>
-    <color name="workspace_all_apps_and_delete_zone_text_shadow_color">#A0000000</color>
     <color name="workspace_icon_text_color">#FFF</color>
 
     <color name="quantum_panel_text_color">#FF666666</color>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 2c9e689..f12cb57 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -25,8 +25,8 @@
     <dimen name="dynamic_grid_workspace_page_spacing">8dp</dimen>
     <dimen name="dynamic_grid_overview_min_icon_zone_height">80dp</dimen>
     <dimen name="dynamic_grid_overview_max_icon_zone_height">120dp</dimen>
-    <dimen name="dynamic_grid_overview_bar_item_width">48dp</dimen>
-    <dimen name="dynamic_grid_overview_bar_spacer_width">68dp</dimen>
+    <dimen name="dynamic_grid_overview_bar_item_width">80dp</dimen>
+    <dimen name="dynamic_grid_overview_bar_spacer_width">20dp</dimen>
 
 <!-- Cling -->
     <dimen name="cling_migration_logo_height">240dp</dimen>
@@ -43,9 +43,6 @@
 <!-- QSB -->
     <dimen name="toolbar_button_vertical_padding">4dip</dimen>
     <dimen name="toolbar_button_horizontal_padding">12dip</dimen>
-    <!-- External toolbar icon size (for bounds) -->
-    <dimen name="toolbar_external_icon_width">36dp</dimen>
-    <dimen name="toolbar_external_icon_height">36dp</dimen>
 
 <!-- AllApps/Customize/AppsCustomize -->
     <!-- The height of the tab bar - if this changes, we should update the
@@ -62,6 +59,7 @@
 
     <!-- Drag padding to add to the bottom of drop targets -->
     <dimen name="drop_target_drag_padding">14dp</dimen>
+    <dimen name="drop_target_text_size">14sp</dimen>
 
 <!-- Dragging -->
     <!-- the area at the edge of the screen that makes the workspace go left
diff --git a/res/values/strings.xml b/res/values/strings.xml
index ff3509b..b6f4237 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -40,8 +40,12 @@
     <string name="folder_name"></string>
     <!-- Displayed when user selects a shortcut for an app that was uninstalled [CHAR_LIMIT=none]-->
     <string name="activity_not_found">App isn\'t installed.</string>
+    <!-- Displayed when user selects a shortcut for an app that is current not available [CHAR_LIMIT=none]-->
+    <string name="activity_not_available">App isn\'t available</string>
     <!-- SafeMode shortcut error string -->
     <string name="safemode_shortcut_error">Downloaded app disabled in Safe mode</string>
+    <!-- SafeMode widget error string -->
+    <string name="safemode_widget_error">Widgets disabled in Safe mode</string>
     <!--  Labels for the tabs in the customize drawer -->
     <string name="widgets_tab_label">Widgets</string>
 
@@ -52,9 +56,6 @@
     <!-- AppsCustomize pane -->
     <!-- Message to tell the user to press and hold on a widget to add it [CHAR_LIMIT=50] -->
     <string name="long_press_widget_to_add">Touch &amp; hold to pick up a widget.</string>
-    <!-- Market button text.  The market button text is removed in Launcher.java 
-         in the Phone UI. [CHAR LIMIT=32] -->
-    <string name="market">Shop</string>
     <!-- The format string for the dimensions of a widget in the drawer -->
     <!-- There is a special version of this format string for Farsi -->
     <string name="widget_dims_format">%1$d \u00d7 %2$d</string>
@@ -124,17 +125,13 @@
          device. [CHAR_LIMIT=30]-->
     <string name="delete_zone_label_all_apps">Uninstall</string>
 
-    <!-- Label for delete drop target. [CHAR_LIMIT=30] -->
+    <!-- Label for delete drop target. [CHAR_LIMIT=20] -->
     <string name="delete_target_label">Remove</string>
-    <!-- Label for uninstall drop target. [CHAR_LIMIT=30]-->
+    <!-- Label for uninstall drop target. [CHAR_LIMIT=20]-->
     <string name="delete_target_uninstall_label">Uninstall</string>
-    <!-- Label for the info icon. [CHAR_LIMIT=30] -->
+    <!-- Label for the info icon. [CHAR_LIMIT=20] -->
     <string name="info_target_label">App info</string>
 
-    <!-- Accessibility: Search button -->
-    <string name="accessibility_search_button">Search</string>
-    <!-- Accessibility: Voice Search button -->
-    <string name="accessibility_voice_search_button">Voice Search</string>
     <!-- Accessibility: AllApps button -->
     <string name="accessibility_all_apps_button">Apps</string>
     <!-- Accessibility: Delete button -->
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 56a205f..77798f1 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -32,10 +32,9 @@
         <item name="android:fontFamily">sans-serif-condensed</item>
     </style>
 
-    <style name="WorkspaceIcon.Portrait">
-    </style>
-    <style name="WorkspaceIcon.Landscape">
-    </style>
+    <style name="WorkspaceIcon.Portrait"></style>
+
+    <style name="WorkspaceIcon.Landscape"></style>
 
     <style name="WorkspaceIcon.AppsCustomize">
         <item name="android:background">@null</item>
@@ -52,15 +51,14 @@
         <item name="customShadows">false</item>
     </style>
 
-    <style name="SearchDropTargetBar">
-    </style>
-    <style name="SearchButton">
-    </style>
+    <style name="SearchButton"></style>
+
     <style name="DropTargetButtonContainer">
         <item name="android:layout_width">0dp</item>
         <item name="android:layout_height">match_parent</item>
     </style>
-    <style name="DropTargetButton">
+
+    <style name="DropTargetButton.Base">
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">match_parent</item>
         <item name="android:layout_gravity">center</item>
@@ -69,7 +67,7 @@
         <item name="android:paddingLeft">25dp</item>
         <item name="android:paddingRight">25dp</item>
         <item name="android:textColor">#FFFFFFFF</item>
-        <item name="android:textSize">16sp</item>
+        <item name="android:textSize">@dimen/drop_target_text_size</item>
         <item name="android:singleLine">true</item>
         <item name="android:ellipsize">end</item>
         <item name="android:shadowColor">#FF000000</item>
@@ -78,34 +76,7 @@
         <item name="android:shadowRadius">4.0</item>
     </style>
 
-    <style name="TabIndicator">
-        <item name="android:layout_width">wrap_content</item>
-        <item name="android:layout_height">match_parent</item>
-        <item name="android:gravity">center</item>
-        <item name="android:paddingLeft">20dp</item>
-        <item name="android:paddingRight">20dp</item>
-        <item name="android:background">@drawable/tab_widget_indicator_selector</item>
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
-        <item name="android:textSize">12sp</item>
-        <item name="android:textStyle">bold</item>
-        <item name="android:textAllCaps">true</item>
-        <item name="android:singleLine">true</item>
-        <item name="android:ellipsize">end</item>
-    </style>
-    <style name="TabIndicator.AppsCustomize">
-        <!-- Overridden in values-land -->
-    </style>
-
-    <style name="MarketButton">
-        <item name="android:paddingLeft">5dp</item>
-        <item name="android:paddingRight">5dp</item>
-        <item name="android:textColor">@color/workspace_all_apps_and_delete_zone_text_color</item>
-        <item name="android:textSize">18sp</item>
-        <item name="android:shadowColor">@color/workspace_all_apps_and_delete_zone_text_shadow_color</item>
-        <item name="android:shadowDx">0.0</item>
-        <item name="android:shadowDy">0.0</item>
-        <item name="android:shadowRadius">2.0</item>
-    </style>
+    <style name="DropTargetButton" parent="DropTargetButton.Base"></style>
 
     <style name="PreloadIcon">
         <item name="background">@drawable/virtual_preload</item>
@@ -123,7 +94,5 @@
     <style name="PagedViewWidgetImageView">
         <item name="android:paddingLeft">@dimen/app_widget_preview_padding_left</item>
     </style>
-    <style name="SearchButton.WithPaddingStart">
-        <item name="android:paddingLeft">8dp</item>
-    </style>
+
 </resources>
diff --git a/res/xml/default_workspace_4x4_no_all_apps.xml b/res/xml/default_workspace_4x4_no_all_apps.xml
deleted file mode 100644
index 7e1301c..0000000
--- a/res/xml/default_workspace_4x4_no_all_apps.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
-    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
-    <!-- Dialer Hangouts Maps Chrome Camera -->
-    <favorite
-        launcher:packageName="com.google.android.dialer"
-        launcher:className="com.google.android.dialer.extensions.GoogleDialtactsActivity"
-        launcher:container="-101"
-        launcher:screen="0"
-        launcher:x="0"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.google.android.talk"
-        launcher:className="com.google.android.talk.SigningInActivity"
-        launcher:container="-101"
-        launcher:screen="1"
-        launcher:x="1"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.google.android.apps.maps"
-        launcher:className="com.google.android.maps.MapsActivity"
-        launcher:container="-101"
-        launcher:screen="2"
-        launcher:x="2"
-        launcher:y="0"/>
-    <favorite
-        launcher:packageName="com.android.chrome"
-        launcher:className="com.google.android.apps.chrome.Main"
-        launcher:container="-101"
-        launcher:screen="3"
-        launcher:x="3"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.google.android.GoogleCamera"
-        launcher:className="com.android.camera.CameraLauncher"
-        launcher:container="-101"
-        launcher:screen="4"
-        launcher:x="4"
-        launcher:y="0" />
-</favorites>
-
diff --git a/res/xml/default_workspace_5x5_no_all_apps.xml b/res/xml/default_workspace_5x5_no_all_apps.xml
deleted file mode 100644
index f54a204..0000000
--- a/res/xml/default_workspace_5x5_no_all_apps.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
-    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
-    <!-- Dialer Hangouts Maps Chrome Camera -->
-    <favorite
-        launcher:packageName="com.google.android.dialer"
-        launcher:className="com.google.android.dialer.extensions.GoogleDialtactsActivity"
-        launcher:container="-101"
-        launcher:screen="1"
-        launcher:x="1"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.google.android.talk"
-        launcher:className="com.google.android.talk.SigningInActivity"
-        launcher:container="-101"
-        launcher:screen="2"
-        launcher:x="2"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.google.android.apps.maps"
-        launcher:className="com.google.android.maps.MapsActivity"
-        launcher:container="-101"
-        launcher:screen="3"
-        launcher:x="3"
-        launcher:y="0"/>
-    <favorite
-        launcher:packageName="com.android.chrome"
-        launcher:className="com.google.android.apps.chrome.Main"
-        launcher:container="-101"
-        launcher:screen="4"
-        launcher:x="4"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.google.android.GoogleCamera"
-        launcher:className="com.android.camera.CameraLauncher"
-        launcher:container="-101"
-        launcher:screen="5"
-        launcher:x="5"
-        launcher:y="0" />
-</favorites>
-
diff --git a/res/xml/default_workspace_5x6_no_all_apps.xml b/res/xml/default_workspace_5x6_no_all_apps.xml
deleted file mode 100644
index f54a204..0000000
--- a/res/xml/default_workspace_5x6_no_all_apps.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2013 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<favorites xmlns:launcher="http://schemas.android.com/apk/res-auto/com.android.launcher3">
-    <!-- Hotseat (We use the screen as the position of the item in the hotseat) -->
-    <!-- Dialer Hangouts Maps Chrome Camera -->
-    <favorite
-        launcher:packageName="com.google.android.dialer"
-        launcher:className="com.google.android.dialer.extensions.GoogleDialtactsActivity"
-        launcher:container="-101"
-        launcher:screen="1"
-        launcher:x="1"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.google.android.talk"
-        launcher:className="com.google.android.talk.SigningInActivity"
-        launcher:container="-101"
-        launcher:screen="2"
-        launcher:x="2"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.google.android.apps.maps"
-        launcher:className="com.google.android.maps.MapsActivity"
-        launcher:container="-101"
-        launcher:screen="3"
-        launcher:x="3"
-        launcher:y="0"/>
-    <favorite
-        launcher:packageName="com.android.chrome"
-        launcher:className="com.google.android.apps.chrome.Main"
-        launcher:container="-101"
-        launcher:screen="4"
-        launcher:x="4"
-        launcher:y="0" />
-    <favorite
-        launcher:packageName="com.google.android.GoogleCamera"
-        launcher:className="com.android.camera.CameraLauncher"
-        launcher:container="-101"
-        launcher:screen="5"
-        launcher:x="5"
-        launcher:y="0" />
-</favorites>
-
diff --git a/src/com/android/launcher3/AccessibleTabView.java b/src/com/android/launcher3/AccessibleTabView.java
deleted file mode 100644
index 90a7865..0000000
--- a/src/com/android/launcher3/AccessibleTabView.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.KeyEvent;
-import android.widget.TextView;
-
-/**
- * We use a custom tab view to process our own focus traversals.
- */
-public class AccessibleTabView extends TextView {
-    public AccessibleTabView(Context context) {
-        super(context);
-    }
-
-    public AccessibleTabView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public AccessibleTabView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        return FocusHelper.handleTabKeyEvent(this, keyCode, event)
-                || super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        return FocusHelper.handleTabKeyEvent(this, keyCode, event)
-                || super.onKeyUp(keyCode, event);
-    }
-}
diff --git a/src/com/android/launcher3/AllAppsList.java b/src/com/android/launcher3/AllAppsList.java
index 38d2fa5..72c6693 100644
--- a/src/com/android/launcher3/AllAppsList.java
+++ b/src/com/android/launcher3/AllAppsList.java
@@ -18,10 +18,6 @@
 
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 
 import com.android.launcher3.compat.LauncherActivityInfoCompat;
 import com.android.launcher3.compat.LauncherAppsCompat;
@@ -101,17 +97,15 @@
         final List<LauncherActivityInfoCompat> matches = launcherApps.getActivityList(packageName,
                 user);
 
-        if (matches.size() > 0) {
-            for (LauncherActivityInfoCompat info : matches) {
-                add(new AppInfo(context, info, user, mIconCache, null));
-            }
+        for (LauncherActivityInfoCompat info : matches) {
+            add(new AppInfo(context, info, user, mIconCache, null));
         }
     }
 
     /**
      * Remove the apps for the given apk identified by packageName.
      */
-    public void removePackage(String packageName, UserHandleCompat user) {
+    public void removePackage(String packageName, UserHandleCompat user, boolean clearCache) {
         final List<AppInfo> data = this.data;
         for (int i = data.size() - 1; i >= 0; i--) {
             AppInfo info = data.get(i);
@@ -121,7 +115,9 @@
                 data.remove(i);
             }
         }
-        mIconCache.remove(packageName, user);
+        if (clearCache) {
+            mIconCache.remove(packageName, user);
+        }
     }
 
     /**
@@ -149,9 +145,7 @@
 
             // Find enabled activities and add them to the adapter
             // Also updates existing activities with new labels/icons
-            int count = matches.size();
-            for (int i = 0; i < count; i++) {
-                final LauncherActivityInfoCompat info = matches.get(i);
+            for (final LauncherActivityInfoCompat info : matches) {
                 AppInfo applicationInfo = findApplicationInfoLocked(
                         info.getComponentName().getPackageName(), user,
                         info.getComponentName().getClassName());
diff --git a/src/com/android/launcher3/AppInfo.java b/src/com/android/launcher3/AppInfo.java
index bfcad84..a66bac0 100644
--- a/src/com/android/launcher3/AppInfo.java
+++ b/src/com/android/launcher3/AppInfo.java
@@ -84,16 +84,11 @@
         flags = initFlags(info);
         firstInstallTime = info.getFirstInstallTime();
         iconCache.getTitleAndIcon(this, info, labelCache);
-        intent = new Intent(Intent.ACTION_MAIN);
-        intent.addCategory(Intent.CATEGORY_LAUNCHER);
-        intent.setComponent(info.getComponentName());
-        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-        long serialNumber = UserManagerCompat.getInstance(context).getSerialNumberForUser(user);
-        intent.putExtra(EXTRA_PROFILE, serialNumber);
+        intent = makeLaunchIntent(context, info, user);
         this.user = user;
     }
 
-    private static int initFlags(LauncherActivityInfoCompat info) {
+    public static int initFlags(LauncherActivityInfoCompat info) {
         int appFlags = info.getApplicationInfo().flags;
         int flags = 0;
         if ((appFlags & android.content.pm.ApplicationInfo.FLAG_SYSTEM) == 0) {
@@ -137,4 +132,14 @@
     public ShortcutInfo makeShortcut() {
         return new ShortcutInfo(this);
     }
+
+    public static Intent makeLaunchIntent(Context context, LauncherActivityInfoCompat info,
+            UserHandleCompat user) {
+        long serialNumber = UserManagerCompat.getInstance(context).getSerialNumberForUser(user);
+        return new Intent(Intent.ACTION_MAIN)
+            .addCategory(Intent.CATEGORY_LAUNCHER)
+            .setComponent(info.getComponentName())
+            .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
+            .putExtra(EXTRA_PROFILE, serialNumber);
+    }
 }
diff --git a/src/com/android/launcher3/AppsCustomizePagedView.java b/src/com/android/launcher3/AppsCustomizePagedView.java
index 1bd2907..c8187f0 100644
--- a/src/com/android/launcher3/AppsCustomizePagedView.java
+++ b/src/com/android/launcher3/AppsCustomizePagedView.java
@@ -366,11 +366,7 @@
                     // This code triggers requestLayout so must be posted outside of the
                     // layout pass.
                     public void run() {
-                        boolean attached = true;
-                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-                            attached = isAttachedToWindow();
-                        }
-                        if (attached) {
+                        if (Utilities.isViewAttachedToWindow(AppsCustomizePagedView.this)) {
                             setDataIsReady();
                             onDataReady(getMeasuredWidth(), getMeasuredHeight());
                         }
@@ -728,7 +724,8 @@
                 !(target instanceof DeleteDropTarget) && !(target instanceof Folder))) {
             // Exit spring loaded mode if we have not successfully dropped or have not handled the
             // drop in Workspace
-            mLauncher.exitSpringLoadedDragMode();
+            mLauncher.exitSpringLoadedDragModeDelayed(true,
+                    Launcher.EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT, null);
             mLauncher.unlockScreenOrientation(false);
         } else {
             mLauncher.unlockScreenOrientation(false);
@@ -842,6 +839,12 @@
         cancelAllTasks();
     }
 
+    @Override
+    public void trimMemory() {
+        super.trimMemory();
+        clearAllWidgetPages();
+    }
+
     public void clearAllWidgetPages() {
         cancelAllTasks();
         int count = getChildCount();
diff --git a/src/com/android/launcher3/AppsCustomizeTabHost.java b/src/com/android/launcher3/AppsCustomizeTabHost.java
index 9a516fd..a271712 100644
--- a/src/com/android/launcher3/AppsCustomizeTabHost.java
+++ b/src/com/android/launcher3/AppsCustomizeTabHost.java
@@ -16,27 +16,13 @@
 
 package com.android.launcher3;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.AnimatorSet;
-import android.animation.ObjectAnimator;
 import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Color;
 import android.graphics.Rect;
 import android.util.AttributeSet;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityManager;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.TabHost;
-import android.widget.TabWidget;
-import android.widget.TextView;
-
-import java.util.ArrayList;
 
 public class AppsCustomizeTabHost extends FrameLayout implements LauncherTransitionable, Insettable  {
     static final String LOG_TAG = "AppsCustomizeTabHost";
@@ -132,6 +118,10 @@
         mPagedView.reset();
     }
 
+    void trimMemory() {
+        mPagedView.trimMemory();
+    }
+
     public void onWindowVisible() {
         if (getVisibility() == VISIBLE) {
             mContent.setVisibility(VISIBLE);
@@ -141,14 +131,6 @@
             mPagedView.loadAssociatedPages(mPagedView.getCurrentPage());
         }
     }
-
-    public void onTrimMemory() {
-        mContent.setVisibility(GONE);
-        // Clear the widget pages of all their subviews - this will trigger the widget previews
-        // to delete their bitmaps
-        mPagedView.clearAllWidgetPages();
-    }
-
     @Override
     public ViewGroup getContent() {
         return mPagedView;
diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java
index 00f0cf3..a5d2228 100644
--- a/src/com/android/launcher3/AutoInstallsLayout.java
+++ b/src/com/android/launcher3/AutoInstallsLayout.java
@@ -36,7 +36,6 @@
 import android.util.Patterns;
 
 import com.android.launcher3.LauncherProvider.SqlArguments;
-import com.android.launcher3.LauncherProvider.WorkspaceLoader;
 import com.android.launcher3.LauncherSettings.Favorites;
 
 import org.xmlpull.v1.XmlPullParser;
@@ -47,13 +46,11 @@
 import java.util.HashMap;
 
 /**
- * This class contains contains duplication of functionality as found in
- * LauncherProvider#DatabaseHelper. It has been isolated and differentiated in order
- * to cleanly and separately represent AutoInstall default layout format and policy.
+ * Layout parsing code for auto installs layout
  */
-public class AutoInstallsLayout implements WorkspaceLoader {
+public class AutoInstallsLayout {
     private static final String TAG = "AutoInstalls";
-    private static final boolean LOGD = true;
+    private static final boolean LOGD = false;
 
     /** Marker action used to discover a package which defines launcher customization */
     static final String ACTION_LAUNCHER_CUSTOMIZATION =
@@ -76,7 +73,8 @@
             Log.e(TAG, "Layout definition not found in package: " + pkg);
             return null;
         }
-        return new AutoInstallsLayout(context, appWidgetHost, callback, pkg, res, layoutId);
+        return new AutoInstallsLayout(context, appWidgetHost, callback, res, layoutId,
+                TAG_WORKSPACE);
     }
 
     // Object Tags
@@ -116,45 +114,55 @@
     private final AppWidgetHost mAppWidgetHost;
     private final LayoutParserCallback mCallback;
 
-    private final PackageManager mPackageManager;
+    protected final PackageManager mPackageManager;
+    protected final Resources mSourceRes;
+    protected final int mLayoutId;
+
+    private final int mHotseatAllAppsRank;
+
+    private final long[] mTemp = new long[2];
     private final ContentValues mValues;
+    private final String mRootTag;
 
-    private final Resources mRes;
-    private final int mLayoutId;
-
-    private SQLiteDatabase mDb;
+    protected SQLiteDatabase mDb;
 
     public AutoInstallsLayout(Context context, AppWidgetHost appWidgetHost,
-            LayoutParserCallback callback, String packageName, Resources res, int layoutId) {
+            LayoutParserCallback callback, Resources res,
+            int layoutId, String rootTag) {
         mContext = context;
         mAppWidgetHost = appWidgetHost;
         mCallback = callback;
 
         mPackageManager = context.getPackageManager();
         mValues = new ContentValues();
+        mRootTag = rootTag;
 
-        mRes = res;
+        mSourceRes = res;
         mLayoutId = layoutId;
+        mHotseatAllAppsRank = LauncherAppState.getInstance()
+                .getDynamicGrid().getDeviceProfile().hotseatAllAppsRank;
     }
 
-    @Override
+    /**
+     * Loads the layout in the db and returns the number of entries added on the desktop.
+     */
     public int loadLayout(SQLiteDatabase db, ArrayList<Long> screenIds) {
         mDb = db;
         try {
-            return parseLayout(mRes, mLayoutId, screenIds);
-        } catch (XmlPullParserException | IOException | RuntimeException e) {
+            return parseLayout(mLayoutId, screenIds);
+        } catch (Exception e) {
             Log.w(TAG, "Got exception parsing layout.", e);
             return -1;
         }
     }
 
-    private int parseLayout(Resources res, int layoutId, ArrayList<Long> screenIds)
+    /**
+     * Parses the layout and returns the number of elements added on the homescreen.
+     */
+    protected int parseLayout(int layoutId, ArrayList<Long> screenIds)
             throws XmlPullParserException, IOException {
-        final int hotseatAllAppsRank = LauncherAppState.getInstance()
-                .getDynamicGrid().getDeviceProfile().hotseatAllAppsRank;
-
-        XmlResourceParser parser = res.getXml(layoutId);
-        beginDocument(parser, TAG_WORKSPACE);
+        XmlResourceParser parser = mSourceRes.getXml(layoutId);
+        beginDocument(parser, mRootTag);
         final int depth = parser.getDepth();
         int type;
         HashMap<String, TagParser> tagParserMap = getLayoutElementsMap();
@@ -165,47 +173,62 @@
             if (type != XmlPullParser.START_TAG) {
                 continue;
             }
-
-            mValues.clear();
-            final int container;
-            final long screenId;
-
-            if (HOTSEAT_CONTAINER_NAME.equals(getAttributeValue(parser, ATTR_CONTAINER))) {
-                container = Favorites.CONTAINER_HOTSEAT;
-
-                // Hack: hotseat items are stored using screen ids
-                long rank = Long.parseLong(getAttributeValue(parser, ATTR_RANK));
-                screenId = (rank < hotseatAllAppsRank) ? rank : (rank + 1);
-
-            } else {
-                container = Favorites.CONTAINER_DESKTOP;
-                screenId = Long.parseLong(getAttributeValue(parser, ATTR_SCREEN));
-
-                mValues.put(Favorites.CELLX, getAttributeValue(parser, ATTR_X));
-                mValues.put(Favorites.CELLY, getAttributeValue(parser, ATTR_Y));
-            }
-
-            mValues.put(Favorites.CONTAINER, container);
-            mValues.put(Favorites.SCREEN, screenId);
-
-            TagParser tagParser = tagParserMap.get(parser.getName());
-            if (tagParser == null) {
-                if (LOGD) Log.d(TAG, "Ignoring unknown element tag: " + parser.getName());
-                continue;
-            }
-            long newElementId = tagParser.parseAndAdd(parser, res);
-            if (newElementId >= 0) {
-                // Keep track of the set of screens which need to be added to the db.
-                if (!screenIds.contains(screenId) &&
-                        container == Favorites.CONTAINER_DESKTOP) {
-                    screenIds.add(screenId);
-                }
-                count++;
-            }
+            count += parseAndAddNode(parser, tagParserMap, screenIds);
         }
         return count;
     }
 
+    /**
+     * Parses container and screenId attribute from the current tag, and puts it in the out.
+     * @param out array of size 2.
+     */
+    protected void parseContainerAndScreen(XmlResourceParser parser, long[] out) {
+        if (HOTSEAT_CONTAINER_NAME.equals(getAttributeValue(parser, ATTR_CONTAINER))) {
+            out[0] = Favorites.CONTAINER_HOTSEAT;
+            // Hack: hotseat items are stored using screen ids
+            long rank = Long.parseLong(getAttributeValue(parser, ATTR_RANK));
+            out[1] = (rank < mHotseatAllAppsRank) ? rank : (rank + 1);
+        } else {
+            out[0] = Favorites.CONTAINER_DESKTOP;
+            out[1] = Long.parseLong(getAttributeValue(parser, ATTR_SCREEN));
+        }
+    }
+
+    /**
+     * Parses the current node and returns the number of elements added.
+     */
+    protected int parseAndAddNode(
+            XmlResourceParser parser,
+            HashMap<String, TagParser> tagParserMap,
+            ArrayList<Long> screenIds)
+                    throws XmlPullParserException, IOException {
+        mValues.clear();
+        parseContainerAndScreen(parser, mTemp);
+        final long container = mTemp[0];
+        final long screenId = mTemp[1];
+
+        mValues.put(Favorites.CONTAINER, container);
+        mValues.put(Favorites.SCREEN, screenId);
+        mValues.put(Favorites.CELLX, getAttributeValue(parser, ATTR_X));
+        mValues.put(Favorites.CELLY, getAttributeValue(parser, ATTR_Y));
+
+        TagParser tagParser = tagParserMap.get(parser.getName());
+        if (tagParser == null) {
+            if (LOGD) Log.d(TAG, "Ignoring unknown element tag: " + parser.getName());
+            return 0;
+        }
+        long newElementId = tagParser.parseAndAdd(parser);
+        if (newElementId >= 0) {
+            // Keep track of the set of screens which need to be added to the db.
+            if (!screenIds.contains(screenId) &&
+                    container == Favorites.CONTAINER_DESKTOP) {
+                screenIds.add(screenId);
+            }
+            return 1;
+        }
+        return 0;
+    }
+
     protected long addShortcut(String title, Intent intent, int type) {
         long id = mCallback.generateNewItemId();
         mValues.put(Favorites.INTENT, intent.toUri(0));
@@ -225,7 +248,7 @@
         HashMap<String, TagParser> parsers = new HashMap<String, TagParser>();
         parsers.put(TAG_APP_ICON, new AppShortcutParser());
         parsers.put(TAG_AUTO_INSTALL, new AutoInstallParser());
-        parsers.put(TAG_SHORTCUT, new ShortcutParser());
+        parsers.put(TAG_SHORTCUT, new ShortcutParser(mSourceRes));
         return parsers;
     }
 
@@ -235,23 +258,26 @@
         parsers.put(TAG_AUTO_INSTALL, new AutoInstallParser());
         parsers.put(TAG_FOLDER, new FolderParser());
         parsers.put(TAG_APPWIDGET, new AppWidgetParser());
-        parsers.put(TAG_SHORTCUT, new ShortcutParser());
+        parsers.put(TAG_SHORTCUT, new ShortcutParser(mSourceRes));
         return parsers;
     }
 
-    private interface TagParser {
+    protected interface TagParser {
         /**
          * Parses the tag and adds to the db
          * @return the id of the row added or -1;
          */
-        long parseAndAdd(XmlResourceParser parser, Resources res)
+        long parseAndAdd(XmlResourceParser parser)
                 throws XmlPullParserException, IOException;
     }
 
-    private class AppShortcutParser implements TagParser {
+    /**
+     * App shortcuts: required attributes packageName and className
+     */
+    protected class AppShortcutParser implements TagParser {
 
         @Override
-        public long parseAndAdd(XmlResourceParser parser, Resources res) {
+        public long parseAndAdd(XmlResourceParser parser) {
             final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
             final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
 
@@ -277,20 +303,30 @@
                     return addShortcut(info.loadLabel(mPackageManager).toString(),
                             intent, Favorites.ITEM_TYPE_APPLICATION);
                 } catch (PackageManager.NameNotFoundException e) {
-                    Log.w(TAG, "Unable to add favorite: " + packageName + "/" + className, e);
+                    if (LOGD) Log.w(TAG, "Unable to add favorite: " + packageName + "/" + className, e);
                 }
                 return -1;
             } else {
-                if (LOGD) Log.d(TAG, "Skipping invalid <favorite> with no component or uri");
-                return -1;
+                return invalidPackageOrClass(parser);
             }
         }
+
+        /**
+         * Helper method to allow extending the parser capabilities
+         */
+        protected long invalidPackageOrClass(XmlResourceParser parser) {
+            if (LOGD) Log.d(TAG, "Skipping invalid <favorite> with no component");
+            return -1;
+        }
     }
 
-    private class AutoInstallParser implements TagParser {
+    /**
+     * AutoInstall: required attributes packageName and className
+     */
+    protected class AutoInstallParser implements TagParser {
 
         @Override
-        public long parseAndAdd(XmlResourceParser parser, Resources res) {
+        public long parseAndAdd(XmlResourceParser parser) {
             final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
             final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
             if (TextUtils.isEmpty(packageName) || TextUtils.isEmpty(className)) {
@@ -309,11 +345,19 @@
         }
     }
 
-    private class ShortcutParser implements TagParser {
+    /**
+     * Parses a web shortcut. Required attributes url, icon, title
+     */
+    protected class ShortcutParser implements TagParser {
+
+        private final Resources mIconRes;
+
+        public ShortcutParser(Resources iconRes) {
+            mIconRes = iconRes;
+        }
 
         @Override
-        public long parseAndAdd(XmlResourceParser parser, Resources res) {
-            final String url = getAttributeValue(parser, ATTR_URL);
+        public long parseAndAdd(XmlResourceParser parser) {
             final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
             final int iconId = getAttributeResourceValue(parser, ATTR_ICON, 0);
 
@@ -322,29 +366,46 @@
                 return -1;
             }
 
-            if (TextUtils.isEmpty(url) || !Patterns.WEB_URL.matcher(url).matches()) {
-                if (LOGD) Log.d(TAG, "Ignoring shortcut, invalid url: " + url);
+            final Intent intent = parseIntent(parser);
+            if (intent == null) {
                 return -1;
             }
-            Drawable icon = res.getDrawable(iconId);
+
+            Drawable icon = mIconRes.getDrawable(iconId);
             if (icon == null) {
                 if (LOGD) Log.d(TAG, "Ignoring shortcut, can't load icon");
                 return -1;
             }
 
             ItemInfo.writeBitmap(mValues, Utilities.createIconBitmap(icon, mContext));
-            final Intent intent = new Intent(Intent.ACTION_VIEW, null)
-                .setData(Uri.parse(url))
-                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+            mValues.put(Favorites.ICON_TYPE, Favorites.ICON_TYPE_RESOURCE);
+            mValues.put(Favorites.ICON_PACKAGE, mIconRes.getResourcePackageName(iconId));
+            mValues.put(Favorites.ICON_RESOURCE, mIconRes.getResourceName(iconId));
+
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
                         Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-            return addShortcut(res.getString(titleResId), intent, Favorites.ITEM_TYPE_SHORTCUT);
+            return addShortcut(mSourceRes.getString(titleResId),
+                    intent, Favorites.ITEM_TYPE_SHORTCUT);
+        }
+
+        protected Intent parseIntent(XmlResourceParser parser) {
+            final String url = getAttributeValue(parser, ATTR_URL);
+            if (TextUtils.isEmpty(url) || !Patterns.WEB_URL.matcher(url).matches()) {
+                if (LOGD) Log.d(TAG, "Ignoring shortcut, invalid url: " + url);
+                return null;
+            }
+            return new Intent(Intent.ACTION_VIEW, null).setData(Uri.parse(url));
         }
     }
 
-    private class AppWidgetParser implements TagParser {
+    /**
+     * AppWidget parser: Required attributes packageName, className, spanX and spanY.
+     * Options child nodes: <extra key=... value=... />
+     */
+    protected class AppWidgetParser implements TagParser {
 
         @Override
-        public long parseAndAdd(XmlResourceParser parser, Resources res)
+        public long parseAndAdd(XmlResourceParser parser)
                 throws XmlPullParserException, IOException {
             final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
             final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
@@ -429,16 +490,24 @@
         }
     }
 
-    private class FolderParser implements TagParser {
-        private final HashMap<String, TagParser> mFolderElements = getFolderElementsMap();
+    protected class FolderParser implements TagParser {
+        private final HashMap<String, TagParser> mFolderElements;
+
+        public FolderParser() {
+            this(getFolderElementsMap());
+        }
+
+        public FolderParser(HashMap<String, TagParser> elements) {
+            mFolderElements = elements;
+        }
 
         @Override
-        public long parseAndAdd(XmlResourceParser parser, Resources res)
+        public long parseAndAdd(XmlResourceParser parser)
                 throws XmlPullParserException, IOException {
             final String title;
             final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
             if (titleResId != 0) {
-                title = res.getString(titleResId);
+                title = mSourceRes.getString(titleResId);
             } else {
                 title = mContext.getResources().getString(R.string.folder_name);
             }
@@ -469,7 +538,7 @@
 
                 TagParser tagParser = mFolderElements.get(parser.getName());
                 if (tagParser != null) {
-                    final long id = tagParser.parseAndAdd(parser, res);
+                    final long id = tagParser.parseAndAdd(parser);
                     if (id >= 0) {
                         folderItems.add(id);
                     }
@@ -508,7 +577,7 @@
         }
     }
 
-    private static final void beginDocument(XmlPullParser parser, String firstElementName)
+    protected static final void beginDocument(XmlPullParser parser, String firstElementName)
             throws XmlPullParserException, IOException {
         int type;
         while ((type = parser.next()) != XmlPullParser.START_TAG
@@ -528,7 +597,7 @@
      * Return attribute value, attempting launcher-specific namespace first
      * before falling back to anonymous attribute.
      */
-    private static String getAttributeValue(XmlResourceParser parser, String attribute) {
+    protected static String getAttributeValue(XmlResourceParser parser, String attribute) {
         String value = parser.getAttributeValue(
                 "http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute);
         if (value == null) {
@@ -541,7 +610,7 @@
      * Return attribute resource value, attempting launcher-specific namespace
      * first before falling back to anonymous attribute.
      */
-    private static int getAttributeResourceValue(XmlResourceParser parser, String attribute,
+    protected static int getAttributeResourceValue(XmlResourceParser parser, String attribute,
             int defaultValue) {
         int value = parser.getAttributeResourceValue(
                 "http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute,
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index a368796..07f3045 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -40,7 +40,7 @@
  */
 public class BubbleTextView extends TextView {
 
-    private static SparseArray<Theme> sPreloaderThemes = new SparseArray<>(2);
+    private static SparseArray<Theme> sPreloaderThemes = new SparseArray<Theme>(2);
 
     private static final float SHADOW_LARGE_RADIUS = 4.0f;
     private static final float SHADOW_SMALL_RADIUS = 1.75f;
@@ -122,7 +122,7 @@
         LauncherAppState app = LauncherAppState.getInstance();
 
         FastBitmapDrawable iconDrawable = Utilities.createIconDrawable(b);
-        iconDrawable.setGhostModeEnabled(info.isDisabled);
+        iconDrawable.setGhostModeEnabled(info.isDisabled != 0);
 
         setCompoundDrawables(null, iconDrawable, null, null);
         if (setDefaultPadding) {
diff --git a/src/com/android/launcher3/DefaultLayoutParser.java b/src/com/android/launcher3/DefaultLayoutParser.java
new file mode 100644
index 0000000..e3ea40e
--- /dev/null
+++ b/src/com/android/launcher3/DefaultLayoutParser.java
@@ -0,0 +1,290 @@
+package com.android.launcher3;
+
+import android.appwidget.AppWidgetHost;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.launcher3.LauncherSettings.Favorites;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Implements the layout parser with rules for internal layouts and partner layouts.
+ */
+public class DefaultLayoutParser extends AutoInstallsLayout {
+    private static final String TAG = "DefaultLayoutParser";
+
+    private static final String TAG_RESOLVE = "resolve";
+    private static final String TAG_FAVORITES = "favorites";
+    private static final String TAG_FAVORITE = "favorite";
+    private static final String TAG_APPWIDGET = "appwidget";
+    private static final String TAG_SHORTCUT = "shortcut";
+    private static final String TAG_FOLDER = "folder";
+    private static final String TAG_PARTNER_FOLDER = "partner-folder";
+    private static final String TAG_INCLUDE = "include";
+
+    private static final String ATTR_URI = "uri";
+    private static final String ATTR_WORKSPACE = "workspace";
+    private static final String ATTR_CONTAINER = "container";
+    private static final String ATTR_SCREEN = "screen";
+    private static final String ATTR_FOLDER_ITEMS = "folderItems";
+
+    public DefaultLayoutParser(Context context, AppWidgetHost appWidgetHost,
+            LayoutParserCallback callback, Resources sourceRes, int layoutId) {
+        super(context, appWidgetHost, callback, sourceRes, layoutId, TAG_FAVORITES);
+        Log.e(TAG, "Default layout parser initialized");
+    }
+
+    @Override
+    protected HashMap<String, TagParser> getFolderElementsMap() {
+        return getFolderElementsMap(mSourceRes);
+    }
+
+    private HashMap<String, TagParser> getFolderElementsMap(Resources res) {
+        HashMap<String, TagParser> parsers = new HashMap<String, TagParser>();
+        parsers.put(TAG_FAVORITE, new AppShortcutWithUriParser());
+        parsers.put(TAG_SHORTCUT, new UriShortcutParser(res));
+        return parsers;
+    }
+
+    @Override
+    protected HashMap<String, TagParser> getLayoutElementsMap() {
+        HashMap<String, TagParser> parsers = new HashMap<String, TagParser>();
+        parsers.put(TAG_FAVORITE, new AppShortcutWithUriParser());
+        parsers.put(TAG_APPWIDGET, new AppWidgetParser());
+        parsers.put(TAG_SHORTCUT, new UriShortcutParser(mSourceRes));
+        parsers.put(TAG_RESOLVE, new ResolveParser());
+        parsers.put(TAG_FOLDER, new MyFolderParser());
+        parsers.put(TAG_PARTNER_FOLDER, new PartnerFolderParser());
+        return parsers;
+    }
+
+    @Override
+    protected void parseContainerAndScreen(XmlResourceParser parser, long[] out) {
+        out[0] = LauncherSettings.Favorites.CONTAINER_DESKTOP;
+        String strContainer = getAttributeValue(parser, ATTR_CONTAINER);
+        if (strContainer != null) {
+            out[0] = Long.valueOf(strContainer);
+        }
+        out[1] = Long.parseLong(getAttributeValue(parser, ATTR_SCREEN));
+    }
+
+    @Override
+    protected int parseAndAddNode(
+            XmlResourceParser parser,
+            HashMap<String, TagParser> tagParserMap,
+            ArrayList<Long> screenIds)
+                    throws XmlPullParserException, IOException {
+        if (TAG_INCLUDE.equals(parser.getName())) {
+            final int resId = getAttributeResourceValue(parser, ATTR_WORKSPACE, 0);
+            if (resId != 0) {
+                // recursively load some more favorites, why not?
+                return parseLayout(resId, screenIds);
+            } else {
+                return 0;
+            }
+        } else {
+            return super.parseAndAddNode(parser, tagParserMap, screenIds);
+        }
+    }
+
+    /**
+     * AppShortcutParser which also supports adding URI based intents
+     */
+    private class AppShortcutWithUriParser extends AppShortcutParser {
+
+        @Override
+        protected long invalidPackageOrClass(XmlResourceParser parser) {
+            final String uri = getAttributeValue(parser, ATTR_URI);
+            if (TextUtils.isEmpty(uri)) {
+                Log.e(TAG, "Skipping invalid <favorite> with no component or uri");
+                return -1;
+            }
+
+            final Intent metaIntent;
+            try {
+                metaIntent = Intent.parseUri(uri, 0);
+            } catch (URISyntaxException e) {
+                Log.e(TAG, "Unable to add meta-favorite: " + uri, e);
+                return -1;
+            }
+
+            ResolveInfo resolved = mPackageManager.resolveActivity(metaIntent,
+                    PackageManager.MATCH_DEFAULT_ONLY);
+            final List<ResolveInfo> appList = mPackageManager.queryIntentActivities(
+                    metaIntent, PackageManager.MATCH_DEFAULT_ONLY);
+
+            // Verify that the result is an app and not just the resolver dialog asking which
+            // app to use.
+            if (wouldLaunchResolverActivity(resolved, appList)) {
+                // If only one of the results is a system app then choose that as the default.
+                final ResolveInfo systemApp = getSingleSystemActivity(appList);
+                if (systemApp == null) {
+                    // There is no logical choice for this meta-favorite, so rather than making
+                    // a bad choice just add nothing.
+                    Log.w(TAG, "No preference or single system activity found for "
+                            + metaIntent.toString());
+                    return -1;
+                }
+                resolved = systemApp;
+            }
+            final ActivityInfo info = resolved.activityInfo;
+            final Intent intent = mPackageManager.getLaunchIntentForPackage(info.packageName);
+            if (intent == null) {
+                return -1;
+            }
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
+                    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+
+            return addShortcut(info.loadLabel(mPackageManager).toString(), intent,
+                    Favorites.ITEM_TYPE_APPLICATION);
+        }
+
+        private ResolveInfo getSingleSystemActivity(List<ResolveInfo> appList) {
+            ResolveInfo systemResolve = null;
+            final int N = appList.size();
+            for (int i = 0; i < N; ++i) {
+                try {
+                    ApplicationInfo info = mPackageManager.getApplicationInfo(
+                            appList.get(i).activityInfo.packageName, 0);
+                    if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+                        if (systemResolve != null) {
+                            return null;
+                        } else {
+                            systemResolve = appList.get(i);
+                        }
+                    }
+                } catch (PackageManager.NameNotFoundException e) {
+                    Log.w(TAG, "Unable to get info about resolve results", e);
+                    return null;
+                }
+            }
+            return systemResolve;
+        }
+
+        private boolean wouldLaunchResolverActivity(ResolveInfo resolved,
+                List<ResolveInfo> appList) {
+            // If the list contains the above resolved activity, then it can't be
+            // ResolverActivity itself.
+            for (int i = 0; i < appList.size(); ++i) {
+                ResolveInfo tmp = appList.get(i);
+                if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
+                        && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+
+    /**
+     * Shortcut parser which allows any uri and not just web urls.
+     */
+    private class UriShortcutParser extends ShortcutParser {
+
+        public UriShortcutParser(Resources iconRes) {
+            super(iconRes);
+        }
+
+        @Override
+        protected Intent parseIntent(XmlResourceParser parser) {
+            String uri = null;
+            try {
+                uri = getAttributeValue(parser, ATTR_URI);
+                return Intent.parseUri(uri, 0);
+            } catch (URISyntaxException e) {
+                Log.w(TAG, "Shortcut has malformed uri: " + uri);
+                return null; // Oh well
+            }
+        }
+    }
+
+    /**
+     * Contains a list of <favorite> nodes, and accepts the first successfully parsed node.
+     */
+    private class ResolveParser implements TagParser {
+
+        private final AppShortcutWithUriParser mChildParser = new AppShortcutWithUriParser();
+
+        @Override
+        public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
+                IOException {
+            final int groupDepth = parser.getDepth();
+            int type;
+            long addedId = -1;
+            while ((type = parser.next()) != XmlPullParser.END_TAG ||
+                    parser.getDepth() > groupDepth) {
+                if (type != XmlPullParser.START_TAG || addedId > -1) {
+                    continue;
+                }
+                final String fallback_item_name = parser.getName();
+                if (TAG_FAVORITE.equals(fallback_item_name)) {
+                    addedId = mChildParser.parseAndAdd(parser);
+                } else {
+                    Log.e(TAG, "Fallback groups can contain only favorites, found "
+                            + fallback_item_name);
+                }
+            }
+            return addedId;
+        }
+    }
+
+    /**
+     * A parser which adds a folder whose contents come from partner apk.
+     */
+    private class PartnerFolderParser implements TagParser {
+
+        @Override
+        public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
+                IOException {
+            // Folder contents come from an external XML resource
+            final Partner partner = Partner.get(mPackageManager);
+            if (partner != null) {
+                final Resources partnerRes = partner.getResources();
+                final int resId = partnerRes.getIdentifier(Partner.RES_FOLDER,
+                        "xml", partner.getPackageName());
+                if (resId != 0) {
+                    final XmlResourceParser partnerParser = partnerRes.getXml(resId);
+                    beginDocument(partnerParser, TAG_FOLDER);
+
+                    FolderParser folderParser = new FolderParser(getFolderElementsMap(partnerRes));
+                    return folderParser.parseAndAdd(partnerParser);
+                }
+            }
+            return -1;
+        }
+    }
+
+    /**
+     * An extension of FolderParser which allows adding items from a different xml.
+     */
+    private class MyFolderParser extends FolderParser {
+
+        @Override
+        public long parseAndAdd(XmlResourceParser parser) throws XmlPullParserException,
+                IOException {
+            final int resId = getAttributeResourceValue(parser, ATTR_FOLDER_ITEMS, 0);
+            if (resId != 0) {
+                parser = mSourceRes.getXml(resId);
+                beginDocument(parser, TAG_FOLDER);
+            }
+            return super.parseAndAdd(parser);
+        }
+    }
+}
diff --git a/src/com/android/launcher3/DeleteDropTarget.java b/src/com/android/launcher3/DeleteDropTarget.java
index 05e8906..ea058ea 100644
--- a/src/com/android/launcher3/DeleteDropTarget.java
+++ b/src/com/android/launcher3/DeleteDropTarget.java
@@ -21,8 +21,6 @@
 import android.animation.ValueAnimator.AnimatorUpdateListener;
 import android.content.ComponentName;
 import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ResolveInfo;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
 import android.content.res.Resources;
@@ -41,12 +39,8 @@
 import android.view.animation.DecelerateInterpolator;
 import android.view.animation.LinearInterpolator;
 
-import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserHandleCompat;
 
-import java.util.List;
-import java.util.Set;
-
 public class DeleteDropTarget extends ButtonDropTarget {
     private static int DELETE_ANIMATION_DURATION = 285;
     private static int FLING_DELETE_ANIMATION_DURATION = 350;
@@ -266,7 +260,7 @@
             public void run() {
                 completeDrop(d);
                 mSearchDropTargetBar.onDragEnd();
-                mLauncher.exitSpringLoadedDragMode();
+                mLauncher.exitSpringLoadedDragModeDelayed(true, 0, null);
             }
         };
         dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index daf5556..d6aadce 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -33,6 +33,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.ViewGroup.LayoutParams;
+import android.view.ViewGroup.MarginLayoutParams;
 import android.view.WindowManager;
 import android.widget.FrameLayout;
 import android.widget.LinearLayout;
@@ -75,7 +76,6 @@
     private float hotseatIconSize;
 
     int defaultLayoutId;
-    int defaultNoAllAppsLayoutId;
 
     boolean isLandscape;
     boolean isTablet;
@@ -122,9 +122,7 @@
     int allAppsNumRows;
     int allAppsNumCols;
     int searchBarSpaceWidthPx;
-    int searchBarSpaceMaxWidthPx;
     int searchBarSpaceHeightPx;
-    int searchBarHeightPx;
     int pageIndicatorHeightPx;
     int allAppsButtonVisualSize;
 
@@ -136,7 +134,7 @@
     private ArrayList<DeviceProfileCallbacks> mCallbacks = new ArrayList<DeviceProfileCallbacks>();
 
     DeviceProfile(String n, float w, float h, float r, float c,
-                  float is, float its, float hs, float his, int dlId, int dnalId) {
+                  float is, float its, float hs, float his, int dlId) {
         // Ensure that we have an odd number of hotseat items (since we need to place all apps)
         if (!LauncherAppState.isDisableAllApps() && hs % 2 == 0) {
             throw new RuntimeException("All Device Profiles must have an odd number of hotseat spaces");
@@ -152,7 +150,6 @@
         numHotseatIcons = hs;
         hotseatIconSize = his;
         defaultLayoutId = dlId;
-        defaultNoAllAppsLayoutId = dnalId;
     }
 
     DeviceProfile() {
@@ -215,9 +212,6 @@
         // Snap to the closest default layout id
         defaultLayoutId = closestProfile.defaultLayoutId;
 
-        // Snap to the closest default no all-apps layout id
-        defaultNoAllAppsLayoutId = closestProfile.defaultNoAllAppsLayoutId;
-
         // Interpolate the icon size
         points.clear();
         for (DeviceProfile p : profiles) {
@@ -376,10 +370,10 @@
         hotseatIconSizePx = (int) (DynamicGrid.pxFromDp(hotseatIconSize, dm) * scale);
 
         // Search Bar
-        searchBarSpaceMaxWidthPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width);
-        searchBarHeightPx = resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
-        searchBarSpaceWidthPx = Math.min(searchBarSpaceMaxWidthPx, widthPx);
-        searchBarSpaceHeightPx = searchBarHeightPx + getSearchBarTopOffset();
+        searchBarSpaceWidthPx = Math.min(widthPx,
+                resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width));
+        searchBarSpaceHeightPx = getSearchBarTopOffset()
+                + resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
 
         // Calculate the actual text height
         Paint textPaint = new Paint();
@@ -402,10 +396,6 @@
         folderIconSizePx = iconSizePx + 2 * -folderBackgroundOffset;
 
         // All Apps
-        Rect padding = getWorkspacePadding(isLandscape ?
-                CellLayout.LANDSCAPE : CellLayout.PORTRAIT);
-        int pageIndicatorOffset =
-                resources.getDimensionPixelSize(R.dimen.apps_customize_page_indicator_offset);
         allAppsCellWidthPx = allAppsIconSizePx;
         allAppsCellHeightPx = allAppsIconSizePx + drawablePadding + iconTextSizePx;
         int maxLongEdgeCellCount =
@@ -708,11 +698,6 @@
         return visibleChildren;
     }
 
-    int calculateOverviewModeWidth(int visibleChildCount) {
-        return visibleChildCount * overviewModeBarItemWidthPx +
-                (visibleChildCount-1) * overviewModeBarSpacerWidthPx;
-    }
-
     public void layout(Launcher launcher) {
         FrameLayout.LayoutParams lp;
         Resources res = launcher.getResources();
@@ -726,9 +711,6 @@
             lp.gravity = Gravity.TOP | Gravity.LEFT;
             lp.width = searchBarSpaceHeightPx;
             lp.height = LayoutParams.WRAP_CONTENT;
-            searchBar.setPadding(
-                    0, 2 * edgeMarginPx, 0,
-                    2 * edgeMarginPx);
 
             LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar);
             targets.setOrientation(LinearLayout.VERTICAL);
@@ -737,27 +719,9 @@
             lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
             lp.width = searchBarSpaceWidthPx;
             lp.height = searchBarSpaceHeightPx;
-            searchBar.setPadding(
-                    2 * edgeMarginPx,
-                    getSearchBarTopOffset(),
-                    2 * edgeMarginPx, 0);
         }
         searchBar.setLayoutParams(lp);
 
-        // Layout the voice proxy
-        View voiceButtonProxy = launcher.findViewById(R.id.voice_button_proxy);
-        if (voiceButtonProxy != null) {
-            if (hasVerticalBarLayout) {
-                // TODO: MOVE THIS INTO SEARCH BAR MEASURE
-            } else {
-                lp = (FrameLayout.LayoutParams) voiceButtonProxy.getLayoutParams();
-                lp.gravity = Gravity.TOP | Gravity.END;
-                lp.width = (widthPx - searchBarSpaceWidthPx) / 2 +
-                        2 * iconSizePx;
-                lp.height = searchBarSpaceHeightPx;
-            }
-        }
-
         // Layout the workspace
         PagedView workspace = (PagedView) launcher.findViewById(R.id.workspace);
         lp = (FrameLayout.LayoutParams) workspace.getLayoutParams();
@@ -877,10 +841,38 @@
             Rect r = getOverviewModeButtonBarRect();
             lp = (FrameLayout.LayoutParams) overviewMode.getLayoutParams();
             lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
-            lp.width = Math.min(availableWidthPx,
-                    calculateOverviewModeWidth(getVisibleChildCount(overviewMode)));
+
+            int visibleChildCount = getVisibleChildCount(overviewMode);
+            int totalItemWidth = visibleChildCount * overviewModeBarItemWidthPx;
+            int maxWidth = totalItemWidth + (visibleChildCount-1) * overviewModeBarSpacerWidthPx;
+
+            lp.width = Math.min(availableWidthPx, maxWidth);
             lp.height = r.height();
             overviewMode.setLayoutParams(lp);
+
+            if (lp.width > totalItemWidth && visibleChildCount > 1) {
+                // We have enough space. Lets add some margin too.
+                int margin = (lp.width - totalItemWidth) / (visibleChildCount-1);
+                View lastChild = null;
+
+                // Set margin of all visible children except the last visible child
+                for (int i = 0; i < visibleChildCount; i++) {
+                    if (lastChild != null) {
+                        MarginLayoutParams clp = (MarginLayoutParams) lastChild.getLayoutParams();
+                        if (isLayoutRtl) {
+                            clp.leftMargin = margin;
+                        } else {
+                            clp.rightMargin = margin;
+                        }
+                        lastChild.setLayoutParams(clp);
+                        lastChild = null;
+                    }
+                    View thisChild = overviewMode.getChildAt(i);
+                    if (thisChild.getVisibility() != View.GONE) {
+                        lastChild = thisChild;
+                    }
+                }
+            }
         }
     }
 }
diff --git a/src/com/android/launcher3/DragController.java b/src/com/android/launcher3/DragController.java
index 6d0a2be..480dce9 100644
--- a/src/com/android/launcher3/DragController.java
+++ b/src/com/android/launcher3/DragController.java
@@ -26,10 +26,16 @@
 import android.os.Handler;
 import android.os.IBinder;
 import android.util.Log;
-import android.view.*;
+import android.view.HapticFeedbackConstants;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
 import android.view.inputmethod.InputMethodManager;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 
 /**
  * Class for initiating a drag within a view or across multiple views.
@@ -318,18 +324,17 @@
         }
         endDrag();
     }
-    public void onAppsRemoved(final ArrayList<String> packageNames, ArrayList<AppInfo> appInfos) {
+    public void onAppsRemoved(final ArrayList<String> packageNames, HashSet<ComponentName> cns) {
         // Cancel the current drag if we are removing an app that we are dragging
         if (mDragObject != null) {
             Object rawDragInfo = mDragObject.dragInfo;
             if (rawDragInfo instanceof ShortcutInfo) {
                 ShortcutInfo dragInfo = (ShortcutInfo) rawDragInfo;
-                for (AppInfo info : appInfos) {
+                for (ComponentName componentName : cns) {
                     // Added null checks to prevent NPE we've seen in the wild
-                    if (dragInfo != null &&
-                            dragInfo.intent != null && info != null) {
+                    if (dragInfo != null && dragInfo.intent != null) {
                         ComponentName cn = dragInfo.intent.getComponent();
-                        boolean isSameComponent = cn != null && (cn.equals(info.componentName) ||
+                        boolean isSameComponent = cn != null && (cn.equals(componentName) ||
                                 packageNames.contains(cn.getPackageName()));
                         if (isSameComponent) {
                             cancelDrag();
diff --git a/src/com/android/launcher3/DragLayer.java b/src/com/android/launcher3/DragLayer.java
index a8a61ea..a352b79 100644
--- a/src/com/android/launcher3/DragLayer.java
+++ b/src/com/android/launcher3/DragLayer.java
@@ -38,12 +38,14 @@
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
+import com.android.launcher3.InsettableFrameLayout.LayoutParams;
+
 import java.util.ArrayList;
 
 /**
  * A ViewGroup that coordinates dragging across its descendants
  */
-public class DragLayer extends FrameLayout implements ViewGroup.OnHierarchyChangeListener {
+public class DragLayer extends InsettableFrameLayout {
     private DragController mDragController;
     private int[] mTmpXY = new int[2];
 
@@ -71,8 +73,6 @@
 
     private TouchCompleteListener mTouchCompleteListener;
 
-    private final Rect mInsets = new Rect();
-
     private View mOverlayView;
     private int mTopViewIndex;
     private int mChildCountOnLastUpdate = -1;
@@ -89,6 +89,8 @@
     private Drawable mLeftHoverDrawableActive;
     private Drawable mRightHoverDrawableActive;
 
+    private boolean mBlockTouches = false;
+
     /**
      * Used to create a new DragLayer from XML.
      *
@@ -101,7 +103,6 @@
         // Disable multitouch across the workspace/all apps/customize tray
         setMotionEventSplittingEnabled(false);
         setChildrenDrawingOrderEnabled(true);
-        setOnHierarchyChangeListener(this);
 
         final Resources res = getResources();
         mLeftHoverDrawable = res.getDrawable(R.drawable.page_hover_left);
@@ -121,27 +122,6 @@
         return mDragController.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
     }
 
-    @Override
-    protected boolean fitSystemWindows(Rect insets) {
-        final int n = getChildCount();
-        for (int i = 0; i < n; i++) {
-            final View child = getChildAt(i);
-            setInsets(child, insets, mInsets);
-        }
-        mInsets.set(insets);
-        return true; // I'll take it from here
-    }
-
-    Rect getInsets() {
-        return mInsets;
-    }
-
-    @Override
-    public void addView(View child, int index, android.view.ViewGroup.LayoutParams params) {
-        super.addView(child, index, params);
-        setInsets(child, mInsets, new Rect());
-    }
-
     public void showOverlayView(View overlayView) {
         LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
         mOverlayView = overlayView;
@@ -156,19 +136,6 @@
         removeView(mOverlayView);
     }
 
-    private void setInsets(View child, Rect newInsets, Rect oldInsets) {
-        final FrameLayout.LayoutParams flp = (FrameLayout.LayoutParams) child.getLayoutParams();
-        if (child instanceof Insettable) {
-            ((Insettable) child).setInsets(newInsets);
-        } else {
-            flp.topMargin += (newInsets.top - oldInsets.top);
-            flp.leftMargin += (newInsets.left - oldInsets.left);
-            flp.rightMargin += (newInsets.right - oldInsets.right);
-            flp.bottomMargin += (newInsets.bottom - oldInsets.bottom);
-        }
-        child.setLayoutParams(flp);
-    }
-
     private boolean isEventOverFolderTextRegion(Folder folder, MotionEvent ev) {
         getDescendantRectRelativeToSelf(folder.getEditTextRegion(), mHitRect);
         if (mHitRect.contains((int) ev.getX(), (int) ev.getY())) {
@@ -185,11 +152,19 @@
         return false;
     }
 
+    public void setBlockTouch(boolean block) {
+        mBlockTouches = block;
+    }
+
     private boolean handleTouchDown(MotionEvent ev, boolean intercept) {
         Rect hitRect = new Rect();
         int x = (int) ev.getX();
         int y = (int) ev.getY();
 
+        if (mBlockTouches) {
+            return true;
+        }
+
         for (AppWidgetResizeFrame child: mResizeFrames) {
             child.getHitRect(hitRect);
             if (hitRect.contains(x, y)) {
@@ -332,6 +307,10 @@
         int x = (int) ev.getX();
         int y = (int) ev.getY();
 
+        if (mBlockTouches) {
+            return true;
+        }
+
         if (action == MotionEvent.ACTION_DOWN) {
             if (handleTouchDown(ev, false)) {
                 return true;
@@ -433,17 +412,43 @@
         return mDragController.dispatchUnhandledMove(focused, direction);
     }
 
-    public static class LayoutParams extends FrameLayout.LayoutParams {
+    @Override
+    public LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new LayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    protected LayoutParams generateDefaultLayoutParams() {
+        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+    }
+
+    // Override to allow type-checking of LayoutParams.
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof LayoutParams;
+    }
+
+    @Override
+    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        return new LayoutParams(p);
+    }
+
+    public static class LayoutParams extends InsettableFrameLayout.LayoutParams {
         public int x, y;
         public boolean customPosition = false;
 
-        /**
-         * {@inheritDoc}
-         */
+        public LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+        }
+
         public LayoutParams(int width, int height) {
             super(width, height);
         }
 
+        public LayoutParams(ViewGroup.LayoutParams lp) {
+            super(lp);
+        }
+
         public void setWidth(int width) {
             this.width = width;
         }
@@ -801,6 +806,7 @@
 
     @Override
     public void onChildViewAdded(View parent, View child) {
+        super.onChildViewAdded(parent, child);
         if (mOverlayView != null) {
             // ensure that the overlay view stays on top. we can't use drawing order for this
             // because in API level 16 touch dispatch doesn't respect drawing order.
diff --git a/src/com/android/launcher3/DrawableStateProxyView.java b/src/com/android/launcher3/DrawableStateProxyView.java
deleted file mode 100644
index c83659a..0000000
--- a/src/com/android/launcher3/DrawableStateProxyView.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.LinearLayout;
-
-public class DrawableStateProxyView extends LinearLayout {
-
-    private View mView;
-    private int mViewId;
-
-    public DrawableStateProxyView(Context context) {
-        this(context, null);
-    }
-
-    public DrawableStateProxyView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-
-    public DrawableStateProxyView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.DrawableStateProxyView,
-                defStyle, 0);
-        mViewId = a.getResourceId(R.styleable.DrawableStateProxyView_sourceViewId, -1);
-        a.recycle();
-
-        setFocusable(false);
-    }
-
-    @Override
-    protected void drawableStateChanged() {
-        super.drawableStateChanged();
-
-        if (mView == null) {
-            View parent = (View) getParent();
-            mView = parent.findViewById(mViewId);
-        }
-        if (mView != null) {
-            mView.setPressed(isPressed());
-            mView.setHovered(isHovered());
-        }
-    }
-
-    @Override
-    public boolean onHoverEvent(MotionEvent event) {
-        return false;
-    }
-}
diff --git a/src/com/android/launcher3/DynamicGrid.java b/src/com/android/launcher3/DynamicGrid.java
index 94a07d7..aa08148 100644
--- a/src/com/android/launcher3/DynamicGrid.java
+++ b/src/com/android/launcher3/DynamicGrid.java
@@ -60,41 +60,30 @@
         DEFAULT_ICON_SIZE_PX = pxFromDp(DEFAULT_ICON_SIZE_DP, dm);
         // Our phone profiles include the bar sizes in each orientation
         deviceProfiles.add(new DeviceProfile("Super Short Stubby",
-                255, 300,  2, 3,  48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4,
-                R.xml.default_workspace_4x4_no_all_apps));
+                255, 300,  2, 3,  48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4));
         deviceProfiles.add(new DeviceProfile("Shorter Stubby",
-                255, 400,  3, 3,  48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4,
-                R.xml.default_workspace_4x4_no_all_apps));
+                255, 400,  3, 3,  48, 13, (hasAA ? 3 : 5), 48, R.xml.default_workspace_4x4));
         deviceProfiles.add(new DeviceProfile("Short Stubby",
-                275, 420,  3, 4,  48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4,
-                R.xml.default_workspace_4x4_no_all_apps));
+                275, 420,  3, 4,  48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4));
         deviceProfiles.add(new DeviceProfile("Stubby",
-                255, 450,  3, 4,  48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4,
-                R.xml.default_workspace_4x4_no_all_apps));
+                255, 450,  3, 4,  48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4));
         deviceProfiles.add(new DeviceProfile("Nexus S",
-                296, 491.33f,  4, 4,  48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4,
-                R.xml.default_workspace_4x4_no_all_apps));
+                296, 491.33f,  4, 4,  48, 13, (hasAA ? 5 : 5), 48, R.xml.default_workspace_4x4));
         deviceProfiles.add(new DeviceProfile("Nexus 4",
-                335, 567,  4, 4,  DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4,
-                R.xml.default_workspace_4x4_no_all_apps));
+                335, 567,  4, 4,  DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4));
         deviceProfiles.add(new DeviceProfile("Nexus 5",
-                359, 567,  4, 4,  DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4,
-                R.xml.default_workspace_4x4_no_all_apps));
+                359, 567,  4, 4,  DEFAULT_ICON_SIZE_DP, 13, (hasAA ? 5 : 5), 56, R.xml.default_workspace_4x4));
         deviceProfiles.add(new DeviceProfile("Large Phone",
-                406, 694,  5, 5,  64, 14.4f,  5, 56, R.xml.default_workspace_5x5,
-                R.xml.default_workspace_5x5_no_all_apps));
+                406, 694,  5, 5,  64, 14.4f,  5, 56, R.xml.default_workspace_5x5));
         // The tablet profile is odd in that the landscape orientation
         // also includes the nav bar on the side
         deviceProfiles.add(new DeviceProfile("Nexus 7",
-                575, 904,  5, 6,  72, 14.4f,  7, 60, R.xml.default_workspace_5x6,
-                R.xml.default_workspace_5x6_no_all_apps));
+                575, 904,  5, 6,  72, 14.4f,  7, 60, R.xml.default_workspace_5x6));
         // Larger tablet profiles always have system bars on the top & bottom
         deviceProfiles.add(new DeviceProfile("Nexus 10",
-                727, 1207,  5, 6,  76, 14.4f,  7, 64, R.xml.default_workspace_5x6,
-                R.xml.default_workspace_5x6_no_all_apps));
+                727, 1207,  5, 6,  76, 14.4f,  7, 64, R.xml.default_workspace_5x6));
         deviceProfiles.add(new DeviceProfile("20-inch Tablet",
-                1527, 2527,  7, 7,  100, 20,  7, 72, R.xml.default_workspace_4x4,
-                R.xml.default_workspace_4x4_no_all_apps));
+                1527, 2527,  7, 7,  100, 20,  7, 72, R.xml.default_workspace_4x4));
         mMinWidth = dpiFromPx(minWidthPx, dm);
         mMinHeight = dpiFromPx(minHeightPx, dm);
         mProfile = new DeviceProfile(context, deviceProfiles,
diff --git a/src/com/android/launcher3/FirstFrameAnimatorHelper.java b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
index f4c49d7..095c563 100644
--- a/src/com/android/launcher3/FirstFrameAnimatorHelper.java
+++ b/src/com/android/launcher3/FirstFrameAnimatorHelper.java
@@ -92,12 +92,14 @@
         }
 
         final long currentPlayTime = animation.getCurrentPlayTime();
+        boolean isFinalFrame = Float.compare(1f, animation.getAnimatedFraction()) == 0;
+
         if (!mHandlingOnAnimationUpdate &&
             sVisible &&
-            // If the current play time exceeds the duration, the animation
-            // will get finished, even if we call setCurrentPlayTime -- therefore
+            // If the current play time exceeds the duration, or the animated fraction is 1,
+            // the animation will get finished, even if we call setCurrentPlayTime -- therefore
             // don't adjust the animation in that case
-            currentPlayTime < animation.getDuration()) {
+            currentPlayTime < animation.getDuration() && !isFinalFrame) {
             mHandlingOnAnimationUpdate = true;
             long frameNum = sGlobalFrameCounter - mStartFrame;
             // If we haven't drawn our first frame, reset the time to t = 0
diff --git a/src/com/android/launcher3/FocusHelper.java b/src/com/android/launcher3/FocusHelper.java
index d529b39..e607047 100644
--- a/src/com/android/launcher3/FocusHelper.java
+++ b/src/com/android/launcher3/FocusHelper.java
@@ -17,12 +17,10 @@
 package com.android.launcher3;
 
 import android.content.res.Configuration;
-import android.util.Log;
 import android.view.KeyEvent;
 import android.view.SoundEffectConstants;
 import android.view.View;
 import android.view.ViewGroup;
-import android.view.ViewParent;
 import android.widget.ScrollView;
 
 import java.util.ArrayList;
@@ -58,16 +56,6 @@
 }
 
 public class FocusHelper {
-    /**
-     * Private helper to get the parent TabHost in the view hiearchy.
-     */
-    private static AppsCustomizeTabHost findTabHostParent(View v) {
-        ViewParent p = v.getParent();
-        while (p != null && !(p instanceof AppsCustomizeTabHost)) {
-            p = p.getParent();
-        }
-        return (AppsCustomizeTabHost) p;
-    }
 
     /**
      * Returns the Viewgroup containing page contents for the page at the index specified.
@@ -82,148 +70,6 @@
     }
 
     /**
-     * Handles key events in a PageViewExtendedLayout containing PagedViewWidgets.
-     */
-    static boolean handlePagedViewGridLayoutWidgetKeyEvent(PagedViewWidget w, int keyCode,
-            KeyEvent e) {
-
-        final PagedViewGridLayout parent = (PagedViewGridLayout) w.getParent();
-        final PagedView container = (PagedView) parent.getParent();
-        final int widgetIndex = parent.indexOfChild(w);
-        final int widgetCount = parent.getChildCount();
-        final int pageIndex = ((PagedView) container).indexToPage(container.indexOfChild(parent));
-        final int pageCount = container.getChildCount();
-        final int cellCountX = parent.getCellCountX();
-        final int cellCountY = parent.getCellCountY();
-        final int x = widgetIndex % cellCountX;
-        final int y = widgetIndex / cellCountX;
-
-        final int action = e.getAction();
-        final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
-        ViewGroup newParent = null;
-        // Now that we load items in the bg asynchronously, we can't just focus
-        // child siblings willy-nilly
-        View child = null;
-        boolean wasHandled = false;
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-                if (handleKeyEvent) {
-                    // Select the previous widget or the last widget on the previous page
-                    if (widgetIndex > 0) {
-                        parent.getChildAt(widgetIndex - 1).requestFocus();
-                    } else {
-                        if (pageIndex > 0) {
-                            newParent = getAppsCustomizePage(container, pageIndex - 1);
-                            if (newParent != null) {
-                                child = newParent.getChildAt(newParent.getChildCount() - 1);
-                                if (child != null) child.requestFocus();
-                            }
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                if (handleKeyEvent) {
-                    // Select the next widget or the first widget on the next page
-                    if (widgetIndex < (widgetCount - 1)) {
-                        parent.getChildAt(widgetIndex + 1).requestFocus();
-                    } else {
-                        if (pageIndex < (pageCount - 1)) {
-                            newParent = getAppsCustomizePage(container, pageIndex + 1);
-                            if (newParent != null) {
-                                child = newParent.getChildAt(0);
-                                if (child != null) child.requestFocus();
-                            }
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_UP:
-                if (handleKeyEvent) {
-                    // Select the closest icon in the previous row, otherwise select the tab bar
-                    if (y > 0) {
-                        int newWidgetIndex = ((y - 1) * cellCountX) + x;
-                        child = parent.getChildAt(newWidgetIndex);
-                        if (child != null) child.requestFocus();
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-                if (handleKeyEvent) {
-                    // Select the closest icon in the previous row, otherwise do nothing
-                    if (y < (cellCountY - 1)) {
-                        int newWidgetIndex = Math.min(widgetCount - 1, ((y + 1) * cellCountX) + x);
-                        child = parent.getChildAt(newWidgetIndex);
-                        if (child != null) child.requestFocus();
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_ENTER:
-            case KeyEvent.KEYCODE_DPAD_CENTER:
-                if (handleKeyEvent) {
-                    // Simulate a click on the widget
-                    View.OnClickListener clickListener = (View.OnClickListener) container;
-                    clickListener.onClick(w);
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_PAGE_UP:
-                if (handleKeyEvent) {
-                    // Select the first item on the previous page, or the first item on this page
-                    // if there is no previous page
-                    if (pageIndex > 0) {
-                        newParent = getAppsCustomizePage(container, pageIndex - 1);
-                        if (newParent != null) {
-                            child = newParent.getChildAt(0);
-                        }
-                    } else {
-                        child = parent.getChildAt(0);
-                    }
-                    if (child != null) child.requestFocus();
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_PAGE_DOWN:
-                if (handleKeyEvent) {
-                    // Select the first item on the next page, or the last item on this page
-                    // if there is no next page
-                    if (pageIndex < (pageCount - 1)) {
-                        newParent = getAppsCustomizePage(container, pageIndex + 1);
-                        if (newParent != null) {
-                            child = newParent.getChildAt(0);
-                        }
-                    } else {
-                        child = parent.getChildAt(widgetCount - 1);
-                    }
-                    if (child != null) child.requestFocus();
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_MOVE_HOME:
-                if (handleKeyEvent) {
-                    // Select the first item on this page
-                    child = parent.getChildAt(0);
-                    if (child != null) child.requestFocus();
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_MOVE_END:
-                if (handleKeyEvent) {
-                    // Select the last item on this page
-                    parent.getChildAt(widgetCount - 1).requestFocus();
-                }
-                wasHandled = true;
-                break;
-            default: break;
-        }
-        return wasHandled;
-    }
-
-    /**
      * Handles key events in a PageViewCellLayout containing PagedViewIcons.
      */
     static boolean handleAppsCustomizeKeyEvent(View v, int keyCode, KeyEvent e) {
@@ -394,60 +240,6 @@
     }
 
     /**
-     * Handles key events in the tab widget.
-     */
-    static boolean handleTabKeyEvent(AccessibleTabView v, int keyCode, KeyEvent e) {
-        if (!LauncherAppState.getInstance().isScreenLarge()) return false;
-
-        final FocusOnlyTabWidget parent = (FocusOnlyTabWidget) v.getParent();
-        final AppsCustomizeTabHost tabHost = findTabHostParent(parent);
-        final ViewGroup contents = tabHost.getContent();
-        final int tabCount = parent.getTabCount();
-        final int tabIndex = parent.getChildTabIndex(v);
-
-        final int action = e.getAction();
-        final boolean handleKeyEvent = (action != KeyEvent.ACTION_UP);
-        boolean wasHandled = false;
-        switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-                if (handleKeyEvent) {
-                    // Select the previous tab
-                    if (tabIndex > 0) {
-                        parent.getChildTabViewAt(tabIndex - 1).requestFocus();
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-                if (handleKeyEvent) {
-                    // Select the next tab, or if the last tab has a focus right id, select that
-                    if (tabIndex < (tabCount - 1)) {
-                        parent.getChildTabViewAt(tabIndex + 1).requestFocus();
-                    } else {
-                        if (v.getNextFocusRightId() != View.NO_ID) {
-                            tabHost.findViewById(v.getNextFocusRightId()).requestFocus();
-                        }
-                    }
-                }
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_UP:
-                // Do nothing
-                wasHandled = true;
-                break;
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-                if (handleKeyEvent) {
-                    // Select the content view
-                    contents.requestFocus();
-                }
-                wasHandled = true;
-                break;
-            default: break;
-        }
-        return wasHandled;
-    }
-
-    /**
      * Handles key events in the workspace hotseat (bottom of the screen).
      */
     static boolean handleHotseatButtonKeyEvent(View v, int keyCode, KeyEvent e, int orientation) {
diff --git a/src/com/android/launcher3/FocusIndicatorView.java b/src/com/android/launcher3/FocusIndicatorView.java
index 12b7a40..7d4664a 100644
--- a/src/com/android/launcher3/FocusIndicatorView.java
+++ b/src/com/android/launcher3/FocusIndicatorView.java
@@ -16,6 +16,8 @@
 
 package com.android.launcher3;
 
+import android.animation.ObjectAnimator;
+import android.animation.PropertyValuesHolder;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.util.AttributeSet;
@@ -28,6 +30,7 @@
     // It can be any number >0. The view is resized using scaleX and scaleY.
     static final int DEFAULT_LAYOUT_SIZE = 100;
     private static final float MIN_VISIBLE_ALPHA = 0.2f;
+    private static final long ANIM_DURATION = 150;
 
     private static final int[] sTempPos = new int[2];
     private static final int[] sTempShift = new int[2];
@@ -35,6 +38,9 @@
     private final int[] mIndicatorPos = new int[2];
     private final int[] mTargetViewPos = new int[2];
 
+    private ObjectAnimator mCurrentAnimation;
+    private ViewAnimState mTargetState;
+
     private View mLastFocusedView;
     private boolean mInitiated;
 
@@ -82,34 +88,58 @@
             int indicatorWidth = getWidth();
             int indicatorHeight = getHeight();
 
-            float scaleX = v.getScaleX() * v.getWidth() / indicatorWidth;
-            float scaleY = v.getScaleY() * v.getHeight() / indicatorHeight;
+            endCurrentAnimation();
+            ViewAnimState nextState = new ViewAnimState();
+            nextState.scaleX = v.getScaleX() * v.getWidth() / indicatorWidth;
+            nextState.scaleY = v.getScaleY() * v.getHeight() / indicatorHeight;
 
             getLocationRelativeToParentPagedView(v, mTargetViewPos);
-            float x = mTargetViewPos[0] - mIndicatorPos[0] - (1 - scaleX) * indicatorWidth / 2;
-            float y = mTargetViewPos[1] - mIndicatorPos[1] - (1 - scaleY) * indicatorHeight / 2;
+            nextState.x = mTargetViewPos[0] - mIndicatorPos[0] - (1 - nextState.scaleX) * indicatorWidth / 2;
+            nextState.y = mTargetViewPos[1] - mIndicatorPos[1] - (1 - nextState.scaleY) * indicatorHeight / 2;
 
             if (getAlpha() > MIN_VISIBLE_ALPHA) {
-                animate()
-                .translationX(x)
-                .translationY(y)
-                .scaleX(scaleX)
-                .scaleY(scaleY)
-                .alpha(1);
+                mTargetState = nextState;
+                mCurrentAnimation = LauncherAnimUtils.ofPropertyValuesHolder(this,
+                        PropertyValuesHolder.ofFloat(View.ALPHA, 1),
+                        PropertyValuesHolder.ofFloat(View.TRANSLATION_X, mTargetState.x),
+                        PropertyValuesHolder.ofFloat(View.TRANSLATION_Y, mTargetState.y),
+                        PropertyValuesHolder.ofFloat(View.SCALE_X, mTargetState.scaleX),
+                        PropertyValuesHolder.ofFloat(View.SCALE_Y, mTargetState.scaleY));
             } else {
-                setTranslationX(x);
-                setTranslationY(y);
-                setScaleX(scaleX);
-                setScaleY(scaleY);
-                animate().alpha(1);
+                applyState(nextState);
+                mCurrentAnimation = LauncherAnimUtils.ofPropertyValuesHolder(this,
+                        PropertyValuesHolder.ofFloat(View.ALPHA, 1));
             }
             mLastFocusedView = v;
         } else {
             if (mLastFocusedView == v) {
                 mLastFocusedView = null;
-                animate().alpha(0);
+                endCurrentAnimation();
+                mCurrentAnimation = LauncherAnimUtils.ofPropertyValuesHolder(this,
+                        PropertyValuesHolder.ofFloat(View.ALPHA, 0));
             }
         }
+        if (mCurrentAnimation != null) {
+            mCurrentAnimation.setDuration(ANIM_DURATION).start();
+        }
+    }
+
+    private void endCurrentAnimation() {
+        if (mCurrentAnimation != null) {
+            mCurrentAnimation.cancel();
+            mCurrentAnimation = null;
+        }
+        if (mTargetState != null) {
+            applyState(mTargetState);
+            mTargetState = null;
+        }
+    }
+
+    private void applyState(ViewAnimState state) {
+        setTranslationX(state.x);
+        setTranslationY(state.y);
+        setScaleX(state.scaleX);
+        setScaleY(state.scaleY);
     }
 
     @Override
@@ -143,4 +173,8 @@
             shift[0] = shift[1] = 0;
         }
     }
+
+    private static final class ViewAnimState {
+        float x, y, scaleX, scaleY;
+    }
 }
diff --git a/src/com/android/launcher3/HolographicImageView.java b/src/com/android/launcher3/HolographicImageView.java
deleted file mode 100644
index 18ac092..0000000
--- a/src/com/android/launcher3/HolographicImageView.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ImageView;
-
-public class HolographicImageView extends ImageView {
-
-    private final HolographicViewHelper mHolographicHelper;
-    private boolean mHotwordOn;
-    private boolean mIsPressed;
-    private boolean mIsFocused;
-
-    public HolographicImageView(Context context) {
-        this(context, null);
-    }
-
-    public HolographicImageView(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public HolographicImageView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        mHolographicHelper = new HolographicViewHelper(context);
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HolographicLinearLayout,
-                defStyle, 0);
-        mHotwordOn = a.getBoolean(R.styleable.HolographicLinearLayout_stateHotwordOn, false);
-        a.recycle();
-
-        setOnTouchListener(new OnTouchListener() {
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                if (isPressed() != mIsPressed) {
-                    mIsPressed = isPressed();
-                    refreshDrawableState();
-                }
-                return false;
-            }
-        });
-
-        setOnFocusChangeListener(new OnFocusChangeListener() {
-            @Override
-            public void onFocusChange(View v, boolean hasFocus) {
-                if (isFocused() != mIsFocused) {
-                    mIsFocused = isFocused();
-                    refreshDrawableState();
-                }
-            }
-        });
-    }
-
-    void invalidatePressedFocusedStates() {
-        mHolographicHelper.invalidatePressedFocusedStates(this);
-    }
-
-    @Override
-    protected void drawableStateChanged() {
-        super.drawableStateChanged();
-
-        mHolographicHelper.generatePressedFocusedStates(this);
-        Drawable d = getDrawable();
-        if (d instanceof StateListDrawable) {
-            StateListDrawable sld = (StateListDrawable) d;
-            sld.setState(getDrawableState());
-            sld.invalidateSelf();
-        }
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        // One time call to generate the pressed/focused state -- must be called after
-        // measure/layout
-        mHolographicHelper.generatePressedFocusedStates(this);
-    }
-
-    private boolean isHotwordOn() {
-        return mHotwordOn;
-    }
-
-    public void setHotwordState(boolean on) {
-        if (on == mHotwordOn) {
-            return;
-        }
-        mHotwordOn = on;
-        refreshDrawableState();
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
-        if (isHotwordOn()) {
-            mergeDrawableStates(drawableState, new int[] {R.attr.stateHotwordOn});
-        }
-        return drawableState;
-    }
-}
diff --git a/src/com/android/launcher3/HolographicLinearLayout.java b/src/com/android/launcher3/HolographicLinearLayout.java
deleted file mode 100644
index 5344a7e..0000000
--- a/src/com/android/launcher3/HolographicLinearLayout.java
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.LinearLayout;
-
-public class HolographicLinearLayout extends LinearLayout {
-    private final HolographicViewHelper mHolographicHelper;
-    private ImageView mImageView;
-    private int mImageViewId;
-
-    private boolean mHotwordOn;
-    private boolean mIsPressed;
-    private boolean mIsFocused;
-
-    public HolographicLinearLayout(Context context) {
-        this(context, null);
-    }
-
-    public HolographicLinearLayout(Context context, AttributeSet attrs) {
-        this(context, attrs, 0);
-    }
-
-    public HolographicLinearLayout(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-
-        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.HolographicLinearLayout,
-                defStyle, 0);
-        mImageViewId = a.getResourceId(R.styleable.HolographicLinearLayout_sourceImageViewId, -1);
-        mHotwordOn = a.getBoolean(R.styleable.HolographicLinearLayout_stateHotwordOn, false);
-        a.recycle();
-
-
-        setWillNotDraw(false);
-        mHolographicHelper = new HolographicViewHelper(context);
-
-        setOnTouchListener(new OnTouchListener() {
-            @Override
-            public boolean onTouch(View v, MotionEvent event) {
-                if (isPressed() != mIsPressed) {
-                    mIsPressed = isPressed();
-                    refreshDrawableState();
-                }
-                return false;
-            }
-        });
-
-        setOnFocusChangeListener(new OnFocusChangeListener() {
-            @Override
-            public void onFocusChange(View v, boolean hasFocus) {
-                if (isFocused() != mIsFocused) {
-                    mIsFocused = isFocused();
-                    refreshDrawableState();
-                }
-            }
-        });
-    }
-
-    @Override
-    protected void drawableStateChanged() {
-        super.drawableStateChanged();
-
-        if (mImageView != null) {
-            mHolographicHelper.generatePressedFocusedStates(mImageView);
-            Drawable d = mImageView.getDrawable();
-            if (d instanceof StateListDrawable) {
-                StateListDrawable sld = (StateListDrawable) d;
-                sld.setState(getDrawableState());
-                sld.invalidateSelf();
-            }
-        }
-    }
-
-    void invalidatePressedFocusedStates() {
-        mHolographicHelper.invalidatePressedFocusedStates(mImageView);
-        invalidate();
-    }
-
-    @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-
-        // One time call to generate the pressed/focused state -- must be called after
-        // measure/layout
-        if (mImageView == null) {
-            mImageView = (ImageView) findViewById(mImageViewId);
-        }
-        mHolographicHelper.generatePressedFocusedStates(mImageView);
-    }
-
-    private boolean isHotwordOn() {
-        return mHotwordOn;
-    }
-
-    public void setHotwordState(boolean on) {
-        if (on == mHotwordOn) {
-            return;
-        }
-        mHotwordOn = on;
-        refreshDrawableState();
-    }
-
-    @Override
-    public int[] onCreateDrawableState(int extraSpace) {
-        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
-        if (isHotwordOn()) {
-            mergeDrawableStates(drawableState, new int[] {R.attr.stateHotwordOn});
-        }
-        return drawableState;
-    }
-}
diff --git a/src/com/android/launcher3/HolographicViewHelper.java b/src/com/android/launcher3/HolographicViewHelper.java
deleted file mode 100644
index 7ef0355..0000000
--- a/src/com/android/launcher3/HolographicViewHelper.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.StateListDrawable;
-import android.widget.ImageView;
-
-public class HolographicViewHelper {
-
-    private final Canvas mTempCanvas = new Canvas();
-
-    private boolean mStatesUpdated;
-    private int mHighlightColor, mHotwordColor;
-
-    public HolographicViewHelper(Context context) {
-        Resources res = context.getResources();
-        mHighlightColor = res.getColor(android.R.color.holo_blue_light);
-        mHotwordColor = res.getColor(android.R.color.holo_green_light);
-    }
-
-    /**
-     * Generate the pressed/focused states if necessary.
-     */
-    void generatePressedFocusedStates(ImageView v) {
-        if (!mStatesUpdated && v != null) {
-            mStatesUpdated = true;
-            Bitmap original = createOriginalImage(v, mTempCanvas);
-            Bitmap outline = createImageWithOverlay(v, mTempCanvas, mHighlightColor);
-            Bitmap hotword = createImageWithOverlay(v, mTempCanvas, mHotwordColor);
-            FastBitmapDrawable originalD = new FastBitmapDrawable(original);
-            FastBitmapDrawable outlineD = new FastBitmapDrawable(outline);
-            FastBitmapDrawable hotwordD = new FastBitmapDrawable(hotword);
-
-            StateListDrawable states = new StateListDrawable();
-
-            states.addState(new int[] {android.R.attr.state_pressed}, outlineD);
-            states.addState(new int[] {android.R.attr.state_focused}, outlineD);
-            states.addState(new int[] {R.attr.stateHotwordOn}, hotwordD);
-            states.addState(new int[] {}, originalD);
-            v.setImageDrawable(states);
-        }
-    }
-
-    /**
-     * Invalidates the pressed/focused states.
-     */
-    void invalidatePressedFocusedStates(ImageView v) {
-        mStatesUpdated = false;
-        if (v != null) {
-            v.invalidate();
-        }
-    }
-
-    /**
-     * Creates a copy of the original image.
-     */
-    private Bitmap createOriginalImage(ImageView v, Canvas canvas) {
-        final Drawable d = v.getDrawable();
-        final Bitmap b = Bitmap.createBitmap(
-                d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
-
-        canvas.setBitmap(b);
-        canvas.save();
-        d.draw(canvas);
-        canvas.restore();
-        canvas.setBitmap(null);
-
-        return b;
-    }
-
-    /**
-     * Creates a new press state image which is the old image with a blue overlay.
-     * Responsibility for the bitmap is transferred to the caller.
-     */
-    private Bitmap createImageWithOverlay(ImageView v, Canvas canvas, int color) {
-        final Drawable d = v.getDrawable();
-        final Bitmap b = Bitmap.createBitmap(
-                d.getIntrinsicWidth(), d.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
-
-        canvas.setBitmap(b);
-        canvas.save();
-        d.draw(canvas);
-        canvas.restore();
-        canvas.drawColor(color, PorterDuff.Mode.SRC_IN);
-        canvas.setBitmap(null);
-
-        return b;
-    }
-}
diff --git a/src/com/android/launcher3/IconCache.java b/src/com/android/launcher3/IconCache.java
index bb71d77..5a0875b 100644
--- a/src/com/android/launcher3/IconCache.java
+++ b/src/com/android/launcher3/IconCache.java
@@ -24,12 +24,10 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
-import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.text.TextUtils;
 import android.util.Log;
@@ -118,11 +116,10 @@
     }
 
     public Drawable getFullResDefaultActivityIcon() {
-        return getFullResIcon(Resources.getSystem(),
-                android.R.mipmap.sym_def_app_icon);
+        return getFullResIcon(Resources.getSystem(), android.R.mipmap.sym_def_app_icon);
     }
 
-    public Drawable getFullResIcon(Resources resources, int iconId) {
+    private Drawable getFullResIcon(Resources resources, int iconId) {
         Drawable d;
         try {
             d = resources.getDrawableForDensity(iconId, mIconDpi);
@@ -152,12 +149,7 @@
         return mIconDpi;
     }
 
-    public Drawable getFullResIcon(ResolveInfo info) {
-        return getFullResIcon(info.activityInfo);
-    }
-
     public Drawable getFullResIcon(ActivityInfo info) {
-
         Resources resources;
         try {
             resources = mPackageManager.getResourcesForApplication(
@@ -191,16 +183,14 @@
     /**
      * Remove any records for the supplied ComponentName.
      */
-    public void remove(ComponentName componentName, UserHandleCompat user) {
-        synchronized (mCache) {
-            mCache.remove(new CacheKey(componentName, user));
-        }
+    public synchronized void remove(ComponentName componentName, UserHandleCompat user) {
+        mCache.remove(new CacheKey(componentName, user));
     }
 
     /**
      * Remove any records for the supplied package name.
      */
-    public void remove(String packageName, UserHandleCompat user) {
+    public synchronized void remove(String packageName, UserHandleCompat user) {
         HashSet<CacheKey> forDeletion = new HashSet<CacheKey>();
         for (CacheKey key: mCache.keySet()) {
             if (key.componentName.getPackageName().equals(packageName)
@@ -216,24 +206,20 @@
     /**
      * Empty out the cache.
      */
-    public void flush() {
-        synchronized (mCache) {
-            mCache.clear();
-        }
+    public synchronized void flush() {
+        mCache.clear();
     }
 
     /**
      * Empty out the cache that aren't of the correct grid size
      */
-    public void flushInvalidIcons(DeviceProfile grid) {
-        synchronized (mCache) {
-            Iterator<Entry<CacheKey, CacheEntry>> it = mCache.entrySet().iterator();
-            while (it.hasNext()) {
-                final CacheEntry e = it.next().getValue();
-                if ((e.icon != null) && (e.icon.getWidth() < grid.iconSizePx
-                        || e.icon.getHeight() < grid.iconSizePx)) {
-                    it.remove();
-                }
+    public synchronized void flushInvalidIcons(DeviceProfile grid) {
+        Iterator<Entry<CacheKey, CacheEntry>> it = mCache.entrySet().iterator();
+        while (it.hasNext()) {
+            final CacheEntry e = it.next().getValue();
+            if ((e.icon != null) && (e.icon.getWidth() < grid.iconSizePx
+                    || e.icon.getHeight() < grid.iconSizePx)) {
+                it.remove();
             }
         }
     }
@@ -241,90 +227,78 @@
     /**
      * Fill in "application" with the icon and label for "info."
      */
-    public void getTitleAndIcon(AppInfo application, LauncherActivityInfoCompat info,
+    public synchronized void getTitleAndIcon(AppInfo application, LauncherActivityInfoCompat info,
             HashMap<Object, CharSequence> labelCache) {
-        synchronized (mCache) {
-            CacheEntry entry = cacheLocked(application.componentName, info, labelCache,
-                    info.getUser(), false);
+        CacheEntry entry = cacheLocked(application.componentName, info, labelCache,
+                info.getUser(), false);
 
-            application.title = entry.title;
-            application.iconBitmap = entry.icon;
-            application.contentDescription = entry.contentDescription;
-        }
+        application.title = entry.title;
+        application.iconBitmap = entry.icon;
+        application.contentDescription = entry.contentDescription;
     }
 
-    public Bitmap getIcon(Intent intent, UserHandleCompat user) {
-        return getIcon(intent, null, user, true);
-    }
-
-    private Bitmap getIcon(Intent intent, String title, UserHandleCompat user, boolean usePkgIcon) {
-        synchronized (mCache) {
-            ComponentName component = intent.getComponent();
-            // null info means not installed, but if we have a component from the intent then
-            // we should still look in the cache for restored app icons.
-            if (component == null) {
-                return getDefaultIcon(user);
-            }
-
-            LauncherActivityInfoCompat launcherActInfo = mLauncherApps.resolveActivity(intent, user);
-            CacheEntry entry = cacheLocked(component, launcherActInfo, null, user, usePkgIcon);
-            if (title != null) {
-                entry.title = title;
-                entry.contentDescription = mUserManager.getBadgedLabelForUser(title, user);
-            }
-            return entry.icon;
+    public synchronized Bitmap getIcon(Intent intent, UserHandleCompat user) {
+        ComponentName component = intent.getComponent();
+        // null info means not installed, but if we have a component from the intent then
+        // we should still look in the cache for restored app icons.
+        if (component == null) {
+            return getDefaultIcon(user);
         }
+
+        LauncherActivityInfoCompat launcherActInfo = mLauncherApps.resolveActivity(intent, user);
+        CacheEntry entry = cacheLocked(component, launcherActInfo, null, user, true);
+        return entry.icon;
     }
 
     /**
      * Fill in "shortcutInfo" with the icon and label for "info."
      */
-    public void getTitleAndIcon(ShortcutInfo shortcutInfo, Intent intent, UserHandleCompat user,
-            boolean usePkgIcon) {
-        synchronized (mCache) {
-            ComponentName component = intent.getComponent();
-            // null info means not installed, but if we have a component from the intent then
-            // we should still look in the cache for restored app icons.
-            if (component == null) {
-                shortcutInfo.setIcon(getDefaultIcon(user));
-                shortcutInfo.title = "";
-                shortcutInfo.usingFallbackIcon = true;
-            } else {
-                LauncherActivityInfoCompat launcherActInfo =
-                        mLauncherApps.resolveActivity(intent, user);
-                CacheEntry entry = cacheLocked(component, launcherActInfo, null, user, usePkgIcon);
+    public synchronized void getTitleAndIcon(ShortcutInfo shortcutInfo, Intent intent,
+            UserHandleCompat user, boolean usePkgIcon) {
+        ComponentName component = intent.getComponent();
+        // null info means not installed, but if we have a component from the intent then
+        // we should still look in the cache for restored app icons.
+        if (component == null) {
+            shortcutInfo.setIcon(getDefaultIcon(user));
+            shortcutInfo.title = "";
+            shortcutInfo.usingFallbackIcon = true;
+        } else {
+            LauncherActivityInfoCompat launcherActInfo =
+                    mLauncherApps.resolveActivity(intent, user);
+            CacheEntry entry = cacheLocked(component, launcherActInfo, null, user, usePkgIcon);
 
-                shortcutInfo.setIcon(entry.icon);
-                shortcutInfo.title = entry.title;
-                shortcutInfo.usingFallbackIcon = isDefaultIcon(entry.icon, user);
-            }
+            shortcutInfo.setIcon(entry.icon);
+            shortcutInfo.title = entry.title;
+            shortcutInfo.usingFallbackIcon = isDefaultIcon(entry.icon, user);
         }
     }
 
 
-    public Bitmap getDefaultIcon(UserHandleCompat user) {
+    public synchronized Bitmap getDefaultIcon(UserHandleCompat user) {
         if (!mDefaultIcons.containsKey(user)) {
             mDefaultIcons.put(user, makeDefaultIcon(user));
         }
         return mDefaultIcons.get(user);
     }
 
-    public Bitmap getIcon(ComponentName component, LauncherActivityInfoCompat info,
+    public synchronized Bitmap getIcon(ComponentName component, LauncherActivityInfoCompat info,
             HashMap<Object, CharSequence> labelCache) {
-        synchronized (mCache) {
-            if (info == null || component == null) {
-                return null;
-            }
-
-            CacheEntry entry = cacheLocked(component, info, labelCache, info.getUser(), false);
-            return entry.icon;
+        if (info == null || component == null) {
+            return null;
         }
+
+        CacheEntry entry = cacheLocked(component, info, labelCache, info.getUser(), false);
+        return entry.icon;
     }
 
     public boolean isDefaultIcon(Bitmap icon, UserHandleCompat user) {
         return mDefaultIcons.get(user) == icon;
     }
 
+    /**
+     * Retrieves the entry from the cache. If the entry is not present, it creates a new entry.
+     * This method is not thread safe, it must be called from a synchronized method.
+     */
     private CacheEntry cacheLocked(ComponentName componentName, LauncherActivityInfoCompat info,
             HashMap<Object, CharSequence> labelCache, UserHandleCompat user, boolean usePackageIcon) {
         CacheKey cacheKey = new CacheKey(componentName, user);
@@ -381,7 +355,7 @@
      * Adds a default package entry in the cache. This entry is not persisted and will be removed
      * when the cache is flushed.
      */
-    public void cachePackageInstallInfo(String packageName, UserHandleCompat user,
+    public synchronized void cachePackageInstallInfo(String packageName, UserHandleCompat user,
             Bitmap icon, CharSequence title) {
         remove(packageName, user);
 
@@ -390,16 +364,16 @@
             entry.title = title;
         }
         if (icon != null) {
-            entry.icon = Utilities.createIconBitmap(
-                    new BitmapDrawable(mContext.getResources(), icon), mContext);
+            entry.icon = Utilities.createIconBitmap(icon, mContext);
         }
     }
 
     /**
      * Gets an entry for the package, which can be used as a fallback entry for various components.
+     * This method is not thread safe, it must be called from a synchronized method.
      */
     private CacheEntry getEntryForPackage(String packageName, UserHandleCompat user) {
-        ComponentName cn = getPackageComponent(packageName);
+        ComponentName cn = new ComponentName(packageName, EMPTY_CLASS_NAME);;
         CacheKey cacheKey = new CacheKey(cn, user);
         CacheEntry entry = mCache.get(cacheKey);
         if (entry == null) {
@@ -422,15 +396,13 @@
         return entry;
     }
 
-    public HashMap<ComponentName,Bitmap> getAllIcons() {
-        synchronized (mCache) {
-            HashMap<ComponentName,Bitmap> set = new HashMap<ComponentName,Bitmap>();
-            for (CacheKey ck : mCache.keySet()) {
-                final CacheEntry e = mCache.get(ck);
-                set.put(ck.componentName, e.icon);
-            }
-            return set;
+    public synchronized HashMap<ComponentName,Bitmap> getAllIcons() {
+        HashMap<ComponentName,Bitmap> set = new HashMap<ComponentName,Bitmap>();
+        for (CacheKey ck : mCache.keySet()) {
+            final CacheEntry e = mCache.get(ck);
+            set.put(ck.componentName, e.icon);
         }
+        return set;
     }
 
     /**
@@ -536,23 +508,15 @@
      * Remove a pre-loaded icon from the persistent icon cache.
      *
      * @param componentName the component that should own the icon
-     * @returns true on success
      */
-    public boolean deletePreloadedIcon(ComponentName componentName, UserHandleCompat user) {
+    public void deletePreloadedIcon(ComponentName componentName, UserHandleCompat user) {
         // We don't keep icons for other profiles in persistent cache.
-        if (!user.equals(UserHandleCompat.myUserHandle())) {
-            return false;
+        if (!user.equals(UserHandleCompat.myUserHandle()) || componentName == null) {
+            return;
         }
-        if (componentName == null) {
-            return false;
-        }
-        if (mCache.remove(componentName) != null) {
-            if (DEBUG) Log.d(TAG, "removed pre-loaded icon from the in-memory cache");
-        }
+        remove(componentName, user);
         boolean success = mContext.deleteFile(getResourceFilename(componentName));
         if (DEBUG && success) Log.d(TAG, "removed pre-loaded icon from persistent cache");
-
-        return success;
     }
 
     private static String getResourceFilename(ComponentName component) {
@@ -560,8 +524,4 @@
         String filename = resourceName.replace(File.separatorChar, '_');
         return RESOURCE_FILE_PREFIX + filename;
     }
-
-    static ComponentName getPackageComponent(String packageName) {
-        return new ComponentName(packageName, EMPTY_CLASS_NAME);
-    }
 }
diff --git a/src/com/android/launcher3/InsettableFrameLayout.java b/src/com/android/launcher3/InsettableFrameLayout.java
new file mode 100644
index 0000000..7343bf6
--- /dev/null
+++ b/src/com/android/launcher3/InsettableFrameLayout.java
@@ -0,0 +1,96 @@
+package com.android.launcher3;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+
+public class InsettableFrameLayout extends FrameLayout implements
+    ViewGroup.OnHierarchyChangeListener, Insettable {
+
+    protected Rect mInsets = new Rect();
+
+    public InsettableFrameLayout(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        setOnHierarchyChangeListener(this);
+    }
+
+    public void setFrameLayoutChildInsets(View child, Rect newInsets, Rect oldInsets) {
+        final LayoutParams lp = (LayoutParams) child.getLayoutParams();
+
+        if (child instanceof Insettable) {
+            ((Insettable) child).setInsets(newInsets);
+        } else if (!lp.ignoreInsets) {
+            lp.topMargin += (newInsets.top - oldInsets.top);
+            lp.leftMargin += (newInsets.left - oldInsets.left);
+            lp.rightMargin += (newInsets.right - oldInsets.right);
+            lp.bottomMargin += (newInsets.bottom - oldInsets.bottom);
+        }
+        child.setLayoutParams(lp);
+    }
+
+    @Override
+    public void setInsets(Rect insets) {
+        final int n = getChildCount();
+        for (int i = 0; i < n; i++) {
+            final View child = getChildAt(i);
+            setFrameLayoutChildInsets(child, insets, mInsets);
+        }
+        mInsets.set(insets);
+    }
+
+    @Override
+    public LayoutParams generateLayoutParams(AttributeSet attrs) {
+        return new InsettableFrameLayout.LayoutParams(getContext(), attrs);
+    }
+
+    @Override
+    protected LayoutParams generateDefaultLayoutParams() {
+        return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+    }
+
+    // Override to allow type-checking of LayoutParams.
+    @Override
+    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
+        return p instanceof InsettableFrameLayout.LayoutParams;
+    }
+
+    @Override
+    protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {
+        return new LayoutParams(p);
+    }
+
+    public static class LayoutParams extends FrameLayout.LayoutParams {
+        boolean ignoreInsets = false;
+
+        public LayoutParams(Context c, AttributeSet attrs) {
+            super(c, attrs);
+            TypedArray a = c.obtainStyledAttributes(attrs,
+                    R.styleable.InsettableFrameLayout_Layout);
+            ignoreInsets = a.getBoolean(
+                    R.styleable.InsettableFrameLayout_Layout_layout_ignoreInsets, false);
+            a.recycle();
+        }
+
+        public LayoutParams(int width, int height) {
+            super(width, height);
+        }
+
+        public LayoutParams(ViewGroup.LayoutParams lp) {
+            super(lp);
+        }
+    }
+
+    @Override
+    public void onChildViewAdded(View parent, View child) {
+        setFrameLayoutChildInsets(child, mInsets, new Rect());
+    }
+
+    @Override
+    public void onChildViewRemoved(View parent, View child) {
+    }
+
+}
diff --git a/src/com/android/launcher3/InstallShortcutReceiver.java b/src/com/android/launcher3/InstallShortcutReceiver.java
index 2edde4f..1ab3085 100644
--- a/src/com/android/launcher3/InstallShortcutReceiver.java
+++ b/src/com/android/launcher3/InstallShortcutReceiver.java
@@ -17,7 +17,6 @@
 package com.android.launcher3;
 
 import android.content.BroadcastReceiver;
-import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.SharedPreferences;
@@ -28,14 +27,18 @@
 import android.text.TextUtils;
 import android.util.Base64;
 import android.util.Log;
-import android.widget.Toast;
 
+import com.android.launcher3.compat.LauncherActivityInfoCompat;
+import com.android.launcher3.compat.LauncherAppsCompat;
 import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.compat.UserManagerCompat;
 
+import org.json.JSONException;
 import org.json.JSONObject;
 import org.json.JSONStringer;
 import org.json.JSONTokener;
 
+import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -45,80 +48,52 @@
     private static final String TAG = "InstallShortcutReceiver";
     private static final boolean DBG = false;
 
-    public static final String ACTION_INSTALL_SHORTCUT =
+    private static final String ACTION_INSTALL_SHORTCUT =
             "com.android.launcher.action.INSTALL_SHORTCUT";
 
-    public static final String DATA_INTENT_KEY = "intent.data";
-    public static final String LAUNCH_INTENT_KEY = "intent.launch";
-    public static final String NAME_KEY = "name";
-    public static final String ICON_KEY = "icon";
-    public static final String ICON_RESOURCE_NAME_KEY = "iconResource";
-    public static final String ICON_RESOURCE_PACKAGE_NAME_KEY = "iconResourcePackage";
+    private static final String LAUNCH_INTENT_KEY = "intent.launch";
+    private static final String NAME_KEY = "name";
+    private static final String ICON_KEY = "icon";
+    private static final String ICON_RESOURCE_NAME_KEY = "iconResource";
+    private static final String ICON_RESOURCE_PACKAGE_NAME_KEY = "iconResourcePackage";
+
+    private static final String APP_SHORTCUT_TYPE_KEY = "isAppShortcut";
+    private static final String USER_HANDLE_KEY = "userHandle";
+
     // The set of shortcuts that are pending install
-    public static final String APPS_PENDING_INSTALL = "apps_to_install";
+    private static final String APPS_PENDING_INSTALL = "apps_to_install";
 
     public static final int NEW_SHORTCUT_BOUNCE_DURATION = 450;
     public static final int NEW_SHORTCUT_STAGGER_DELAY = 85;
 
-    private static final int INSTALL_SHORTCUT_SUCCESSFUL = 0;
-    private static final int INSTALL_SHORTCUT_IS_DUPLICATE = -1;
-
-    // A mime-type representing shortcut data
-    public static final String SHORTCUT_MIMETYPE =
-            "com.android.launcher3/shortcut";
-
-    private static Object sLock = new Object();
-
-    private static void addToStringSet(SharedPreferences sharedPrefs,
-            SharedPreferences.Editor editor, String key, String value) {
-        Set<String> strings = sharedPrefs.getStringSet(key, null);
-        if (strings == null) {
-            strings = new HashSet<String>(0);
-        } else {
-            strings = new HashSet<String>(strings);
-        }
-        strings.add(value);
-        editor.putStringSet(key, strings);
-    }
+    private static final Object sLock = new Object();
 
     private static void addToInstallQueue(
             SharedPreferences sharedPrefs, PendingInstallShortcutInfo info) {
         synchronized(sLock) {
-            try {
-                JSONStringer json = new JSONStringer()
-                    .object()
-                    .key(DATA_INTENT_KEY).value(info.data.toUri(0))
-                    .key(LAUNCH_INTENT_KEY).value(info.launchIntent.toUri(0))
-                    .key(NAME_KEY).value(info.name);
-                if (info.icon != null) {
-                    byte[] iconByteArray = ItemInfo.flattenBitmap(info.icon);
-                    json = json.key(ICON_KEY).value(
-                        Base64.encodeToString(
-                            iconByteArray, 0, iconByteArray.length, Base64.DEFAULT));
+            String encoded = info.encodeToString();
+            if (encoded != null) {
+                Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null);
+                if (strings == null) {
+                    strings = new HashSet<String>(1);
+                } else {
+                    strings = new HashSet<String>(strings);
                 }
-                if (info.iconResource != null) {
-                    json = json.key(ICON_RESOURCE_NAME_KEY).value(info.iconResource.resourceName);
-                    json = json.key(ICON_RESOURCE_PACKAGE_NAME_KEY)
-                        .value(info.iconResource.packageName);
-                }
-                json = json.endObject();
-                SharedPreferences.Editor editor = sharedPrefs.edit();
-                if (DBG) Log.d(TAG, "Adding to APPS_PENDING_INSTALL: " + json);
-                addToStringSet(sharedPrefs, editor, APPS_PENDING_INSTALL, json.toString());
-                editor.commit();
-            } catch (org.json.JSONException e) {
-                Log.d(TAG, "Exception when adding shortcut: " + e);
+                strings.add(encoded);
+                sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, strings).commit();
             }
         }
     }
 
-    public static void removeFromInstallQueue(SharedPreferences sharedPrefs,
-                                              ArrayList<String> packageNames) {
+    public static void removeFromInstallQueue(Context context, ArrayList<String> packageNames,
+            UserHandleCompat user) {
         if (packageNames.isEmpty()) {
             return;
         }
+        String spKey = LauncherAppState.getSharedPreferencesKey();
+        SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
         synchronized(sLock) {
-            Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null);
+            Set<String> strings = sp.getStringSet(APPS_PENDING_INSTALL, null);
             if (DBG) {
                 Log.d(TAG, "APPS_PENDING_INSTALL: " + strings
                         + ", removing packages: " + packageNames);
@@ -127,31 +102,20 @@
                 Set<String> newStrings = new HashSet<String>(strings);
                 Iterator<String> newStringsIter = newStrings.iterator();
                 while (newStringsIter.hasNext()) {
-                    String json = newStringsIter.next();
-                    try {
-                        JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
-                        Intent launchIntent = Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0);
-                        String pn = launchIntent.getPackage();
-                        if (pn == null) {
-                            pn = launchIntent.getComponent().getPackageName();
-                        }
-                        if (packageNames.contains(pn)) {
-                            newStringsIter.remove();
-                        }
-                    } catch (org.json.JSONException e) {
-                        Log.d(TAG, "Exception reading shortcut to remove: " + e);
-                    } catch (java.net.URISyntaxException e) {
-                        Log.d(TAG, "Exception reading shortcut to remove: " + e);
+                    String encoded = newStringsIter.next();
+                    PendingInstallShortcutInfo info = decode(encoded, context);
+                    if (info == null || (packageNames.contains(info.getTargetPackage())
+                            && user.equals(info.user))) {
+                        newStringsIter.remove();
                     }
                 }
-                sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL,
-                        new HashSet<String>(newStrings)).commit();
+                sp.edit().putStringSet(APPS_PENDING_INSTALL, newStrings).commit();
             }
         }
     }
 
     private static ArrayList<PendingInstallShortcutInfo> getAndClearInstallQueue(
-            SharedPreferences sharedPrefs) {
+            SharedPreferences sharedPrefs, Context context) {
         synchronized(sLock) {
             Set<String> strings = sharedPrefs.getStringSet(APPS_PENDING_INSTALL, null);
             if (DBG) Log.d(TAG, "Getting and clearing APPS_PENDING_INSTALL: " + strings);
@@ -160,36 +124,10 @@
             }
             ArrayList<PendingInstallShortcutInfo> infos =
                 new ArrayList<PendingInstallShortcutInfo>();
-            for (String json : strings) {
-                try {
-                    JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
-                    Intent data = Intent.parseUri(object.getString(DATA_INTENT_KEY), 0);
-                    Intent launchIntent =
-                            Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0);
-                    String name = object.getString(NAME_KEY);
-                    String iconBase64 = object.optString(ICON_KEY);
-                    String iconResourceName = object.optString(ICON_RESOURCE_NAME_KEY);
-                    String iconResourcePackageName =
-                        object.optString(ICON_RESOURCE_PACKAGE_NAME_KEY);
-                    if (iconBase64 != null && !iconBase64.isEmpty()) {
-                        byte[] iconArray = Base64.decode(iconBase64, Base64.DEFAULT);
-                        Bitmap b = BitmapFactory.decodeByteArray(iconArray, 0, iconArray.length);
-                        data.putExtra(Intent.EXTRA_SHORTCUT_ICON, b);
-                    } else if (iconResourceName != null && !iconResourceName.isEmpty()) {
-                        Intent.ShortcutIconResource iconResource =
-                            new Intent.ShortcutIconResource();
-                        iconResource.resourceName = iconResourceName;
-                        iconResource.packageName = iconResourcePackageName;
-                        data.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
-                    }
-                    data.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launchIntent);
-                    PendingInstallShortcutInfo info =
-                        new PendingInstallShortcutInfo(data, name, launchIntent);
+            for (String encoded : strings) {
+                PendingInstallShortcutInfo info = decode(encoded, context);
+                if (info != null) {
                     infos.add(info);
-                } catch (org.json.JSONException e) {
-                    Log.d(TAG, "Exception reading shortcut to add: " + e);
-                } catch (java.net.URISyntaxException e) {
-                    Log.d(TAG, "Exception reading shortcut to add: " + e);
                 }
             }
             sharedPrefs.edit().putStringSet(APPS_PENDING_INSTALL, new HashSet<String>()).commit();
@@ -201,49 +139,26 @@
     // processAllPendingInstalls() is called.
     private static boolean mUseInstallQueue = false;
 
-    private static class PendingInstallShortcutInfo {
-        Intent data;
-        Intent launchIntent;
-        String name;
-        Bitmap icon;
-        Intent.ShortcutIconResource iconResource;
-
-        public PendingInstallShortcutInfo(Intent rawData, String shortcutName,
-                Intent shortcutIntent) {
-            data = rawData;
-            name = shortcutName;
-            launchIntent = shortcutIntent;
-        }
-    }
-
     public void onReceive(Context context, Intent data) {
         if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) {
             return;
         }
 
         if (DBG) Log.d(TAG, "Got INSTALL_SHORTCUT: " + data.toUri(0));
+        PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, context);
 
-        Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
-        if (intent == null) {
-            return;
-        }
+        queuePendingShortcutInfo(info, context);
+    }
 
-        // This name is only used for comparisons and notifications, so fall back to activity name
-        // if not supplied
-        String name = ensureValidName(context, intent,
-                data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME)).toString();
-        Bitmap icon = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
-        Intent.ShortcutIconResource iconResource =
-            data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
+    static void queueInstallShortcut(LauncherActivityInfoCompat info, Context context) {
+        queuePendingShortcutInfo(new PendingInstallShortcutInfo(info, context), context);
+    }
 
+    private static void queuePendingShortcutInfo(PendingInstallShortcutInfo info, Context context) {
         // Queue the item up for adding if launcher has not loaded properly yet
         LauncherAppState.setApplicationContext(context.getApplicationContext());
         LauncherAppState app = LauncherAppState.getInstance();
-        boolean launcherNotLoaded = (app.getDynamicGrid() == null);
-
-        PendingInstallShortcutInfo info = new PendingInstallShortcutInfo(data, name, intent);
-        info.icon = icon;
-        info.iconResource = iconResource;
+        boolean launcherNotLoaded = app.getModel().getCallback() == null;
 
         String spKey = LauncherAppState.getSharedPreferencesKey();
         SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
@@ -263,33 +178,22 @@
     static void flushInstallQueue(Context context) {
         String spKey = LauncherAppState.getSharedPreferencesKey();
         SharedPreferences sp = context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-        ArrayList<PendingInstallShortcutInfo> installQueue = getAndClearInstallQueue(sp);
+        ArrayList<PendingInstallShortcutInfo> installQueue = getAndClearInstallQueue(sp, context);
         if (!installQueue.isEmpty()) {
             Iterator<PendingInstallShortcutInfo> iter = installQueue.iterator();
             ArrayList<ItemInfo> addShortcuts = new ArrayList<ItemInfo>();
-            int result = INSTALL_SHORTCUT_SUCCESSFUL;
-            String duplicateName = "";
             while (iter.hasNext()) {
                 final PendingInstallShortcutInfo pendingInfo = iter.next();
-                //final Intent data = pendingInfo.data;
                 final Intent intent = pendingInfo.launchIntent;
-                final String name = pendingInfo.name;
 
                 if (LauncherAppState.isDisableAllApps() && !isValidShortcutLaunchIntent(intent)) {
                     if (DBG) Log.d(TAG, "Ignoring shortcut with launchIntent:" + intent);
                     continue;
                 }
 
-                final boolean exists = LauncherModel.shortcutExists(context, name, intent);
-                //final boolean allowDuplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
-
                 // If the intent specifies a package, make sure the package exists
-                String packageName = intent.getPackage();
-                if (packageName == null) {
-                    packageName = intent.getComponent() == null ? null :
-                        intent.getComponent().getPackageName();
-                }
-                if (packageName != null && !packageName.isEmpty()) {
+                String packageName = pendingInfo.getTargetPackage();
+                if (!TextUtils.isEmpty(packageName)) {
                     UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
                     if (!LauncherModel.isValidPackage(context, packageName, myUserHandle)) {
                         if (DBG) Log.d(TAG, "Ignoring shortcut for absent package:" + intent);
@@ -297,19 +201,12 @@
                     }
                 }
 
+                final boolean exists = LauncherModel.shortcutExists(context, pendingInfo.label,
+                        intent, pendingInfo.user);
                 if (!exists) {
                     // Generate a shortcut info to add into the model
-                    ShortcutInfo info = getShortcutInfo(context, pendingInfo.data,
-                            pendingInfo.launchIntent);
-                    addShortcuts.add(info);
+                    addShortcuts.add(pendingInfo.getShortcutInfo());
                 }
-
-            }
-
-            // Notify the user once if we weren't able to place any duplicates
-            if (result == INSTALL_SHORTCUT_IS_DUPLICATE) {
-                Toast.makeText(context, context.getString(R.string.shortcut_duplicate,
-                        duplicateName), Toast.LENGTH_SHORT).show();
             }
 
             // Add the new apps to the model and bind them
@@ -344,22 +241,6 @@
         return true;
     }
 
-    private static ShortcutInfo getShortcutInfo(Context context, Intent data,
-                                                Intent launchIntent) {
-        if (launchIntent.getAction() == null) {
-            launchIntent.setAction(Intent.ACTION_VIEW);
-        } else if (launchIntent.getAction().equals(Intent.ACTION_MAIN) &&
-                launchIntent.getCategories() != null &&
-                launchIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
-            launchIntent.addFlags(
-                    Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-        }
-        LauncherAppState app = LauncherAppState.getInstance();
-        ShortcutInfo info = app.getModel().infoFromShortcutIntent(context, data, null);
-        info.title = ensureValidName(context, launchIntent, info.title);
-        return info;
-    }
-
     /**
      * Ensures that we have a valid, non-null name.  If the provided name is null, we will return
      * the application name instead.
@@ -376,4 +257,171 @@
         }
         return name;
     }
+
+    private static class PendingInstallShortcutInfo {
+
+        final LauncherActivityInfoCompat activityInfo;
+
+        final Intent data;
+        final Context mContext;
+        final Intent launchIntent;
+        final String label;
+        final UserHandleCompat user;
+
+        /**
+         * Initializes a PendingInstallShortcutInfo received from a different app.
+         */
+        public PendingInstallShortcutInfo(Intent data, Context context) {
+            this.data = data;
+            mContext = context;
+
+            launchIntent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
+            label = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
+            user = UserHandleCompat.myUserHandle();
+            activityInfo = null;
+        }
+
+        /**
+         * Initializes a PendingInstallShortcutInfo to represent a launcher target.
+         */
+        public PendingInstallShortcutInfo(LauncherActivityInfoCompat info, Context context) {
+            this.data = null;
+            mContext = context;
+            activityInfo = info;
+            user = info.getUser();
+
+            launchIntent = AppInfo.makeLaunchIntent(context, info, user);
+            label = info.getLabel().toString();
+        }
+
+        public String encodeToString() {
+            if (activityInfo != null) {
+                try {
+                    // If it a launcher target, we only need component name, and user to
+                    // recreate this.
+                    return new JSONStringer()
+                        .object()
+                        .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
+                        .key(APP_SHORTCUT_TYPE_KEY).value(true)
+                        .key(USER_HANDLE_KEY).value(UserManagerCompat.getInstance(mContext)
+                                .getSerialNumberForUser(user))
+                        .endObject().toString();
+                } catch (JSONException e) {
+                    Log.d(TAG, "Exception when adding shortcut: " + e);
+                    return null;
+                }
+            }
+
+            if (launchIntent.getAction() == null) {
+                launchIntent.setAction(Intent.ACTION_VIEW);
+            } else if (launchIntent.getAction().equals(Intent.ACTION_MAIN) &&
+                    launchIntent.getCategories() != null &&
+                    launchIntent.getCategories().contains(Intent.CATEGORY_LAUNCHER)) {
+                launchIntent.addFlags(
+                        Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
+            }
+
+            // This name is only used for comparisons and notifications, so fall back to activity
+            // name if not supplied
+            String name = ensureValidName(mContext, launchIntent, label).toString();
+            Bitmap icon = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
+            Intent.ShortcutIconResource iconResource =
+                data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
+
+            // Only encode the parameters which are supported by the API.
+            try {
+                JSONStringer json = new JSONStringer()
+                    .object()
+                    .key(LAUNCH_INTENT_KEY).value(launchIntent.toUri(0))
+                    .key(NAME_KEY).value(name);
+                if (icon != null) {
+                    byte[] iconByteArray = ItemInfo.flattenBitmap(icon);
+                    json = json.key(ICON_KEY).value(
+                            Base64.encodeToString(
+                                    iconByteArray, 0, iconByteArray.length, Base64.DEFAULT));
+                }
+                if (iconResource != null) {
+                    json = json.key(ICON_RESOURCE_NAME_KEY).value(iconResource.resourceName);
+                    json = json.key(ICON_RESOURCE_PACKAGE_NAME_KEY)
+                            .value(iconResource.packageName);
+                }
+                return json.endObject().toString();
+            } catch (JSONException e) {
+                Log.d(TAG, "Exception when adding shortcut: " + e);
+            }
+            return null;
+        }
+
+        public ShortcutInfo getShortcutInfo() {
+            if (activityInfo != null) {
+                final ShortcutInfo info = new ShortcutInfo();
+                info.user = user;
+                info.title = label;
+                info.contentDescription = label;
+                info.customIcon = false;
+                info.intent = launchIntent;
+                info.itemType = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
+                info.flags = AppInfo.initFlags(activityInfo);
+                info.firstInstallTime = activityInfo.getFirstInstallTime();
+                return info;
+            } else {
+                return LauncherAppState.getInstance().getModel().infoFromShortcutIntent(mContext, data);
+            }
+        }
+
+        public String getTargetPackage() {
+            String packageName = launchIntent.getPackage();
+            if (packageName == null) {
+                packageName = launchIntent.getComponent() == null ? null :
+                    launchIntent.getComponent().getPackageName();
+            }
+            return packageName;
+        }
+    }
+
+    private static PendingInstallShortcutInfo decode(String encoded, Context context) {
+        try {
+            JSONObject object = (JSONObject) new JSONTokener(encoded).nextValue();
+            Intent launcherIntent = Intent.parseUri(object.getString(LAUNCH_INTENT_KEY), 0);
+
+            if (object.optBoolean(APP_SHORTCUT_TYPE_KEY)) {
+                // The is an internal launcher target shortcut.
+                UserHandleCompat user = UserManagerCompat.getInstance(context)
+                        .getUserForSerialNumber(object.getLong(USER_HANDLE_KEY));
+                if (user == null) {
+                    return null;
+                }
+
+                LauncherActivityInfoCompat info = LauncherAppsCompat.getInstance(context)
+                        .resolveActivity(launcherIntent, user);
+                return info == null ? null : new PendingInstallShortcutInfo(info, context);
+            }
+
+            Intent data = new Intent();
+            data.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);
+            data.putExtra(Intent.EXTRA_SHORTCUT_NAME, object.getString(NAME_KEY));
+
+            String iconBase64 = object.optString(ICON_KEY);
+            String iconResourceName = object.optString(ICON_RESOURCE_NAME_KEY);
+            String iconResourcePackageName = object.optString(ICON_RESOURCE_PACKAGE_NAME_KEY);
+            if (iconBase64 != null && !iconBase64.isEmpty()) {
+                byte[] iconArray = Base64.decode(iconBase64, Base64.DEFAULT);
+                Bitmap b = BitmapFactory.decodeByteArray(iconArray, 0, iconArray.length);
+                data.putExtra(Intent.EXTRA_SHORTCUT_ICON, b);
+            } else if (iconResourceName != null && !iconResourceName.isEmpty()) {
+                Intent.ShortcutIconResource iconResource =
+                    new Intent.ShortcutIconResource();
+                iconResource.resourceName = iconResourceName;
+                iconResource.packageName = iconResourcePackageName;
+                data.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
+            }
+
+            return new PendingInstallShortcutInfo(data, context);
+        } catch (JSONException e) {
+            Log.d(TAG, "Exception reading shortcut to add: " + e);
+        } catch (URISyntaxException e) {
+            Log.d(TAG, "Exception reading shortcut to add: " + e);
+        }
+        return null;
+    }
 }
diff --git a/src/com/android/launcher3/InstallWidgetReceiver.java b/src/com/android/launcher3/InstallWidgetReceiver.java
deleted file mode 100644
index 74b9e3d..0000000
--- a/src/com/android/launcher3/InstallWidgetReceiver.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT 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.appwidget.AppWidgetProviderInfo;
-import android.content.ClipData;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.database.DataSetObserver;
-import android.graphics.drawable.Drawable;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.TextView;
-
-import java.util.List;
-
-
-/**
- * We will likely flesh this out later, to handle allow external apps to place widgets, but for now,
- * we just want to expose the action around for checking elsewhere.
- */
-public class InstallWidgetReceiver {
-    public static final String ACTION_INSTALL_WIDGET =
-            "com.android.launcher3.action.INSTALL_WIDGET";
-    public static final String ACTION_SUPPORTS_CLIPDATA_MIMETYPE =
-            "com.android.launcher3.action.SUPPORTS_CLIPDATA_MIMETYPE";
-
-    // Currently not exposed.  Put into Intent when we want to make it public.
-    // TEMP: Should we call this "EXTRA_APPWIDGET_PROVIDER"?
-    public static final String EXTRA_APPWIDGET_COMPONENT =
-        "com.android.launcher3.extra.widget.COMPONENT";
-    public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA_MIME_TYPE =
-        "com.android.launcher3.extra.widget.CONFIGURATION_DATA_MIME_TYPE";
-    public static final String EXTRA_APPWIDGET_CONFIGURATION_DATA =
-        "com.android.launcher3.extra.widget.CONFIGURATION_DATA";
-
-    /**
-     * A simple data class that contains per-item information that the adapter below can reference.
-     */
-    public static class WidgetMimeTypeHandlerData {
-        public ResolveInfo resolveInfo;
-        public AppWidgetProviderInfo widgetInfo;
-
-        public WidgetMimeTypeHandlerData(ResolveInfo rInfo, AppWidgetProviderInfo wInfo) {
-            resolveInfo = rInfo;
-            widgetInfo = wInfo;
-        }
-    }
-
-    /**
-     * The ListAdapter which presents all the valid widgets that can be created for a given drop.
-     */
-    public static class WidgetListAdapter implements ListAdapter, DialogInterface.OnClickListener {
-        private LayoutInflater mInflater;
-        private Launcher mLauncher;
-        private String mMimeType;
-        private ClipData mClipData;
-        private List<WidgetMimeTypeHandlerData> mActivities;
-        private int mTargetLayoutScreen;
-        private int[] mTargetLayoutPos;
-
-        public WidgetListAdapter(Launcher l, String mimeType, ClipData data,
-                List<WidgetMimeTypeHandlerData> list, int targetScreen, int[] targetPos) {
-            mLauncher = l;
-            mMimeType = mimeType;
-            mClipData = data;
-            mActivities = list;
-            mTargetLayoutScreen = targetScreen;
-            mTargetLayoutPos = targetPos;
-        }
-
-        @Override
-        public void registerDataSetObserver(DataSetObserver observer) {
-        }
-
-        @Override
-        public void unregisterDataSetObserver(DataSetObserver observer) {
-        }
-
-        @Override
-        public int getCount() {
-            return mActivities.size();
-        }
-
-        @Override
-        public Object getItem(int position) {
-            return null;
-        }
-
-        @Override
-        public long getItemId(int position) {
-            return position;
-        }
-
-        @Override
-        public boolean hasStableIds() {
-            return true;
-        }
-
-        @Override
-        public View getView(int position, View convertView, ViewGroup parent) {
-            final Context context = parent.getContext();
-            final PackageManager packageManager = context.getPackageManager();
-
-            // Lazy-create inflater
-            if (mInflater == null) {
-                mInflater = LayoutInflater.from(context);
-            }
-
-            // Use the convert-view where possible
-            if (convertView == null) {
-                convertView = mInflater.inflate(R.layout.external_widget_drop_list_item, parent,
-                        false);
-            }
-
-            final WidgetMimeTypeHandlerData data = mActivities.get(position);
-            final ResolveInfo resolveInfo = data.resolveInfo;
-            final AppWidgetProviderInfo widgetInfo = data.widgetInfo;
-
-            // Set the icon
-            Drawable d = resolveInfo.loadIcon(packageManager);
-            ImageView i = (ImageView) convertView.findViewById(R.id.provider_icon);
-            i.setImageDrawable(d);
-
-            // Set the text
-            final CharSequence component = resolveInfo.loadLabel(packageManager);
-            final int[] widgetSpan = new int[2];
-            CellLayout.rectToCell(widgetInfo.minWidth, widgetInfo.minHeight, widgetSpan);
-            TextView t = (TextView) convertView.findViewById(R.id.provider);
-            t.setText(context.getString(R.string.external_drop_widget_pick_format,
-                    component, widgetSpan[0], widgetSpan[1]));
-
-            return convertView;
-        }
-
-        @Override
-        public int getItemViewType(int position) {
-            return 0;
-        }
-
-        @Override
-        public int getViewTypeCount() {
-            return 1;
-        }
-
-        @Override
-        public boolean isEmpty() {
-            return mActivities.isEmpty();
-        }
-
-        @Override
-        public boolean areAllItemsEnabled() {
-            return false;
-        }
-
-        @Override
-        public boolean isEnabled(int position) {
-            return true;
-        }
-
-        @Override
-        public void onClick(DialogInterface dialog, int which) {
-            final AppWidgetProviderInfo widgetInfo = mActivities.get(which).widgetInfo;
-
-            final PendingAddWidgetInfo createInfo = new PendingAddWidgetInfo(widgetInfo, mMimeType,
-                    mClipData);
-            mLauncher.addAppWidgetFromDrop(createInfo, LauncherSettings.Favorites.CONTAINER_DESKTOP,
-                    mTargetLayoutScreen, null, null, mTargetLayoutPos);
-        }
-    }
-}
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 42ec4fb..ac46fd3 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -50,10 +50,10 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
+import android.database.sqlite.SQLiteDatabase;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
-import android.graphics.Point;
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
@@ -66,14 +66,11 @@
 import android.os.Message;
 import android.os.StrictMode;
 import android.os.SystemClock;
-import android.speech.RecognizerIntent;
 import android.text.Selection;
 import android.text.SpannableStringBuilder;
 import android.text.TextUtils;
 import android.text.method.TextKeyListener;
-import android.util.DisplayMetrics;
 import android.util.Log;
-import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
@@ -87,19 +84,17 @@
 import android.view.View.OnLongClickListener;
 import android.view.ViewAnimationUtils;
 import android.view.ViewGroup;
+import android.view.ViewStub;
 import android.view.ViewTreeObserver;
-import android.view.ViewTreeObserver.OnGlobalLayoutListener;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.AccelerateInterpolator;
 import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Interpolator;
 import android.view.inputmethod.InputMethodManager;
 import android.widget.Advanceable;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
-import android.widget.TextView;
 import android.widget.Toast;
 
 import com.android.launcher3.DropTarget.DragObject;
@@ -128,6 +123,7 @@
 import java.util.Collection;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -168,10 +164,8 @@
     static final int SCREEN_COUNT = 5;
     static final int DEFAULT_SCREEN = 2;
 
-    private static final String PREFERENCES = "launcher.preferences";
     // To turn on these properties, type
     // adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]
-    static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";
     static final String DUMP_STATE_PROPERTY = "launcher_dump_state";
     static final String DISABLE_ALL_APPS_PROPERTY = "launcher_noallapps";
 
@@ -213,15 +207,12 @@
     static final String ACTION_FIRST_LOAD_COMPLETE =
             "com.android.launcher3.action.FIRST_LOAD_COMPLETE";
 
-    private static final String TOOLBAR_ICON_METADATA_NAME = "com.android.launcher.toolbar_icon";
-    private static final String TOOLBAR_SEARCH_ICON_METADATA_NAME =
-            "com.android.launcher.toolbar_search_icon";
-    private static final String TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME =
-            "com.android.launcher.toolbar_voice_search_icon";
-
     public static final String SHOW_WEIGHT_WATCHER = "debug.show_mem";
     public static final boolean SHOW_WEIGHT_WATCHER_DEFAULT = false;
 
+    private static final String QSB_WIDGET_ID = "qsb_widget_id";
+    private static final String QSB_WIDGET_PROVIDER = "qsb_widget_provider";
+
     public static final String USER_HAS_MIGRATED = "launcher.user_migrated_from_old_data";
 
     /** The different states that Launcher can be in. */
@@ -231,6 +222,10 @@
 
     private boolean mIsSafeModeEnabled;
 
+    LauncherOverlayCallbacks mLauncherOverlayCallbacks = new LauncherOverlayCallbacksImpl();
+    LauncherOverlay mLauncherOverlay;
+    InsettableFrameLayout mLauncherOverlayContainer;
+
     static final int APPWIDGET_HOST_ID = 1024;
     public static final int EXIT_SPRINGLOADED_MODE_SHORT_TIMEOUT = 300;
     private static final int ON_ACTIVITY_RESULT_ANIMATION_DELAY = 500;
@@ -281,7 +276,7 @@
     private AppsCustomizeTabHost mAppsCustomizeTabHost;
     private AppsCustomizePagedView mAppsCustomizeContent;
     private boolean mAutoAdvanceRunning = false;
-    private View mQsb;
+    private AppWidgetHostView mQsb;
 
     private Bundle mSavedState;
     // We set the state in both onCreate and then onNewIntent in some cases, which causes both
@@ -329,10 +324,6 @@
     // match the sensor state.
     private final int mRestoreScreenOrientationDelay = 500;
 
-    // External icons saved in case of resource changes, orientation, etc.
-    private static Drawable.ConstantState[] sGlobalSearchIcon = new Drawable.ConstantState[2];
-    private static Drawable.ConstantState[] sVoiceSearchIcon = new Drawable.ConstantState[2];
-
     private Drawable mWorkspaceBackgroundDrawable;
 
     private final ArrayList<Integer> mSynchronouslyBoundPages = new ArrayList<Integer>();
@@ -370,8 +361,6 @@
 
     private static PendingAddArguments sPendingAddItem;
 
-    public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
-
     private static class PendingAddArguments {
         int requestCode;
         Intent intent;
@@ -386,10 +375,6 @@
 
     FocusIndicatorView mFocusHandler;
 
-    static boolean isPropertyEnabled(String propertyName) {
-        return Log.isLoggable(propertyName, Log.VERBOSE);
-    }
-
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         if (DEBUG_STRICT_MODE) {
@@ -407,27 +392,18 @@
                     .build());
         }
 
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.preOnCreate();
+        }
+
         super.onCreate(savedInstanceState);
 
         LauncherAppState.setApplicationContext(getApplicationContext());
         LauncherAppState app = LauncherAppState.getInstance();
         LauncherAppState.getLauncherProvider().setLauncherProviderChangeListener(this);
-        // Determine the dynamic grid properties
-        Point smallestSize = new Point();
-        Point largestSize = new Point();
-        Point realSize = new Point();
-        Display display = getWindowManager().getDefaultDisplay();
-        display.getCurrentSizeRange(smallestSize, largestSize);
-        display.getRealSize(realSize);
-        DisplayMetrics dm = new DisplayMetrics();
-        display.getMetrics(dm);
 
         // Lazy-initialize the dynamic grid
-        DeviceProfile grid = app.initDynamicGrid(this,
-                Math.min(smallestSize.x, smallestSize.y),
-                Math.min(largestSize.x, largestSize.y),
-                realSize.x, realSize.y,
-                dm.widthPixels, dm.heightPixels);
+        DeviceProfile grid = app.initDynamicGrid(this);
 
         // the LauncherApplication should call this, but in case of Instrumentation it might not be present yet
         mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),
@@ -492,11 +468,20 @@
         IntentFilter filter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
         registerReceiver(mCloseSystemDialogsReceiver, filter);
 
-        updateGlobalIcons();
-
         // On large interfaces, we want the screen to auto-rotate based on the current orientation
         unlockScreenOrientation(true);
 
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onCreate(savedInstanceState);
+            if (mLauncherCallbacks.hasLauncherOverlay()) {
+                ViewStub stub = (ViewStub) findViewById(R.id.launcher_overlay_stub);
+                mLauncherOverlayContainer = (InsettableFrameLayout) stub.inflate();
+                mLauncherOverlay = mLauncherCallbacks.setLauncherOverlayView(
+                        mLauncherOverlayContainer, mLauncherOverlayCallbacks);
+                mWorkspace.setLauncherOverlay(mLauncherOverlay);
+            }
+        }
+
         if (shouldShowIntroScreen()) {
             showIntroScreen();
         } else {
@@ -505,11 +490,32 @@
         }
     }
 
-    @Override
-    public void onLauncherProviderChange() { }
+    private LauncherCallbacks mLauncherCallbacks;
 
-    /** To be overriden by subclasses to hint to Launcher that we have custom content */
+    public void onPostCreate(Bundle savedInstanceState) {
+        super.onPostCreate(savedInstanceState);
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onPostCreate(savedInstanceState);
+        }
+    }
+
+    public boolean setLauncherCallbacks(LauncherCallbacks callbacks) {
+        mLauncherCallbacks = callbacks;
+        return true;
+    }
+
+    @Override
+    public void onLauncherProviderChange() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onLauncherProviderChange();
+        }
+    }
+
+    /** To be overridden by subclasses to hint to Launcher that we have custom content */
     protected boolean hasCustomContentToLeft() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.hasCustomContentToLeft();
+        }
         return false;
     }
 
@@ -519,6 +525,9 @@
      * {@link #hasCustomContentToLeft()} is {@code true}.
      */
     protected void populateCustomContentContainer() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.populateCustomContentContainer();
+        }
     }
 
     /**
@@ -540,28 +549,6 @@
         }
     }
 
-    private void updateGlobalIcons() {
-        boolean searchVisible = false;
-        boolean voiceVisible = false;
-        // If we have a saved version of these external icons, we load them up immediately
-        int coi = getCurrentOrientationIndexForGlobalIcons();
-        if (sGlobalSearchIcon[coi] == null || sVoiceSearchIcon[coi] == null) {
-            searchVisible = updateGlobalSearchIcon();
-            voiceVisible = updateVoiceSearchIcon(searchVisible);
-        }
-        if (sGlobalSearchIcon[coi] != null) {
-             updateGlobalSearchIcon(sGlobalSearchIcon[coi]);
-             searchVisible = true;
-        }
-        if (sVoiceSearchIcon[coi] != null) {
-            updateVoiceSearchIcon(sVoiceSearchIcon[coi]);
-            voiceVisible = true;
-        }
-        if (mSearchDropTargetBar != null) {
-            mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);
-        }
-    }
-
     private void checkForLocaleChange() {
         if (sLocaleConfiguration == null) {
             new AsyncTask<Void, Void, LocaleConfiguration>() {
@@ -620,7 +607,7 @@
     private static void readConfiguration(Context context, LocaleConfiguration configuration) {
         DataInputStream in = null;
         try {
-            in = new DataInputStream(context.openFileInput(PREFERENCES));
+            in = new DataInputStream(context.openFileInput(LauncherFiles.LAUNCHER_PREFERENCES));
             configuration.locale = in.readUTF();
             configuration.mcc = in.readInt();
             configuration.mnc = in.readInt();
@@ -642,7 +629,8 @@
     private static void writeConfiguration(Context context, LocaleConfiguration configuration) {
         DataOutputStream out = null;
         try {
-            out = new DataOutputStream(context.openFileOutput(PREFERENCES, MODE_PRIVATE));
+            out = new DataOutputStream(context.openFileOutput(
+                    LauncherFiles.LAUNCHER_PREFERENCES, MODE_PRIVATE));
             out.writeUTF(configuration.locale);
             out.writeInt(configuration.mcc);
             out.writeInt(configuration.mnc);
@@ -651,7 +639,7 @@
             // Ignore
         } catch (IOException e) {
             //noinspection ResultOfMethodCallIgnored
-            context.getFileStreamPath(PREFERENCES).delete();
+            context.getFileStreamPath(LauncherFiles.LAUNCHER_PREFERENCES).delete();
         } finally {
             if (out != null) {
                 try {
@@ -749,8 +737,7 @@
         return screenId;
     }
 
-    @Override
-    protected void onActivityResult(
+    private void handleActivityResult(
             final int requestCode, final int resultCode, final Intent data) {
         // Reset the startActivity waiting flag
         setWaitingForResult(false);
@@ -883,6 +870,16 @@
                     ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
         }
         mDragLayer.clearAnimatedView();
+
+    }
+
+    @Override
+    protected void onActivityResult(
+            final int requestCode, final int resultCode, final Intent data) {
+        handleActivityResult(requestCode, resultCode, data);
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onActivityResult(requestCode, resultCode, data);
+        }
     }
 
     private PendingAddArguments preparePendingAddArgs(int requestCode, Intent data, int
@@ -956,12 +953,20 @@
     protected void onStop() {
         super.onStop();
         FirstFrameAnimatorHelper.setIsVisible(false);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onStop();
+        }
     }
 
     @Override
     protected void onStart() {
         super.onStart();
         FirstFrameAnimatorHelper.setIsVisible(true);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onStart();
+        }
     }
 
     @Override
@@ -971,6 +976,11 @@
             startTime = System.currentTimeMillis();
             Log.v(TAG, "Launcher.onResume()");
         }
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.preOnResume();
+        }
+
         super.onResume();
 
         // Restore the previous launcher state
@@ -1037,12 +1047,6 @@
         // Process any items that were added while Launcher was away.
         InstallShortcutReceiver.disableAndFlushInstallQueue(this);
 
-        // Update the voice search button proxy
-        updateVoiceButtonProxyVisible(false);
-
-        // Again, as with the above scenario, it's possible that one or more of the global icons
-        // were updated in the wrong orientation.
-        updateGlobalIcons();
         if (DEBUG_RESUME_TIME) {
             Log.d(TAG, "Time spent in onResume: " + (System.currentTimeMillis() - startTime));
         }
@@ -1059,6 +1063,10 @@
         mWorkspace.onResume();
 
         PackageInstallerCompat.getInstance(this).onResume();
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onResume();
+        }
     }
 
     @Override
@@ -1077,25 +1085,10 @@
         if (mWorkspace.getCustomContentCallbacks() != null) {
             mWorkspace.getCustomContentCallbacks().onHide();
         }
-    }
 
-    QSBScroller mQsbScroller = new QSBScroller() {
-        int scrollY = 0;
-
-        @Override
-        public void setScrollY(int scroll) {
-            scrollY = scroll;
-
-            if (mWorkspace.isOnOrMovingToCustomContent()) {
-                mSearchDropTargetBar.setTranslationY(- scrollY);
-                getQsbBar().setTranslationY(-scrollY);
-            }
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onPause();
         }
-    };
-
-    public void resetQSBScroll() {
-        mSearchDropTargetBar.animate().translationY(0).start();
-        getQsbBar().animate().translationY(0).start();
     }
 
     public interface CustomContentCallbacks {
@@ -1113,18 +1106,95 @@
         boolean isScrollingAllowed();
     }
 
+    public interface LauncherOverlay {
+
+        /**
+         * Touch interaction leading to overscroll has begun
+         */
+        public void onScrollInteractionBegin();
+
+        /**
+         * Touch interaction related to overscroll has ended
+         */
+        public void onScrollInteractionEnd();
+
+        /**
+         * Scroll progress, between 0 and 100, when the user scrolls beyond the leftmost
+         * screen (or in the case of RTL, the rightmost screen).
+         */
+        public void onScrollChange(int progress, boolean rtl);
+
+        /**
+         * Screen has stopped scrolling
+         */
+        public void onScrollSettled();
+
+        /**
+         * This method can be called by the Launcher in order to force the LauncherOverlay
+         * to exit fully immersive mode.
+         */
+        public void forceExitFullImmersion();
+    }
+
+    public interface LauncherOverlayCallbacks {
+        /**
+         * This method indicates whether a call to {@link #enterFullImmersion()} will succeed,
+         * however it doesn't modify any state within the launcher.
+         */
+        public boolean canEnterFullImmersion();
+
+        /**
+         * Should be called to tell Launcher that the LauncherOverlay will take over interaction,
+         * eg. by occupying the full screen and handling all touch events.
+         *
+         * @return true if Launcher allows the LauncherOverlay to become fully immersive. In this
+         *          case, Launcher will modify any necessary state and assumes the overlay is
+         *          handling all interaction. If false, the LauncherOverlay should cancel any
+         *
+         */
+        public boolean enterFullImmersion();
+
+        /**
+         * Must be called when exiting fully immersive mode. Indicates to Launcher that it has
+         * full control over UI and state.
+         */
+        public void exitFullImmersion();
+    }
+
+    class LauncherOverlayCallbacksImpl implements LauncherOverlayCallbacks {
+
+        @Override
+        public boolean canEnterFullImmersion() {
+            return mState == State.WORKSPACE;
+        }
+
+        @Override
+        public boolean enterFullImmersion() {
+            if (mState == State.WORKSPACE) {
+                // When fully immersed, disregard any touches which fall through.
+                mDragLayer.setBlockTouch(true);
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void exitFullImmersion() {
+            mDragLayer.setBlockTouch(false);
+        }
+    }
+
     protected boolean hasSettings() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.hasSettings();
+        }
         return false;
     }
 
-    public interface QSBScroller {
-        public void setScrollY(int scrollY);
-    }
 
-    public QSBScroller addToCustomContentPage(View customContent,
+    public void addToCustomContentPage(View customContent,
             CustomContentCallbacks callbacks, String description) {
         mWorkspace.addToCustomContentPage(customContent, callbacks, description);
-        return mQsbScroller;
     }
 
     // The custom content needs to offset its content to account for the QSB
@@ -1149,6 +1219,10 @@
     public void onWindowFocusChanged(boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
         mHasFocus = hasFocus;
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onWindowFocusChanged(hasFocus);
+        }
     }
 
     private boolean acceptFilter() {
@@ -1335,9 +1409,6 @@
             settingsButton.setOnTouchListener(getHapticFeedbackTouchListener());
         } else {
             settingsButton.setVisibility(View.GONE);
-            FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) widgetButton.getLayoutParams();
-            lp.gravity = Gravity.END | Gravity.TOP;
-            widgetButton.requestLayout();
         }
 
         mOverviewPanel.setAlpha(0f);
@@ -1365,6 +1436,7 @@
         dragController.addDropTarget(mWorkspace);
         if (mSearchDropTargetBar != null) {
             mSearchDropTargetBar.setup(this, dragController);
+            mSearchDropTargetBar.setQsbSearchBar(getQsbBar());
         }
 
         if (getResources().getBoolean(R.bool.debug_memory_enabled)) {
@@ -1437,7 +1509,7 @@
 
         boolean foundCellSpan = false;
 
-        ShortcutInfo info = mModel.infoFromShortcutIntent(this, data, null);
+        ShortcutInfo info = mModel.infoFromShortcutIntent(this, data);
         if (info == null) {
             return;
         }
@@ -1887,8 +1959,11 @@
             Folder openFolder = mWorkspace.getOpenFolder();
             // In all these cases, only animate if we're already on home
             mWorkspace.exitWidgetResizeMode();
+
+            boolean moveToDefaultScreen = mLauncherCallbacks != null ?
+                    mLauncherCallbacks.shouldMoveToDefaultScreenOnHomeIntent() : true;
             if (alreadyOnHome && mState == State.WORKSPACE && !mWorkspace.isTouchActive() &&
-                    openFolder == null && shouldMoveToDefaultScreenOnHomeIntent()) {
+                    openFolder == null && moveToDefaultScreen) {
                 mWorkspace.moveToDefaultScreen(true);
             }
 
@@ -1915,27 +1990,18 @@
                 mAppsCustomizeTabHost.reset();
             }
 
-            onHomeIntent();
+            if (mLauncherCallbacks != null) {
+                mLauncherCallbacks.onHomeIntent();
+            }
         }
 
         if (DEBUG_RESUME_TIME) {
             Log.d(TAG, "Time spent in onNewIntent: " + (System.currentTimeMillis() - startTime));
         }
-    }
 
-    /**
-     * Override point for subclasses to prevent movement to the default screen when the home
-     * button is pressed. Used (for example) in GEL, to prevent movement during a search.
-     */
-    protected boolean shouldMoveToDefaultScreenOnHomeIntent() {
-        return true;
-    }
-
-    /**
-     * Override point for subclasses to provide custom behaviour for when a home intent is fired.
-     */
-    protected void onHomeIntent() {
-        // Do nothing
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onNewIntent(intent);
+        }
     }
 
     @Override
@@ -1987,6 +2053,10 @@
             outState.putInt("apps_customize_currentIndex", currentIndex);
         }
         outState.putSerializable(RUNTIME_STATE_VIEW_IDS, mItemIdToViewId);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onSaveInstanceState(outState);
+        }
     }
 
     @Override
@@ -2034,8 +2104,11 @@
         mWorkspace = null;
         mDragController = null;
 
-        PackageInstallerCompat.getInstance(this).onStop();
         LauncherAnimUtils.onDestroyActivity();
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onDestroy();
+        }
     }
 
     public DragController getDragController() {
@@ -2089,6 +2162,11 @@
      */
     public boolean startSearch(String initialQuery,
             boolean selectInitialQuery, Bundle appSearchData, Rect sourceBounds) {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+            return mLauncherCallbacks.startSearch(initialQuery, selectInitialQuery, appSearchData,
+                    sourceBounds);
+        }
+
         startGlobalSearch(initialQuery, selectInitialQuery,
                 appSearchData, sourceBounds);
         return false;
@@ -2115,7 +2193,7 @@
         } else {
             appSearchData = new Bundle(appSearchData);
         }
-        // Set source to package name of app that starts global search, if not set already.
+        // Set source to package name of app that starts global search if not set already.
         if (!appSearchData.containsKey("source")) {
             appSearchData.putString("source", getPackageName());
         }
@@ -2153,6 +2231,10 @@
                 showWorkspace(true);
             }
         }
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.onPrepareOptionsMenu(menu);
+        }
+
         return false;
     }
 
@@ -2187,7 +2269,11 @@
         }
     }
 
-    protected void onWorkspaceLockedChanged() { }
+    protected void onWorkspaceLockedChanged() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onWorkspaceLockedChanged();
+        }
+    }
 
     private void resetAddInfo() {
         mPendingAddInfo.container = ItemInfo.NO_ID;
@@ -2349,6 +2435,9 @@
     }
 
     protected ComponentName getWallpaperPickerComponent() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.getWallpaperPickerComponent();
+        }
         return new ComponentName(getPackageName(), LauncherWallpaperPickerActivity.class.getName());
     }
 
@@ -2369,7 +2458,7 @@
                 case KeyEvent.KEYCODE_HOME:
                     return true;
                 case KeyEvent.KEYCODE_VOLUME_DOWN:
-                    if (isPropertyEnabled(DUMP_STATE_PROPERTY)) {
+                    if (Utilities.isPropertyEnabled(DUMP_STATE_PROPERTY)) {
                         dumpState();
                         return true;
                     }
@@ -2387,6 +2476,10 @@
 
     @Override
     public void onBackPressed() {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.handleBackPressed()) {
+            return;
+        }
+
         if (isAllAppsVisible()) {
             if (mAppsCustomizeContent.getContentType() ==
                     AppsCustomizePagedView.ContentType.Applications) {
@@ -2469,6 +2562,9 @@
 
     public void onClickPagedViewIcon(View v) {
         startAppShortcutOrInfoActivity(v);
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickPagedViewIcon(v);
+        }
     }
 
     public boolean onTouch(View v, MotionEvent event) {
@@ -2479,6 +2575,11 @@
      * Event handler for the app widget view which has not fully restored.
      */
     public void onClickPendingWidget(final PendingAppWidgetHostView v) {
+        if (mIsSafeModeEnabled) {
+            Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();
+            return;
+        }
+
         final LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) v.getTag();
         if (v.isReadyForClickSetup()) {
             int widgetId = info.appWidgetId;
@@ -2508,46 +2609,6 @@
     }
 
     /**
-     * Event handler for the search button
-     *
-     * @param v The view that was clicked.
-     */
-    public void onClickSearchButton(View v) {
-        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-
-        onSearchRequested();
-    }
-
-    /**
-     * Event handler for the voice button
-     *
-     * @param v The view that was clicked.
-     */
-    public void onClickVoiceButton(View v) {
-        v.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-
-        startVoice();
-    }
-
-    public void startVoice() {
-        try {
-            final SearchManager searchManager =
-                    (SearchManager) getSystemService(Context.SEARCH_SERVICE);
-            ComponentName activityName = searchManager.getGlobalSearchActivity();
-            Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            if (activityName != null) {
-                intent.setPackage(activityName.getPackageName());
-            }
-            startActivity(null, intent, "onClickVoiceButton");
-        } catch (ActivityNotFoundException e) {
-            Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            startActivitySafely(null, intent, "onClickVoiceButton");
-        }
-    }
-
-    /**
      * Event handler for the "grid" button that appears on the home screen, which
      * enters all apps mode.
      *
@@ -2560,11 +2621,14 @@
         } else {
             showAllApps(true, AppsCustomizePagedView.ContentType.Applications, false);
         }
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickAllAppsButton(v);
+        }
     }
 
     private void showBrokenAppInstallDialog(final String packageName,
             DialogInterface.OnClickListener onSearchClickListener) {
-        new AlertDialog.Builder(new ContextThemeWrapper(this, android.R.style.Theme_DeviceDefault))
+        new AlertDialog.Builder(this)
             .setTitle(R.string.abandoned_promises_title)
             .setMessage(R.string.abandoned_promise_explanation)
             .setPositiveButton(R.string.abandoned_search, onSearchClickListener)
@@ -2593,6 +2657,16 @@
 
         // Open shortcut
         final ShortcutInfo shortcut = (ShortcutInfo) tag;
+
+        if (shortcut.isDisabled != 0) {
+            int error = R.string.activity_not_available;
+            if ((shortcut.isDisabled & ShortcutInfo.FLAG_DISABLED_SAFEMODE) != 0) {
+                error = R.string.safemode_shortcut_error;
+            }
+            Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
+            return;
+        }
+
         final Intent intent = shortcut.intent;
 
         // Check for special shortcuts
@@ -2624,6 +2698,10 @@
 
         // Start activities
         startAppShortcutOrInfoActivity(v);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickAppShortcut(v);
+        }
     }
 
     private void startAppShortcutOrInfoActivity(View v) {
@@ -2697,6 +2775,10 @@
                 }
             }
         }
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickFolderIcon(v);
+        }
     }
 
     /**
@@ -2705,7 +2787,14 @@
      */
     protected void onClickAddWidgetButton(View view) {
         if (LOGD) Log.d(TAG, "onClickAddWidgetButton");
-        showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+        if (mIsSafeModeEnabled) {
+            Toast.makeText(this, R.string.safemode_widget_error, Toast.LENGTH_SHORT).show();
+        } else {
+            showAllApps(true, AppsCustomizePagedView.ContentType.Widgets, true);
+            if (mLauncherCallbacks != null) {
+                mLauncherCallbacks.onClickAddWidgetButton(view);
+            }
+        }
     }
 
     /**
@@ -2717,6 +2806,10 @@
         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);
         pickWallpaper.setComponent(getWallpaperPickerComponent());
         startActivityForResult(pickWallpaper, REQUEST_PICK_WALLPAPER);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickWallpaperPicker(v);
+        }
     }
 
     /**
@@ -2725,6 +2818,9 @@
      */
     protected void onClickSettingsButton(View v) {
         if (LOGD) Log.d(TAG, "onClickSettingsButton");
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onClickSettingsButton(v);
+        }
     }
 
     public void onTouchDownAllAppsButton(View v) {
@@ -2752,13 +2848,27 @@
         return mHapticFeedbackTouchListener;
     }
 
-    public void onDragStarted(View view) {}
+    public void onDragStarted(View view) {
+        if (isOnCustomContent()) {
+            // Custom content screen doesn't participate in drag and drop. If on custom
+            // content screen, move to default.
+            moveWorkspaceToDefaultScreen();
+        }
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onDragStarted(view);
+        }
+    }
 
     /**
      * Called when the user stops interacting with the launcher.
      * This implies that the user is now on the homescreen and is not doing housekeeping.
      */
-    protected void onInteractionEnd() {}
+    protected void onInteractionEnd() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onInteractionEnd();
+        }
+    }
 
     /**
      * Called when the user starts interacting with the launcher.
@@ -2769,13 +2879,15 @@
      * This is a good time to stop doing things that only make sense
      * when the user is on the homescreen and not doing housekeeping.
      */
-    protected void onInteractionBegin() {}
+    protected void onInteractionBegin() {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onInteractionBegin();
+        }
+    }
 
     void startApplicationDetailsActivity(ComponentName componentName, UserHandleCompat user) {
-        String packageName = componentName.getPackageName();
         try {
             LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(this);
-            UserManagerCompat userManager = UserManagerCompat.getInstance(this);
             launcherApps.showAppDetailsForProfile(componentName, user);
         } catch (SecurityException e) {
             Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT).show();
@@ -3250,8 +3362,6 @@
             final View page = content.getPageAt(content.getCurrentPage());
             final View revealView = toView.findViewById(R.id.fake_page);
 
-            final float initialPanelAlpha = 1f;
-
             final boolean isWidgetTray = contentType == AppsCustomizePagedView.ContentType.Widgets;
             if (isWidgetTray) {
                 revealView.setBackground(res.getDrawable(R.drawable.quantum_panel_dark));
@@ -3374,6 +3484,9 @@
                     if (mSearchDropTargetBar != null) {
                         mSearchDropTargetBar.hideSearchBar(false);
                     }
+
+                    // This can hold unnecessary references to views.
+                    mStateAnimation = null;
                 }
 
             });
@@ -3399,11 +3512,7 @@
                         for (int i = 0; i < layerViews.size(); i++) {
                             View v = layerViews.get(i);
                             if (v != null) {
-                                boolean attached = true;
-                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-                                    attached = v.isAttachedToWindow();
-                                }
-                                if (attached) v.buildLayer();
+                                if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();
                             }
                         }
                     }
@@ -3532,14 +3641,14 @@
                     yDrift = isWidgetTray ? height / 2 : allAppsToPanelDelta[1];
                     xDrift = isWidgetTray ? 0 : allAppsToPanelDelta[0];
                 } else {
-                    yDrift = 5 * height / 4;
+                    yDrift = 2 * height / 3;
                     xDrift = 0;
                 }
 
                 revealView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
                 TimeInterpolator decelerateInterpolator = material ?
                         new LogDecelerateInterpolator(100, 0) :
-                        new LogDecelerateInterpolator(30, 0);
+                        new DecelerateInterpolator(1f);
 
                 // The vertical motion of the apps panel should be delayed by one frame
                 // from the conceal animation in order to give the right feel. We correpsondingly
@@ -3563,9 +3672,9 @@
                     revealView.setAlpha(1f);
                     ObjectAnimator panelAlpha = LauncherAnimUtils.ofFloat(revealView, "alpha",
                             1f, finalAlpha);
-                    panelAlpha.setDuration(revealDuration);
-                    panelAlpha.setInterpolator(material ? decelerateInterpolator :
-                        new AccelerateInterpolator(1.5f));
+                    panelAlpha.setDuration(material ? revealDuration : 150);
+                    panelAlpha.setInterpolator(decelerateInterpolator);
+                    panelAlpha.setStartDelay(material ? 0 : itemsAlphaStagger + SINGLE_FRAME_DELAY);
                     mStateAnimation.play(panelAlpha);
                 }
 
@@ -3659,6 +3768,9 @@
                     content.setCurrentPage(content.getNextPage());
 
                     mAppsCustomizeContent.updateCurrentPageScroll();
+
+                    // This can hold unnecessary references to views.
+                    mStateAnimation = null;
                 }
             });
 
@@ -3676,11 +3788,7 @@
                         for (int i = 0; i < layerViews.size(); i++) {
                             View v = layerViews.get(i);
                             if (v != null) {
-                                boolean attached = true;
-                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
-                                    attached = v.isAttachedToWindow();
-                                }
-                                if (attached) v.buildLayer();
+                                if (Utilities.isViewAttachedToWindow(v)) v.buildLayer();
                             }
                         }
                     }
@@ -3702,8 +3810,15 @@
     @Override
     public void onTrimMemory(int level) {
         super.onTrimMemory(level);
-        if (level >= ComponentCallbacks2.TRIM_MEMORY_MODERATE) {
-            mAppsCustomizeTabHost.onTrimMemory();
+        if (level >= ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
+            // The widget preview db can result in holding onto over
+            // 3MB of memory for caching which isn't necessary.
+            SQLiteDatabase.releaseMemory();
+
+            // This clears all widget bitmaps from the widget tray
+            if (mAppsCustomizeTabHost != null) {
+                mAppsCustomizeTabHost.trimMemory();
+            }
         }
     }
 
@@ -3831,260 +3946,64 @@
         // TODO
     }
 
-    /**
-     * Hides the hotseat area.
-     */
-    void hideHotseat(boolean animated) {
-        if (!LauncherAppState.getInstance().isScreenLarge()) {
-            if (animated) {
-                if (mHotseat.getAlpha() != 0f) {
-                    int duration = 0;
-                    if (mSearchDropTargetBar != null) {
-                        duration = mSearchDropTargetBar.getTransitionOutDuration();
-                    }
-                    mHotseat.animate().alpha(0f).setDuration(duration);
-                }
-            } else {
-                mHotseat.setAlpha(0f);
-            }
-        }
-    }
-
-    /**
-     * Add an item from all apps or customize onto the given workspace screen.
-     * If layout is null, add to the current screen.
-     */
-    void addExternalItemToScreen(ItemInfo itemInfo, final CellLayout layout) {
-        if (!mWorkspace.addExternalItemToScreen(itemInfo, layout)) {
-            showOutOfSpaceMessage(isHotseatLayout(layout));
-        }
-    }
-
-    /** Maps the current orientation to an index for referencing orientation correct global icons */
-    private int getCurrentOrientationIndexForGlobalIcons() {
-        // default - 0, landscape - 1
-        switch (getResources().getConfiguration().orientation) {
-        case Configuration.ORIENTATION_LANDSCAPE:
-            return 1;
-        default:
-            return 0;
-        }
-    }
-
-    private Drawable getExternalPackageToolbarIcon(ComponentName activityName, String resourceName) {
-        try {
-            PackageManager packageManager = getPackageManager();
-            // Look for the toolbar icon specified in the activity meta-data
-            Bundle metaData = packageManager.getActivityInfo(
-                    activityName, PackageManager.GET_META_DATA).metaData;
-            if (metaData != null) {
-                int iconResId = metaData.getInt(resourceName);
-                if (iconResId != 0) {
-                    Resources res = packageManager.getResourcesForActivity(activityName);
-                    return res.getDrawable(iconResId);
-                }
-            }
-        } catch (NameNotFoundException e) {
-            // This can happen if the activity defines an invalid drawable
-            Log.w(TAG, "Failed to load toolbar icon; " + activityName.flattenToShortString() +
-                    " not found", e);
-        } catch (Resources.NotFoundException nfe) {
-            // This can happen if the activity defines an invalid drawable
-            Log.w(TAG, "Failed to load toolbar icon from " + activityName.flattenToShortString(),
-                    nfe);
-        }
-        return null;
-    }
-
-    // if successful in getting icon, return it; otherwise, set button to use default drawable
-    private Drawable.ConstantState updateTextButtonWithIconFromExternalActivity(
-            int buttonId, ComponentName activityName, int fallbackDrawableId,
-            String toolbarResourceName) {
-        Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);
-        Resources r = getResources();
-        int w = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_width);
-        int h = r.getDimensionPixelSize(R.dimen.toolbar_external_icon_height);
-
-        TextView button = (TextView) findViewById(buttonId);
-        // If we were unable to find the icon via the meta-data, use a generic one
-        if (toolbarIcon == null) {
-            toolbarIcon = r.getDrawable(fallbackDrawableId);
-            toolbarIcon.setBounds(0, 0, w, h);
-            if (button != null) {
-                button.setCompoundDrawables(toolbarIcon, null, null, null);
-            }
-            return null;
-        } else {
-            toolbarIcon.setBounds(0, 0, w, h);
-            if (button != null) {
-                button.setCompoundDrawables(toolbarIcon, null, null, null);
-            }
-            return toolbarIcon.getConstantState();
-        }
-    }
-
-    // if successful in getting icon, return it; otherwise, set button to use default drawable
-    private Drawable.ConstantState updateButtonWithIconFromExternalActivity(
-            int buttonId, ComponentName activityName, int fallbackDrawableId,
-            String toolbarResourceName) {
-        ImageView button = (ImageView) findViewById(buttonId);
-        Drawable toolbarIcon = getExternalPackageToolbarIcon(activityName, toolbarResourceName);
-
-        if (button != null) {
-            // If we were unable to find the icon via the meta-data, use a
-            // generic one
-            if (toolbarIcon == null) {
-                button.setImageResource(fallbackDrawableId);
-            } else {
-                button.setImageDrawable(toolbarIcon);
-            }
-        }
-
-        return toolbarIcon != null ? toolbarIcon.getConstantState() : null;
-
-    }
-
-    private void updateTextButtonWithDrawable(int buttonId, Drawable d) {
-        TextView button = (TextView) findViewById(buttonId);
-        button.setCompoundDrawables(d, null, null, null);
-    }
-
-    private void updateButtonWithDrawable(int buttonId, Drawable.ConstantState d) {
-        ImageView button = (ImageView) findViewById(buttonId);
-        button.setImageDrawable(d.newDrawable(getResources()));
-    }
-
-    private void invalidatePressedFocusedStates(View container, View button) {
-        if (container instanceof HolographicLinearLayout) {
-            HolographicLinearLayout layout = (HolographicLinearLayout) container;
-            layout.invalidatePressedFocusedStates();
-        } else if (button instanceof HolographicImageView) {
-            HolographicImageView view = (HolographicImageView) button;
-            view.invalidatePressedFocusedStates();
-        }
+    protected void disableVoiceButtonProxy(boolean disable) {
+        // NO-OP
     }
 
     public View getQsbBar() {
+        if (mLauncherCallbacks != null && mLauncherCallbacks.providesSearch()) {
+            return mLauncherCallbacks.getQsbBar();
+        }
+
         if (mQsb == null) {
-            mQsb = mInflater.inflate(R.layout.qsb, mSearchDropTargetBar, false);
-            mSearchDropTargetBar.addView(mQsb);
+            AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(this);
+            if (searchProvider == null) {
+                return null;
+            }
+
+            Bundle opts = new Bundle();
+            opts.putInt(AppWidgetManager.OPTION_APPWIDGET_HOST_CATEGORY,
+                    AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX);
+
+            SharedPreferences sp = getSharedPreferences(
+                    LauncherAppState.getSharedPreferencesKey(), MODE_PRIVATE);
+            int widgetId = sp.getInt(QSB_WIDGET_ID, -1);
+            AppWidgetProviderInfo widgetInfo = mAppWidgetManager.getAppWidgetInfo(widgetId);
+            if (!searchProvider.provider.flattenToString().equals(
+                    sp.getString(QSB_WIDGET_PROVIDER, null))
+                    || (widgetInfo == null)
+                    || !widgetInfo.provider.equals(searchProvider.provider)) {
+                // A valid widget is not already bound.
+                if (widgetId > -1) {
+                    mAppWidgetHost.deleteAppWidgetId(widgetId);
+                    widgetId = -1;
+                }
+
+                // Try to bind a new widget
+                widgetId = mAppWidgetHost.allocateAppWidgetId();
+
+                if (!AppWidgetManagerCompat.getInstance(this)
+                        .bindAppWidgetIdIfAllowed(widgetId, searchProvider, opts)) {
+                    mAppWidgetHost.deleteAppWidgetId(widgetId);
+                    widgetId = -1;
+                }
+
+                sp.edit()
+                    .putInt(QSB_WIDGET_ID, widgetId)
+                    .putString(QSB_WIDGET_PROVIDER, searchProvider.provider.flattenToString())
+                    .commit();
+            }
+
+            if (widgetId != -1) {
+                mQsb = mAppWidgetHost.createView(this, widgetId, searchProvider);
+                mQsb.updateAppWidgetOptions(opts);
+                mQsb.setPadding(0, 0, 0, 0);
+                mSearchDropTargetBar.addView(mQsb);
+            }
         }
         return mQsb;
     }
 
-    protected boolean updateGlobalSearchIcon() {
-        final View searchButtonContainer = findViewById(R.id.search_button_container);
-        final ImageView searchButton = (ImageView) findViewById(R.id.search_button);
-        final View voiceButtonContainer = findViewById(R.id.voice_button_container);
-        final View voiceButton = findViewById(R.id.voice_button);
-
-        final SearchManager searchManager =
-                (SearchManager) getSystemService(Context.SEARCH_SERVICE);
-        ComponentName activityName = searchManager.getGlobalSearchActivity();
-        if (activityName != null) {
-            int coi = getCurrentOrientationIndexForGlobalIcons();
-            sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
-                    R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,
-                    TOOLBAR_SEARCH_ICON_METADATA_NAME);
-            if (sGlobalSearchIcon[coi] == null) {
-                sGlobalSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
-                        R.id.search_button, activityName, R.drawable.ic_home_search_normal_holo,
-                        TOOLBAR_ICON_METADATA_NAME);
-            }
-
-            if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.VISIBLE);
-            searchButton.setVisibility(View.VISIBLE);
-            invalidatePressedFocusedStates(searchButtonContainer, searchButton);
-            return true;
-        } else {
-            // We disable both search and voice search when there is no global search provider
-            if (searchButtonContainer != null) searchButtonContainer.setVisibility(View.GONE);
-            if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
-            if (searchButton != null) searchButton.setVisibility(View.GONE);
-            if (voiceButton != null) voiceButton.setVisibility(View.GONE);
-            updateVoiceButtonProxyVisible(false);
-            return false;
-        }
-    }
-
-    protected void updateGlobalSearchIcon(Drawable.ConstantState d) {
-        final View searchButtonContainer = findViewById(R.id.search_button_container);
-        final View searchButton = (ImageView) findViewById(R.id.search_button);
-        updateButtonWithDrawable(R.id.search_button, d);
-        invalidatePressedFocusedStates(searchButtonContainer, searchButton);
-    }
-
-    protected boolean updateVoiceSearchIcon(boolean searchVisible) {
-        final View voiceButtonContainer = findViewById(R.id.voice_button_container);
-        final View voiceButton = findViewById(R.id.voice_button);
-
-        // We only show/update the voice search icon if the search icon is enabled as well
-        final SearchManager searchManager =
-                (SearchManager) getSystemService(Context.SEARCH_SERVICE);
-        ComponentName globalSearchActivity = searchManager.getGlobalSearchActivity();
-
-        ComponentName activityName = null;
-        if (globalSearchActivity != null) {
-            // Check if the global search activity handles voice search
-            Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
-            intent.setPackage(globalSearchActivity.getPackageName());
-            activityName = intent.resolveActivity(getPackageManager());
-        }
-
-        if (activityName == null) {
-            // Fallback: check if an activity other than the global search activity
-            // resolves this
-            Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
-            activityName = intent.resolveActivity(getPackageManager());
-        }
-        if (searchVisible && activityName != null) {
-            int coi = getCurrentOrientationIndexForGlobalIcons();
-            sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
-                    R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,
-                    TOOLBAR_VOICE_SEARCH_ICON_METADATA_NAME);
-            if (sVoiceSearchIcon[coi] == null) {
-                sVoiceSearchIcon[coi] = updateButtonWithIconFromExternalActivity(
-                        R.id.voice_button, activityName, R.drawable.ic_home_voice_search_holo,
-                        TOOLBAR_ICON_METADATA_NAME);
-            }
-            if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.VISIBLE);
-            voiceButton.setVisibility(View.VISIBLE);
-            updateVoiceButtonProxyVisible(false);
-            invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);
-            return true;
-        } else {
-            if (voiceButtonContainer != null) voiceButtonContainer.setVisibility(View.GONE);
-            if (voiceButton != null) voiceButton.setVisibility(View.GONE);
-            updateVoiceButtonProxyVisible(false);
-            return false;
-        }
-    }
-
-    protected void updateVoiceSearchIcon(Drawable.ConstantState d) {
-        final View voiceButtonContainer = findViewById(R.id.voice_button_container);
-        final View voiceButton = findViewById(R.id.voice_button);
-        updateButtonWithDrawable(R.id.voice_button, d);
-        invalidatePressedFocusedStates(voiceButtonContainer, voiceButton);
-    }
-
-    public void updateVoiceButtonProxyVisible(boolean forceDisableVoiceButtonProxy) {
-        final View voiceButtonProxy = findViewById(R.id.voice_button_proxy);
-        if (voiceButtonProxy != null) {
-            boolean visible = !forceDisableVoiceButtonProxy &&
-                    mWorkspace.shouldVoiceButtonProxyBeVisible();
-            voiceButtonProxy.setVisibility(visible ? View.VISIBLE : View.GONE);
-            voiceButtonProxy.bringToFront();
-        }
-    }
-
-    /**
-     * This is an overrid eot disable the voice button proxy.  If disabled is true, then the voice button proxy
-     * will be hidden regardless of what shouldVoiceButtonProxyBeVisible() returns.
-     */
-    public void disableVoiceButtonProxy(boolean disabled) {
-        updateVoiceButtonProxyVisible(disabled);
-    }
-
     @Override
     public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
         final boolean result = super.dispatchPopulateAccessibilityEvent(event);
@@ -4455,8 +4374,9 @@
         final Workspace workspace = mWorkspace;
 
         AppWidgetProviderInfo appWidgetInfo;
-        if (((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0) &&
-                ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {
+        if (!mIsSafeModeEnabled
+                && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY) == 0)
+                && ((item.restoreStatus & LauncherAppWidgetInfo.FLAG_ID_NOT_VALID) != 0)) {
 
             appWidgetInfo = mModel.findAppWidgetProviderInfoWithComponent(this, item.providerName);
             if (appWidgetInfo == null) {
@@ -4506,7 +4426,7 @@
             LauncherModel.updateItemInDatabase(this, item);
         }
 
-        if (item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
+        if (!mIsSafeModeEnabled && item.restoreStatus == LauncherAppWidgetInfo.RESTORE_COMPLETED) {
             final int appWidgetId = item.appWidgetId;
             appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
             if (DEBUG_WIDGETS) {
@@ -4516,7 +4436,8 @@
             item.hostView = mAppWidgetHost.createView(this, appWidgetId, appWidgetInfo);
         } else {
             appWidgetInfo = null;
-            PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item);
+            PendingAppWidgetHostView view = new PendingAppWidgetHostView(this, item,
+                    mIsSafeModeEnabled);
             view.updateIcon(mIconCache);
             item.hostView = view;
             item.hostView.updateAppWidget(null);
@@ -4610,7 +4531,10 @@
             mIntentsOnWorkspaceFromUpgradePath = mWorkspace.getUniqueComponents(true, null);
         }
         PackageInstallerCompat.getInstance(this).onFinishBind();
-        mModel.recheckRestoredItems(this);
+
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.finishBindingItems(upgradePath);
+        }
     }
 
     private void sendLoadingCompleteBroadcastIfNecessary() {
@@ -4658,13 +4582,15 @@
                 getDeviceProfile().getSearchBarBounds();
     }
 
-    @Override
     public void bindSearchablesChanged() {
-        boolean searchVisible = updateGlobalSearchIcon();
-        boolean voiceVisible = updateVoiceSearchIcon(searchVisible);
-        if (mSearchDropTargetBar != null) {
-            mSearchDropTargetBar.onSearchPackagesChanged(searchVisible, voiceVisible);
+        if (mSearchDropTargetBar == null) {
+            return;
         }
+        if (mQsb != null) {
+            mSearchDropTargetBar.removeView(mQsb);
+            mQsb = null;
+        }
+        mSearchDropTargetBar.setQsbSearchBar(getQsbBar());
     }
 
     /**
@@ -4692,6 +4618,9 @@
                         LauncherModel.getSortedWidgetsAndShortcuts(this));
             }
         }
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.bindAllApplications(apps);
+        }
     }
 
     /**
@@ -4709,31 +4638,54 @@
             return;
         }
 
-        if (mWorkspace != null) {
-            mWorkspace.updateShortcutsAndWidgets(apps);
-        }
-
         if (!LauncherAppState.isDisableAllApps() &&
                 mAppsCustomizeContent != null) {
             mAppsCustomizeContent.updateApps(apps);
         }
     }
 
-    /**
-     * Packages were restored
-     */
-    public void bindAppsRestored(final ArrayList<AppInfo> apps) {
+    @Override
+    public void bindWidgetsRestored(final ArrayList<LauncherAppWidgetInfo> widgets) {
         Runnable r = new Runnable() {
             public void run() {
-                bindAppsRestored(apps);
+                bindWidgetsRestored(widgets);
+            }
+        };
+        if (waitUntilResume(r)) {
+            return;
+        }
+        mWorkspace.widgetsRestored(widgets);
+    }
+
+    /**
+     * Some shortcuts were updated in the background.
+     *
+     * Implementation of the method from LauncherModel.Callbacks.
+     */
+    @Override
+    public void bindShortcutsChanged(final ArrayList<ShortcutInfo> updated,
+            final ArrayList<ShortcutInfo> removed, final UserHandleCompat user) {
+        Runnable r = new Runnable() {
+            public void run() {
+                bindShortcutsChanged(updated, removed, user);
             }
         };
         if (waitUntilResume(r)) {
             return;
         }
 
-        if (mWorkspace != null) {
-            mWorkspace.updateShortcutsAndWidgets(apps);
+        if (!updated.isEmpty()) {
+            mWorkspace.updateShortcuts(updated);
+        }
+
+        if (!removed.isEmpty()) {
+            HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();
+            for (ShortcutInfo si : removed) {
+                removedComponents.add(si.getTargetComponent());
+            }
+            mWorkspace.removeItemsByComponentName(removedComponents, user);
+            // Notify the drag controller
+            mDragController.onAppsRemoved(new ArrayList<String>(), removedComponents);
         }
     }
 
@@ -4768,28 +4720,38 @@
      * we only remove specific components from the workspace, where as
      * package-removal should clear all items by package name.
      *
+     * @param reason if non-zero, the icons are not permanently removed, rather marked as disabled.
      * Implementation of the method from LauncherModel.Callbacks.
      */
+    @Override
     public void bindComponentsRemoved(final ArrayList<String> packageNames,
-            final ArrayList<AppInfo> appInfos, final UserHandleCompat user) {
+            final ArrayList<AppInfo> appInfos, final UserHandleCompat user, final int reason) {
         Runnable r = new Runnable() {
             public void run() {
-                bindComponentsRemoved(packageNames, appInfos, user);
+                bindComponentsRemoved(packageNames, appInfos, user, reason);
             }
         };
         if (waitUntilResume(r)) {
             return;
         }
 
-        if (!packageNames.isEmpty()) {
-            mWorkspace.removeItemsByPackageName(packageNames, user);
-        }
-        if (!appInfos.isEmpty()) {
-            mWorkspace.removeItemsByApplicationInfo(appInfos, user);
-        }
+        if (reason == 0) {
+            HashSet<ComponentName> removedComponents = new HashSet<ComponentName>();
+            for (AppInfo info : appInfos) {
+                removedComponents.add(info.componentName);
+            }
+            if (!packageNames.isEmpty()) {
+                mWorkspace.removeItemsByPackageName(packageNames, user);
+            }
+            if (!removedComponents.isEmpty()) {
+                mWorkspace.removeItemsByComponentName(removedComponents, user);
+            }
+            // Notify the drag controller
+            mDragController.onAppsRemoved(packageNames, removedComponents);
 
-        // Notify the drag controller
-        mDragController.onAppsRemoved(packageNames, appInfos);
+        } else {
+            mWorkspace.disableShortcutsByPackageName(packageNames, user, reason);
+        }
 
         // Update AllApps
         if (!LauncherAppState.isDisableAllApps() &&
@@ -4852,19 +4814,14 @@
         return oriMap[(d.getRotation() + indexOffset) % 4];
     }
 
-    public boolean isRotationEnabled() {
-        boolean enableRotation = sForceEnableRotation ||
-                getResources().getBoolean(R.bool.allow_rotation);
-        return enableRotation;
-    }
     public void lockScreenOrientation() {
-        if (isRotationEnabled()) {
+        if (Utilities.isRotationEnabled(this)) {
             setRequestedOrientation(mapConfigurationOriActivityInfoOri(getResources()
                     .getConfiguration().orientation));
         }
     }
     public void unlockScreenOrientation(boolean immediate) {
-        if (isRotationEnabled()) {
+        if (Utilities.isRotationEnabled(this)) {
             if (immediate) {
                 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
             } else {
@@ -4877,16 +4834,10 @@
         }
     }
 
-    /**
-     * Called when the SearchBar hint should be changed.
-     *
-     * @param hint the hint to be displayed in the search bar.
-     */
-    protected void onSearchBarHintChanged(String hint) {
-
-    }
-
     protected boolean isLauncherPreinstalled() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.isLauncherPreinstalled();
+        }
         PackageManager pm = getPackageManager();
         try {
             ApplicationInfo ai = pm.getApplicationInfo(getComponentName().getPackageName(), 0);
@@ -4906,39 +4857,20 @@
      * when our wallpaper cropper was not yet used to set a wallpaper.
      */
     protected boolean overrideWallpaperDimensions() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.overrideWallpaperDimensions();
+        }
         return true;
     }
 
-    protected boolean shouldClingFocusHotseatApp() {
-        return false;
-    }
-    protected String getFirstRunClingSearchBarHint() {
-        return "";
-    }
-    protected String getFirstRunCustomContentHint() {
-        return "";
-    }
-    protected int getFirstRunFocusedHotseatAppDrawableId() {
-        return -1;
-    }
-    protected ComponentName getFirstRunFocusedHotseatAppComponentName() {
-        return null;
-    }
-    protected int getFirstRunFocusedHotseatAppRank() {
-        return -1;
-    }
-    protected String getFirstRunFocusedHotseatAppBubbleTitle() {
-        return "";
-    }
-    protected String getFirstRunFocusedHotseatAppBubbleDescription() {
-        return "";
-    }
-
     /**
      * To be overridden by subclasses to indicate that there is an activity to launch
      * before showing the standard launcher experience.
      */
     protected boolean hasFirstRunActivity() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.hasFirstRunActivity();
+        }
         return false;
     }
 
@@ -4946,6 +4878,9 @@
      * To be overridden by subclasses to launch any first run activity
      */
     protected Intent getFirstRunActivity() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.getFirstRunActivity();
+        }
         return null;
     }
 
@@ -4982,6 +4917,9 @@
      * screen that must be displayed and dismissed.
      */
     protected boolean hasDismissableIntroScreen() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.hasDismissableIntroScreen();
+        }
         return false;
     }
 
@@ -4989,6 +4927,9 @@
      * Full screen intro screen to be shown and dismissed before the launcher can be used.
      */
     protected View getIntroScreen() {
+        if (mLauncherCallbacks != null) {
+            return mLauncherCallbacks.getIntroScreen();
+        }
         return null;
     }
 
@@ -5007,6 +4948,9 @@
         if (introScreen != null) {
             mDragLayer.showOverlayView(introScreen);
         }
+        if (mLauncherOverlayContainer != null) {
+            mLauncherOverlayContainer.setVisibility(View.INVISIBLE);
+        }
     }
 
     public void dismissIntroScreen() {
@@ -5018,11 +4962,17 @@
                 @Override
                 public void run() {
                     mDragLayer.dismissOverlayView();
+                    if (mLauncherOverlayContainer != null) {
+                        mLauncherOverlayContainer.setVisibility(View.VISIBLE);
+                    }
                     showFirstRunClings();
                 }
             }, ACTIVITY_START_DELAY);
         } else {
             mDragLayer.dismissOverlayView();
+            if (mLauncherOverlayContainer != null) {
+                mLauncherOverlayContainer.setVisibility(View.VISIBLE);
+            }
             showFirstRunClings();
         }
         changeWallpaperVisiblity(true);
@@ -5100,6 +5050,9 @@
 
     @Override
     public void onPageSwitch(View newPage, int newPageIndex) {
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.onPageSwitch(newPage, newPageIndex);
+        }
     }
 
     /**
@@ -5131,6 +5084,9 @@
                 writer.println("  " + sDumpLogs.get(i));
             }
         }
+        if (mLauncherCallbacks != null) {
+            mLauncherCallbacks.dump(prefix, fd, writer, args);
+        }
     }
 
     public static void dumpDebugLogsToConsole() {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index 246278f..b7c45a3 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.annotation.TargetApi;
 import android.app.SearchManager;
 import android.content.ComponentName;
 import android.content.ContentResolver;
@@ -25,29 +26,34 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
+import android.graphics.Point;
+import android.os.Build;
 import android.os.Handler;
+import android.util.DisplayMetrics;
 import android.util.Log;
-
+import android.view.Display;
+import android.view.WindowManager;
 import com.android.launcher3.compat.LauncherAppsCompat;
+import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
-
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 
 public class LauncherAppState implements DeviceProfile.DeviceProfileCallbacks {
     private static final String TAG = "LauncherAppState";
-    private static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs";
 
     private static final boolean DEBUG = false;
 
     private final AppFilter mAppFilter;
     private final BuildInfo mBuildInfo;
-    private LauncherModel mModel;
-    private IconCache mIconCache;
+    private final LauncherModel mModel;
+    private final IconCache mIconCache;
+
+    private final boolean mIsScreenLarge;
+    private final float mScreenDensity;
+    private final int mLongPressTimeout = 300;
+
     private WidgetPreviewLoader.CacheDb mWidgetPreviewCacheDb;
-    private boolean mIsScreenLarge;
-    private float mScreenDensity;
-    private int mLongPressTimeout = 300;
     private boolean mWallpaperChangedSinceLastCheck;
 
     private static WeakReference<LauncherProvider> sLauncherProvider;
@@ -135,6 +141,7 @@
         sContext.unregisterReceiver(mModel);
         final LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(sContext);
         launcherApps.removeOnAppsChangedCallback(mModel);
+        PackageInstallerCompat.getInstance(sContext).onStop();
 
         ContentResolver resolver = sContext.getContentResolver();
         resolver.unregisterContentObserver(mFavoritesObserver);
@@ -154,9 +161,6 @@
     };
 
     LauncherModel setLauncher(Launcher launcher) {
-        if (mModel == null) {
-            throw new IllegalStateException("setLauncher() called before init()");
-        }
         mModel.initialize(launcher);
         return mModel;
     }
@@ -186,26 +190,48 @@
     }
 
     public static String getSharedPreferencesKey() {
-        return SHARED_PREFERENCES_KEY;
+        return LauncherFiles.SHARED_PREFERENCES_KEY;
     }
 
-    DeviceProfile initDynamicGrid(Context context, int minWidth, int minHeight,
-                                  int width, int height,
-                                  int availableWidth, int availableHeight) {
-        if (mDynamicGrid == null) {
-            mDynamicGrid = new DynamicGrid(context,
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+    DeviceProfile initDynamicGrid(Context context) {
+        mDynamicGrid = createDynamicGrid(context, mDynamicGrid);
+        mDynamicGrid.getDeviceProfile().addCallback(this);
+        return mDynamicGrid.getDeviceProfile();
+    }
+
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+    static DynamicGrid createDynamicGrid(Context context, DynamicGrid dynamicGrid) {
+        // Determine the dynamic grid properties
+        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+        Display display = wm.getDefaultDisplay();
+
+        Point realSize = new Point();
+        display.getRealSize(realSize);
+        DisplayMetrics dm = new DisplayMetrics();
+        display.getMetrics(dm);
+
+        if (dynamicGrid == null) {
+            Point smallestSize = new Point();
+            Point largestSize = new Point();
+            display.getCurrentSizeRange(smallestSize, largestSize);
+
+            dynamicGrid = new DynamicGrid(context,
                     context.getResources(),
-                    minWidth, minHeight, width, height,
-                    availableWidth, availableHeight);
-            mDynamicGrid.getDeviceProfile().addCallback(this);
+                    Math.min(smallestSize.x, smallestSize.y),
+                    Math.min(largestSize.x, largestSize.y),
+                    realSize.x, realSize.y,
+                    dm.widthPixels, dm.heightPixels);
         }
 
         // Update the icon size
-        DeviceProfile grid = mDynamicGrid.getDeviceProfile();
-        grid.updateFromConfiguration(context, context.getResources(), width, height,
-                availableWidth, availableHeight);
-        return grid;
+        DeviceProfile grid = dynamicGrid.getDeviceProfile();
+        grid.updateFromConfiguration(context, context.getResources(),
+                realSize.x, realSize.y,
+                dm.widthPixels, dm.heightPixels);
+        return dynamicGrid;
     }
+
     public DynamicGrid getDynamicGrid() {
         return mDynamicGrid;
     }
@@ -250,7 +276,7 @@
     public static boolean isDisableAllApps() {
         // Returns false on non-dogfood builds.
         return getInstance().mBuildInfo.isDogfoodBuild() &&
-                Launcher.isPropertyEnabled(Launcher.DISABLE_ALL_APPS_PROPERTY);
+                Utilities.isPropertyEnabled(Launcher.DISABLE_ALL_APPS_PROPERTY);
     }
 
     public static boolean isDogfoodBuild() {
diff --git a/src/com/android/launcher3/LauncherBackupAgentHelper.java b/src/com/android/launcher3/LauncherBackupAgentHelper.java
index c20c693..3868a57 100644
--- a/src/com/android/launcher3/LauncherBackupAgentHelper.java
+++ b/src/com/android/launcher3/LauncherBackupAgentHelper.java
@@ -22,7 +22,6 @@
 import android.content.Context;
 import android.database.Cursor;
 import android.os.ParcelFileDescriptor;
-import android.provider.Settings;
 import android.util.Log;
 
 import java.io.IOException;
@@ -30,13 +29,14 @@
 public class LauncherBackupAgentHelper extends BackupAgentHelper {
 
     private static final String TAG = "LauncherBackupAgentHelper";
+
+    private static final String LAUNCHER_DATA_PREFIX = "L";
+
     static final boolean VERBOSE = true;
     static final boolean DEBUG = false;
 
     private static BackupManager sBackupManager;
 
-    protected static final String SETTING_RESTORE_ENABLED = "launcher_restore_enabled";
-
     /**
      * Notify the backup manager that out database is dirty.
      *
@@ -51,42 +51,46 @@
         sBackupManager.dataChanged();
     }
 
-    @Override
-    public void onDestroy() {
-        // There is only one process accessing this preference file, but the restore
-        // modifies the file outside the normal codepaths, so it looks like another
-        // process.  This forces a reload of the file, in case this process persists.
-        String spKey = LauncherAppState.getSharedPreferencesKey();
-        getSharedPreferences(spKey, Context.MODE_MULTI_PROCESS);
-        super.onDestroy();
-    }
+    private LauncherBackupHelper mHelper;
 
     @Override
     public void onCreate() {
-        boolean restoreEnabled = 0 != Settings.Secure.getInt(
-                getContentResolver(), SETTING_RESTORE_ENABLED, 1);
-        if (VERBOSE) Log.v(TAG, "restore is " + (restoreEnabled ? "enabled" : "disabled"));
-
-        addHelper(LauncherBackupHelper.LAUNCHER_PREFS_PREFIX,
-                new LauncherPreferencesBackupHelper(this,
-                        LauncherAppState.getSharedPreferencesKey(),
-                        restoreEnabled));
-        addHelper(LauncherBackupHelper.LAUNCHER_PREFIX,
-                new LauncherBackupHelper(this, restoreEnabled));
+        super.onCreate();
+        mHelper = new LauncherBackupHelper(this);
+        addHelper(LAUNCHER_DATA_PREFIX, mHelper);
     }
 
     @Override
     public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
             throws IOException {
-        super.onRestore(data, appVersionCode, newState);
+        if (!Utilities.isLmpOrAbove()) {
+            // No restore for old devices.
+            Log.i(TAG, "You shall not pass!!!");
+            Log.d(TAG, "Restore is only supported on devices running Lollipop and above.");
+            return;
+        }
 
-        // If no favorite was migrated, clear the data and start fresh.
-        final Cursor c = getContentResolver().query(
-                LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, null, null, null, null);
-        boolean hasData = c.moveToNext();
-        c.close();
+        // Clear dB before restore
+        LauncherAppState.getLauncherProvider().createEmptyDB();
 
-        if (!hasData) {
+        boolean hasData;
+        try {
+            super.onRestore(data, appVersionCode, newState);
+            // If no favorite was migrated, clear the data and start fresh.
+            final Cursor c = getContentResolver().query(
+                    LauncherSettings.Favorites.CONTENT_URI_NO_NOTIFICATION, null, null, null, null);
+            hasData = c.moveToNext();
+            c.close();
+        } catch (Exception e) {
+            // If the restore fails, we should do a fresh start.
+            Log.e(TAG, "Restore failed", e);
+            hasData = false;
+        }
+
+        if (hasData && mHelper.restoreSuccessful) {
+            LauncherAppState.getLauncherProvider().clearFlagEmptyDbCreated();
+            LauncherClings.synchonouslyMarkFirstRunClingDismissed(this);
+        } else {
             if (VERBOSE) Log.v(TAG, "Nothing was restored, clearing DB");
             LauncherAppState.getLauncherProvider().createEmptyDB();
         }
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index 201f3e9..4374347 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -15,22 +15,6 @@
  */
 package com.android.launcher3;
 
-import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
-import com.google.protobuf.nano.MessageNano;
-
-import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.LauncherSettings.WorkspaceScreens;
-import com.android.launcher3.backup.BackupProtos;
-import com.android.launcher3.backup.BackupProtos.CheckedMessage;
-import com.android.launcher3.backup.BackupProtos.Favorite;
-import com.android.launcher3.backup.BackupProtos.Journal;
-import com.android.launcher3.backup.BackupProtos.Key;
-import com.android.launcher3.backup.BackupProtos.Resource;
-import com.android.launcher3.backup.BackupProtos.Screen;
-import com.android.launcher3.backup.BackupProtos.Widget;
-import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.compat.UserHandleCompat;
-
 import android.app.backup.BackupDataInputStream;
 import android.app.backup.BackupDataOutput;
 import android.app.backup.BackupHelper;
@@ -42,6 +26,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -51,6 +36,22 @@
 import android.util.Base64;
 import android.util.Log;
 
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.WorkspaceScreens;
+import com.android.launcher3.backup.BackupProtos;
+import com.android.launcher3.backup.BackupProtos.CheckedMessage;
+import com.android.launcher3.backup.BackupProtos.DeviceProfieData;
+import com.android.launcher3.backup.BackupProtos.Favorite;
+import com.android.launcher3.backup.BackupProtos.Journal;
+import com.android.launcher3.backup.BackupProtos.Key;
+import com.android.launcher3.backup.BackupProtos.Resource;
+import com.android.launcher3.backup.BackupProtos.Screen;
+import com.android.launcher3.backup.BackupProtos.Widget;
+import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
+import com.google.protobuf.nano.MessageNano;
+
 import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -60,57 +61,53 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.zip.CRC32;
 
 /**
  * Persist the launcher home state across calamities.
  */
 public class LauncherBackupHelper implements BackupHelper {
-
     private static final String TAG = "LauncherBackupHelper";
     private static final boolean VERBOSE = LauncherBackupAgentHelper.VERBOSE;
     private static final boolean DEBUG = LauncherBackupAgentHelper.DEBUG;
-    private static final boolean DEBUG_PAYLOAD = false;
 
+    private static final int BACKUP_VERSION = 2;
     private static final int MAX_JOURNAL_SIZE = 1000000;
 
+    // Journal key is such that it is always smaller than any dynamically generated
+    // key (any Base64 encoded string).
+    private static final String JOURNAL_KEY = "#";
+
     /** icons are large, dribble them out */
     private static final int MAX_ICONS_PER_PASS = 10;
 
     /** widgets contain previews, which are very large, dribble them out */
     private static final int MAX_WIDGETS_PER_PASS = 5;
 
-    public static final int IMAGE_COMPRESSION_QUALITY = 75;
-
-    public static final String LAUNCHER_PREFIX = "L";
-
-    public static final String LAUNCHER_PREFS_PREFIX = "LP";
+    private static final int IMAGE_COMPRESSION_QUALITY = 75;
 
     private static final Bitmap.CompressFormat IMAGE_FORMAT =
             android.graphics.Bitmap.CompressFormat.PNG;
 
-    private static BackupManager sBackupManager;
-
     private static final String[] FAVORITE_PROJECTION = {
-            Favorites._ID,                     // 0
-            Favorites.MODIFIED,                // 1
-            Favorites.INTENT,                  // 2
-            Favorites.APPWIDGET_PROVIDER,      // 3
-            Favorites.APPWIDGET_ID,            // 4
-            Favorites.CELLX,                   // 5
-            Favorites.CELLY,                   // 6
-            Favorites.CONTAINER,               // 7
-            Favorites.ICON,                    // 8
-            Favorites.ICON_PACKAGE,            // 9
-            Favorites.ICON_RESOURCE,           // 10
-            Favorites.ICON_TYPE,               // 11
-            Favorites.ITEM_TYPE,               // 12
-            Favorites.SCREEN,                  // 13
-            Favorites.SPANX,                   // 14
-            Favorites.SPANY,                   // 15
-            Favorites.TITLE,                   // 16
-            Favorites.PROFILE_ID,              // 17
+        Favorites._ID,                     // 0
+        Favorites.MODIFIED,                // 1
+        Favorites.INTENT,                  // 2
+        Favorites.APPWIDGET_PROVIDER,      // 3
+        Favorites.APPWIDGET_ID,            // 4
+        Favorites.CELLX,                   // 5
+        Favorites.CELLY,                   // 6
+        Favorites.CONTAINER,               // 7
+        Favorites.ICON,                    // 8
+        Favorites.ICON_PACKAGE,            // 9
+        Favorites.ICON_RESOURCE,           // 10
+        Favorites.ICON_TYPE,               // 11
+        Favorites.ITEM_TYPE,               // 12
+        Favorites.SCREEN,                  // 13
+        Favorites.SPANX,                   // 14
+        Favorites.SPANY,                   // 15
+        Favorites.TITLE,                   // 16
+        Favorites.PROFILE_ID,              // 17
     };
 
     private static final int ID_INDEX = 0;
@@ -130,37 +127,50 @@
     private static final int SPANX_INDEX = 14;
     private static final int SPANY_INDEX = 15;
     private static final int TITLE_INDEX = 16;
-    private static final int PROFILE_ID_INDEX = 17;
 
     private static final String[] SCREEN_PROJECTION = {
-            WorkspaceScreens._ID,              // 0
-            WorkspaceScreens.MODIFIED,         // 1
-            WorkspaceScreens.SCREEN_RANK       // 2
+        WorkspaceScreens._ID,              // 0
+        WorkspaceScreens.MODIFIED,         // 1
+        WorkspaceScreens.SCREEN_RANK       // 2
     };
 
     private static final int SCREEN_RANK_INDEX = 2;
 
-    private static IconCache mIconCache;
-
     private final Context mContext;
-
-    private final boolean mRestoreEnabled;
-
-    private HashMap<ComponentName, AppWidgetProviderInfo> mWidgetMap;
-
+    private final HashSet<String> mExistingKeys;
     private final ArrayList<Key> mKeys;
 
-    public LauncherBackupHelper(Context context, boolean restoreEnabled) {
+    private IconCache mIconCache;
+    private BackupManager mBackupManager;
+    private HashMap<ComponentName, AppWidgetProviderInfo> mWidgetMap;
+    private byte[] mBuffer = new byte[512];
+    private long mLastBackupRestoreTime;
+
+    private DeviceProfieData mCurrentProfile;
+    boolean restoreSuccessful;
+
+    public LauncherBackupHelper(Context context) {
         mContext = context;
-        mRestoreEnabled = restoreEnabled;
+        mExistingKeys = new HashSet<String>();
         mKeys = new ArrayList<Key>();
+        restoreSuccessful = true;
     }
 
     private void dataChanged() {
-        if (sBackupManager == null) {
-            sBackupManager = new BackupManager(mContext);
+        if (mBackupManager == null) {
+            mBackupManager = new BackupManager(mContext);
         }
-        sBackupManager.dataChanged();
+        mBackupManager.dataChanged();
+    }
+
+    private void applyJournal(Journal journal) {
+        mLastBackupRestoreTime = journal.t;
+        mExistingKeys.clear();
+        if (journal.key != null) {
+            for (Key key : journal.key) {
+                mExistingKeys.add(keyToBackupKey(key));
+            }
+        }
     }
 
     /**
@@ -173,7 +183,6 @@
      * @param oldState notes from the last backup
      * @param data incremental key/value pairs to persist off-device
      * @param newState notes for the next backup
-     * @throws IOException
      */
     @Override
     public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
@@ -181,86 +190,149 @@
         if (VERBOSE) Log.v(TAG, "onBackup");
 
         Journal in = readJournal(oldState);
-        Journal out = new Journal();
+        if (!launcherIsReady()) {
+            // Perform backup later.
+            writeJournal(newState, in);
+            return;
+        }
+        Log.v(TAG, "lastBackupTime = " + in.t);
+        mKeys.clear();
+        applyJournal(in);
 
-        long lastBackupTime = in.t;
-        out.t = System.currentTimeMillis();
-        out.rows = 0;
-        out.bytes = 0;
+        // Record the time before performing backup so that entries edited while the backup
+        // was going on, do not get missed in next backup.
+        long newBackupTime = System.currentTimeMillis();
 
-        Log.v(TAG, "lastBackupTime = " + lastBackupTime);
+        try {
+            backupFavorites(data);
+            backupScreens(data);
+            backupIcons(data);
+            backupWidgets(data);
 
-        ArrayList<Key> keys = new ArrayList<Key>();
-        if (launcherIsReady()) {
-            try {
-                backupFavorites(in, data, out, keys);
-                backupScreens(in, data, out, keys);
-                backupIcons(in, data, out, keys);
-                backupWidgets(in, data, out, keys);
-            } catch (IOException e) {
-                Log.e(TAG, "launcher backup has failed", e);
+            // Delete any key which still exist in the old backup, but is not valid anymore.
+            HashSet<String> validKeys = new HashSet<String>();
+            for (Key key : mKeys) {
+                validKeys.add(keyToBackupKey(key));
             }
-            out.key = keys.toArray(new BackupProtos.Key[keys.size()]);
-        } else {
-            out = in;
+            mExistingKeys.removeAll(validKeys);
+
+            // Delete anything left in the existing keys.
+            for (String deleted: mExistingKeys) {
+                if (VERBOSE) Log.v(TAG, "dropping deleted item " + deleted);
+                data.writeEntityHeader(deleted, -1);
+            }
+
+            mExistingKeys.clear();
+            mLastBackupRestoreTime = newBackupTime;
+
+            // We store the journal at two places.
+            //   1) Storing it in newState allows us to do partial backups by comparing old state
+            //   2) Storing it in backup data allows us to validate keys during restore
+            Journal state = getCurrentStateJournal();
+            writeRowToBackup(JOURNAL_KEY, state, data);
+        } catch (IOException e) {
+            Log.e(TAG, "launcher backup has failed", e);
         }
 
-        writeJournal(newState, out);
-        Log.v(TAG, "onBackup: wrote " + out.bytes + "b in " + out.rows + " rows.");
+        writeNewStateDescription(newState);
+    }
+
+    /**
+     * @return true if the backup corresponding to oldstate can be successfully applied
+     * to this device.
+     */
+    private boolean isBackupCompatible(Journal oldState) {
+        DeviceProfieData currentProfile = getDeviceProfieData();
+
+        DeviceProfieData oldProfile = oldState.profile;
+
+        if (oldProfile == null || oldProfile.desktopCols == 0) {
+            // Profile info is not valid, ignore the check.
+            return true;
+        }
+
+        boolean isHotsetCompatible = false;
+        if (currentProfile.allappsRank >= oldProfile.hotseatCount) {
+            isHotsetCompatible = true;
+        }
+        if ((currentProfile.hotseatCount >= oldProfile.hotseatCount) &&
+                (currentProfile.allappsRank == oldProfile.allappsRank)) {
+            isHotsetCompatible = true;
+        }
+
+        return isHotsetCompatible && (currentProfile.desktopCols >= oldProfile.desktopCols)
+                && (currentProfile.desktopRows >= oldProfile.desktopRows);
     }
 
     /**
      * Restore launcher configuration from the restored data stream.
-     *
-     * <P>Keys may arrive in any order.
+     * It assumes that the keys will arrive in lexical order. So if the journal was present in the
+     * backup, it should arrive first.
      *
      * @param data the key/value pair from the server
      */
     @Override
     public void restoreEntity(BackupDataInputStream data) {
-        if (VERBOSE) Log.v(TAG, "restoreEntity");
-        byte[] buffer = new byte[512];
-            String backupKey = data.getKey();
-            int dataSize = data.size();
-            if (buffer.length < dataSize) {
-                buffer = new byte[dataSize];
-            }
-            Key key = null;
-        int bytesRead = 0;
-        try {
-            bytesRead = data.read(buffer, 0, dataSize);
-            if (DEBUG) Log.d(TAG, "read " + bytesRead + " of " + dataSize + " available");
-        } catch (IOException e) {
-            Log.e(TAG, "failed to read entity from restore data", e);
+        if (!restoreSuccessful) {
+            return;
+        }
+
+        int dataSize = data.size();
+        if (mBuffer.length < dataSize) {
+            mBuffer = new byte[dataSize];
         }
         try {
-            key = backupKeyToKey(backupKey);
+            int bytesRead = data.read(mBuffer, 0, dataSize);
+            if (DEBUG) Log.d(TAG, "read " + bytesRead + " of " + dataSize + " available");
+            String backupKey = data.getKey();
+
+            if (JOURNAL_KEY.equals(backupKey)) {
+                if (VERBOSE) Log.v(TAG, "Journal entry restored");
+                if (!mKeys.isEmpty()) {
+                    // We received the journal key after a restore key.
+                    Log.wtf(TAG, keyToBackupKey(mKeys.get(0)) + " received after " + JOURNAL_KEY);
+                    restoreSuccessful = false;
+                    return;
+                }
+
+                Journal journal = new Journal();
+                MessageNano.mergeFrom(journal, readCheckedBytes(mBuffer, dataSize));
+                applyJournal(journal);
+                restoreSuccessful = isBackupCompatible(journal);
+                return;
+            }
+
+            if (!mExistingKeys.isEmpty() && !mExistingKeys.contains(backupKey)) {
+                if (DEBUG) Log.e(TAG, "Ignoring key not present in the backup state " + backupKey);
+                return;
+            }
+            Key key = backupKeyToKey(backupKey);
             mKeys.add(key);
             switch (key.type) {
                 case Key.FAVORITE:
-                    restoreFavorite(key, buffer, dataSize, mKeys);
+                    restoreFavorite(key, mBuffer, dataSize);
                     break;
 
                 case Key.SCREEN:
-                    restoreScreen(key, buffer, dataSize, mKeys);
+                    restoreScreen(key, mBuffer, dataSize);
                     break;
 
                 case Key.ICON:
-                    restoreIcon(key, buffer, dataSize, mKeys);
+                    restoreIcon(key, mBuffer, dataSize);
                     break;
 
                 case Key.WIDGET:
-                    restoreWidget(key, buffer, dataSize, mKeys);
+                    restoreWidget(key, mBuffer, dataSize);
                     break;
 
                 default:
                     Log.w(TAG, "unknown restore entity type: " + key.type);
+                    mKeys.remove(key);
                     break;
             }
-        } catch (KeyParsingException e) {
-            Log.w(TAG, "ignoring unparsable backup key: " + backupKey);
+        } catch (IOException e) {
+            Log.w(TAG, "ignoring unparsable backup entry", e);
         }
-
     }
 
     /**
@@ -270,63 +342,76 @@
      */
     @Override
     public void writeNewStateDescription(ParcelFileDescriptor newState) {
-        // clear the output journal time, to force a full backup to
-        // will catch any changes the restore process might have made
-        Journal out = new Journal();
-        out.t = 0;
-        out.key = mKeys.toArray(new BackupProtos.Key[mKeys.size()]);
-        writeJournal(newState, out);
-        Log.v(TAG, "onRestore: read " + mKeys.size() + " rows");
-        mKeys.clear();
+        writeJournal(newState, getCurrentStateJournal());
+    }
+
+    private Journal getCurrentStateJournal() {
+        Journal journal = new Journal();
+        journal.t = mLastBackupRestoreTime;
+        journal.key = mKeys.toArray(new BackupProtos.Key[mKeys.size()]);
+        journal.appVersion = getAppVersion();
+        journal.backupVersion = BACKUP_VERSION;
+        journal.profile = getDeviceProfieData();
+        return journal;
+    }
+
+    private int getAppVersion() {
+        try {
+            return mContext.getPackageManager()
+                    .getPackageInfo(mContext.getPackageName(), 0).versionCode;
+        } catch (NameNotFoundException e) {
+            return 0;
+        }
+    }
+
+    /**
+     * @return the current device profile information.
+     */
+    private DeviceProfieData getDeviceProfieData() {
+        if (mCurrentProfile != null) {
+            return mCurrentProfile;
+        }
+        final Context applicationContext = mContext.getApplicationContext();
+        DeviceProfile profile = LauncherAppState.createDynamicGrid(applicationContext, null)
+                .getDeviceProfile();
+
+        mCurrentProfile = new DeviceProfieData();
+        mCurrentProfile.desktopRows = profile.numRows;
+        mCurrentProfile.desktopCols = profile.numColumns;
+        mCurrentProfile.hotseatCount = profile.numHotseatIcons;
+        mCurrentProfile.allappsRank = profile.hotseatAllAppsRank;
+        return mCurrentProfile;
     }
 
     /**
      * Write all modified favorites to the data stream.
      *
-     *
-     * @param in notes from last backup
      * @param data output stream for key/value pairs
-     * @param out notes about this backup
-     * @param keys keys to mark as clean in the notes for next backup
      * @throws IOException
      */
-    private void backupFavorites(Journal in, BackupDataOutput data, Journal out,
-            ArrayList<Key> keys)
-            throws IOException {
-        // read the old ID set
-        Set<String> savedIds = getSavedIdsByType(Key.FAVORITE, in);
-        if (DEBUG) Log.d(TAG, "favorite savedIds.size()=" + savedIds.size());
-
+    private void backupFavorites(BackupDataOutput data) throws IOException {
         // persist things that have changed since the last backup
         ContentResolver cr = mContext.getContentResolver();
         // Don't backup apps in other profiles for now.
         Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
                 getUserSelectionArg(), null, null);
-        Set<String> currentIds = new HashSet<String>(cursor.getCount());
         try {
             cursor.moveToPosition(-1);
             while(cursor.moveToNext()) {
                 final long id = cursor.getLong(ID_INDEX);
                 final long updateTime = cursor.getLong(ID_MODIFIED);
                 Key key = getKey(Key.FAVORITE, id);
-                keys.add(key);
+                mKeys.add(key);
                 final String backupKey = keyToBackupKey(key);
-                currentIds.add(backupKey);
-                if (!savedIds.contains(backupKey) || updateTime >= in.t) {
-                    byte[] blob = packFavorite(cursor);
-                    writeRowToBackup(key, blob, out, data);
+                if (!mExistingKeys.contains(backupKey) || updateTime >= mLastBackupRestoreTime) {
+                    writeRowToBackup(key, packFavorite(cursor), data);
                 } else {
-                    if (VERBOSE) Log.v(TAG, "favorite " + id + " was too old: " + updateTime);
+                    if (DEBUG) Log.d(TAG, "favorite already backup up: " + id);
                 }
             }
         } finally {
             cursor.close();
         }
-        if (DEBUG) Log.d(TAG, "favorite currentIds.size()=" + currentIds.size());
-
-        // these IDs must have been deleted
-        savedIds.removeAll(currentIds);
-        out.rows += removeDeletedKeysFromBackup(savedIds, data);
     }
 
     /**
@@ -337,74 +422,46 @@
      * @param key identifier for the row
      * @param buffer the serialized proto from the stream, may be larger than dataSize
      * @param dataSize the size of the proto from the stream
-     * @param keys keys to mark as clean in the notes for next backup
      */
-    private void restoreFavorite(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+    private void restoreFavorite(Key key, byte[] buffer, int dataSize) throws IOException {
         if (VERBOSE) Log.v(TAG, "unpacking favorite " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
 
-        if (!mRestoreEnabled) {
-            if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
-            return;
-        }
-
-        try {
-            ContentResolver cr = mContext.getContentResolver();
-            ContentValues values = unpackFavorite(buffer, 0, dataSize);
-            cr.insert(Favorites.CONTENT_URI_NO_NOTIFICATION, values);
-        } catch (InvalidProtocolBufferNanoException e) {
-            Log.e(TAG, "failed to decode favorite", e);
-        }
+        ContentResolver cr = mContext.getContentResolver();
+        ContentValues values = unpackFavorite(buffer, dataSize);
+        cr.insert(Favorites.CONTENT_URI_NO_NOTIFICATION, values);
     }
 
     /**
      * Write all modified screens to the data stream.
      *
-     *
-     * @param in notes from last backup
      * @param data output stream for key/value pairs
-     * @param out notes about this backup
-     * @param keys keys to mark as clean in the notes for next backup
      * @throws IOException
      */
-    private void backupScreens(Journal in, BackupDataOutput data, Journal out,
-            ArrayList<Key> keys)
-            throws IOException {
-        // read the old ID set
-        Set<String> savedIds = getSavedIdsByType(Key.SCREEN, in);
-        if (DEBUG) Log.d(TAG, "screen savedIds.size()=" + savedIds.size());
-
+    private void backupScreens(BackupDataOutput data) throws IOException {
         // persist things that have changed since the last backup
         ContentResolver cr = mContext.getContentResolver();
         Cursor cursor = cr.query(WorkspaceScreens.CONTENT_URI, SCREEN_PROJECTION,
                 null, null, null);
-        Set<String> currentIds = new HashSet<String>(cursor.getCount());
         try {
             cursor.moveToPosition(-1);
-            if (DEBUG) Log.d(TAG, "dumping screens after: " + in.t);
+            if (DEBUG) Log.d(TAG, "dumping screens after: " + mLastBackupRestoreTime);
             while(cursor.moveToNext()) {
                 final long id = cursor.getLong(ID_INDEX);
                 final long updateTime = cursor.getLong(ID_MODIFIED);
                 Key key = getKey(Key.SCREEN, id);
-                keys.add(key);
+                mKeys.add(key);
                 final String backupKey = keyToBackupKey(key);
-                currentIds.add(backupKey);
-                if (!savedIds.contains(backupKey) || updateTime >= in.t) {
-                    byte[] blob = packScreen(cursor);
-                    writeRowToBackup(key, blob, out, data);
+                if (!mExistingKeys.contains(backupKey) || updateTime >= mLastBackupRestoreTime) {
+                    writeRowToBackup(key, packScreen(cursor), data);
                 } else {
-                    if (VERBOSE) Log.v(TAG, "screen " + id + " was too old: " + updateTime);
+                    if (VERBOSE) Log.v(TAG, "screen already backup up " + id);
                 }
             }
         } finally {
             cursor.close();
         }
-        if (DEBUG) Log.d(TAG, "screen currentIds.size()=" + currentIds.size());
-
-        // these IDs must have been deleted
-        savedIds.removeAll(currentIds);
-        out.rows += removeDeletedKeysFromBackup(savedIds, data);
     }
 
     /**
@@ -415,40 +472,24 @@
      * @param key identifier for the row
      * @param buffer the serialized proto from the stream, may be larger than dataSize
      * @param dataSize the size of the proto from the stream
-     * @param keys keys to mark as clean in the notes for next backup
      */
-    private void restoreScreen(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+    private void restoreScreen(Key key, byte[] buffer, int dataSize) throws IOException {
         if (VERBOSE) Log.v(TAG, "unpacking screen " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
 
-        if (!mRestoreEnabled) {
-            if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
-            return;
-        }
-
-        try {
-            ContentResolver cr = mContext.getContentResolver();
-            ContentValues values = unpackScreen(buffer, 0, dataSize);
-            cr.insert(WorkspaceScreens.CONTENT_URI, values);
-
-        } catch (InvalidProtocolBufferNanoException e) {
-            Log.e(TAG, "failed to decode screen", e);
-        }
+        ContentResolver cr = mContext.getContentResolver();
+        ContentValues values = unpackScreen(buffer, dataSize);
+        cr.insert(WorkspaceScreens.CONTENT_URI, values);
     }
 
     /**
      * Write all the static icon resources we need to render placeholders
      * for a package that is not installed.
      *
-     * @param in notes from last backup
      * @param data output stream for key/value pairs
-     * @param out notes about this backup
-     * @param keys keys to mark as clean in the notes for next backup
-     * @throws IOException
      */
-    private void backupIcons(Journal in, BackupDataOutput data, Journal out,
-            ArrayList<Key> keys) throws IOException {
+    private void backupIcons(BackupDataOutput data) throws IOException {
         // persist icons that haven't been persisted yet
         if (!initializeIconCache()) {
             dataChanged(); // try again later
@@ -458,21 +499,14 @@
         final ContentResolver cr = mContext.getContentResolver();
         final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
         final UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
-
-        // read the old ID set
-        Set<String> savedIds = getSavedIdsByType(Key.ICON, in);
-        if (DEBUG) Log.d(TAG, "icon savedIds.size()=" + savedIds.size());
+        int backupUpIconCount = 0;
 
         // Don't backup apps in other profiles for now.
-        int startRows = out.rows;
-        if (DEBUG) Log.d(TAG, "starting here: " + startRows);
-
         String where = "(" + Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPLICATION + " OR " +
                 Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_SHORTCUT + ") AND " +
                 getUserSelectionArg();
         Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
                 where, null, null);
-        Set<String> currentIds = new HashSet<String>(cursor.getCount());
         try {
             cursor.moveToPosition(-1);
             while(cursor.moveToNext()) {
@@ -486,27 +520,26 @@
                     if (cn != null) {
                         key = getKey(Key.ICON, cn.flattenToShortString());
                         backupKey = keyToBackupKey(key);
-                        currentIds.add(backupKey);
                     } else {
                         Log.w(TAG, "empty intent on application favorite: " + id);
                     }
-                    if (savedIds.contains(backupKey)) {
-                        if (VERBOSE) Log.v(TAG, "already saved icon " + backupKey);
+                    if (mExistingKeys.contains(backupKey)) {
+                        if (DEBUG) Log.d(TAG, "already saved icon " + backupKey);
 
                         // remember that we already backed this up previously
-                        keys.add(key);
+                        mKeys.add(key);
                     } else if (backupKey != null) {
-                        if (DEBUG) Log.d(TAG, "I can count this high: " + out.rows);
-                        if ((out.rows - startRows) < MAX_ICONS_PER_PASS) {
-                            if (VERBOSE) Log.v(TAG, "saving icon " + backupKey);
+                        if (DEBUG) Log.d(TAG, "I can count this high: " + backupUpIconCount);
+                        if (backupUpIconCount < MAX_ICONS_PER_PASS) {
+                            if (DEBUG) Log.d(TAG, "saving icon " + backupKey);
                             Bitmap icon = mIconCache.getIcon(intent, myUserHandle);
-                            keys.add(key);
                             if (icon != null && !mIconCache.isDefaultIcon(icon, myUserHandle)) {
-                                byte[] blob = packIcon(dpi, icon);
-                                writeRowToBackup(key, blob, out, data);
+                                writeRowToBackup(key, packIcon(dpi, icon), data);
+                                mKeys.add(key);
+                                backupUpIconCount ++;
                             }
                         } else {
-                            if (VERBOSE) Log.d(TAG, "deferring icon backup " + backupKey);
+                            if (VERBOSE) Log.v(TAG, "deferring icon backup " + backupKey);
                             // too many icons for this pass, request another.
                             dataChanged();
                         }
@@ -521,11 +554,6 @@
         } finally {
             cursor.close();
         }
-        if (DEBUG) Log.d(TAG, "icon currentIds.size()=" + currentIds.size());
-
-        // these IDs must have been deleted
-        savedIds.removeAll(currentIds);
-        out.rows += removeDeletedKeysFromBackup(savedIds, data);
     }
 
     /**
@@ -536,55 +564,32 @@
      * @param key identifier for the row
      * @param buffer the serialized proto from the stream, may be larger than dataSize
      * @param dataSize the size of the proto from the stream
-     * @param keys keys to mark as clean in the notes for next backup
      */
-    private void restoreIcon(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+    private void restoreIcon(Key key, byte[] buffer, int dataSize) throws IOException {
         if (VERBOSE) Log.v(TAG, "unpacking icon " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
 
-        try {
-            Resource res = unpackIcon(buffer, 0, dataSize);
-            if (DEBUG) {
-                Log.d(TAG, "unpacked " + res.dpi + " dpi icon");
-            }
-            if (DEBUG_PAYLOAD) {
-                Log.d(TAG, "read " +
-                        Base64.encodeToString(res.data, 0, res.data.length,
-                                Base64.NO_WRAP));
-            }
-            Bitmap icon = BitmapFactory.decodeByteArray(res.data, 0, res.data.length);
-            if (icon == null) {
-                Log.w(TAG, "failed to unpack icon for " + key.name);
-            }
-
-            if (!mRestoreEnabled) {
-                if (VERBOSE) {
-                    Log.v(TAG, "restore not enabled: skipping database mutation");
-                }
-                return;
-            } else {
-                if (VERBOSE) Log.v(TAG, "saving restored icon as: " + key.name);
-                IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(key.name),
-                        icon, res.dpi);
-            }
-        } catch (IOException e) {
-            Log.d(TAG, "failed to save restored icon for: " + key.name, e);
+        Resource res = unpackProto(new Resource(), buffer, dataSize);
+        if (DEBUG) {
+            Log.d(TAG, "unpacked " + res.dpi + " dpi icon");
         }
+        Bitmap icon = BitmapFactory.decodeByteArray(res.data, 0, res.data.length);
+        if (icon == null) {
+            Log.w(TAG, "failed to unpack icon for " + key.name);
+        }
+        if (VERBOSE) Log.v(TAG, "saving restored icon as: " + key.name);
+        IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(key.name), icon, res.dpi);
     }
 
     /**
      * Write all the static widget resources we need to render placeholders
      * for a package that is not installed.
      *
-     * @param in notes from last backup
      * @param data output stream for key/value pairs
-     * @param out notes about this backup
-     * @param keys keys to mark as clean in the notes for next backup
      * @throws IOException
      */
-    private void backupWidgets(Journal in, BackupDataOutput data, Journal out,
-            ArrayList<Key> keys) throws IOException {
+    private void backupWidgets(BackupDataOutput data) throws IOException {
         // persist static widget info that hasn't been persisted yet
         final LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
         if (appState == null || !initializeIconCache()) {
@@ -597,18 +602,12 @@
         final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
         final DeviceProfile profile = appState.getDynamicGrid().getDeviceProfile();
         if (DEBUG) Log.d(TAG, "cellWidthPx: " + profile.cellWidthPx);
+        int backupWidgetCount = 0;
 
-        // read the old ID set
-        Set<String> savedIds = getSavedIdsByType(Key.WIDGET, in);
-        if (DEBUG) Log.d(TAG, "widgets savedIds.size()=" + savedIds.size());
-
-        int startRows = out.rows;
-        if (DEBUG) Log.d(TAG, "starting here: " + startRows);
         String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPWIDGET + " AND "
                 + getUserSelectionArg();
         Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
                 where, null, null);
-        Set<String> currentIds = new HashSet<String>(cursor.getCount());
         try {
             cursor.moveToPosition(-1);
             while(cursor.moveToNext()) {
@@ -622,27 +621,25 @@
                 if (provider != null) {
                     key = getKey(Key.WIDGET, providerName);
                     backupKey = keyToBackupKey(key);
-                    currentIds.add(backupKey);
                 } else {
                     Log.w(TAG, "empty intent on appwidget: " + id);
                 }
-                if (savedIds.contains(backupKey)) {
-                    if (VERBOSE) Log.v(TAG, "already saved widget " + backupKey);
+                if (mExistingKeys.contains(backupKey)) {
+                    if (DEBUG) Log.d(TAG, "already saved widget " + backupKey);
 
                     // remember that we already backed this up previously
-                    keys.add(key);
+                    mKeys.add(key);
                 } else if (backupKey != null) {
-                    if (DEBUG) Log.d(TAG, "I can count this high: " + out.rows);
-                    if ((out.rows - startRows) < MAX_WIDGETS_PER_PASS) {
-                        if (VERBOSE) Log.v(TAG, "saving widget " + backupKey);
+                    if (DEBUG) Log.d(TAG, "I can count this high: " + backupWidgetCount);
+                    if (backupWidgetCount < MAX_WIDGETS_PER_PASS) {
+                        if (DEBUG) Log.d(TAG, "saving widget " + backupKey);
                         previewLoader.setPreviewSize(spanX * profile.cellWidthPx,
                                 spanY * profile.cellHeightPx, widgetSpacingLayout);
-                        byte[] blob = packWidget(dpi, previewLoader, mIconCache, provider);
-                        keys.add(key);
-                        writeRowToBackup(key, blob, out, data);
-
+                        writeRowToBackup(key, packWidget(dpi, previewLoader, mIconCache, provider), data);
+                        mKeys.add(key);
+                        backupWidgetCount ++;
                     } else {
-                        if (VERBOSE) Log.d(TAG, "deferring widget backup " + backupKey);
+                        if (VERBOSE) Log.v(TAG, "deferring widget backup " + backupKey);
                         // too many widgets for this pass, request another.
                         dataChanged();
                     }
@@ -651,11 +648,6 @@
         } finally {
             cursor.close();
         }
-        if (DEBUG) Log.d(TAG, "widget currentIds.size()=" + currentIds.size());
-
-        // these IDs must have been deleted
-        savedIds.removeAll(currentIds);
-        out.rows += removeDeletedKeysFromBackup(savedIds, data);
     }
 
     /**
@@ -666,35 +658,25 @@
      * @param key identifier for the row
      * @param buffer the serialized proto from the stream, may be larger than dataSize
      * @param dataSize the size of the proto from the stream
-     * @param keys keys to mark as clean in the notes for next backup
      */
-    private void restoreWidget(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+    private void restoreWidget(Key key, byte[] buffer, int dataSize) throws IOException {
         if (VERBOSE) Log.v(TAG, "unpacking widget " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
-        try {
-            Widget widget = unpackWidget(buffer, 0, dataSize);
-            if (DEBUG) Log.d(TAG, "unpacked " + widget.provider);
-            if (widget.icon.data != null)  {
-                Bitmap icon = BitmapFactory
-                        .decodeByteArray(widget.icon.data, 0, widget.icon.data.length);
-                if (icon == null) {
-                    Log.w(TAG, "failed to unpack widget icon for " + key.name);
-                } else {
-                    IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(widget.provider),
-                            icon, widget.icon.dpi);
-                }
-            }
-
-            if (!mRestoreEnabled) {
-                if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
-                return;
+        Widget widget = unpackProto(new Widget(), buffer, dataSize);
+        if (DEBUG) Log.d(TAG, "unpacked " + widget.provider);
+        if (widget.icon.data != null)  {
+            Bitmap icon = BitmapFactory
+                    .decodeByteArray(widget.icon.data, 0, widget.icon.data.length);
+            if (icon == null) {
+                Log.w(TAG, "failed to unpack widget icon for " + key.name);
             } else {
-                // future site of widget table mutation
+                IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(widget.provider),
+                        icon, widget.icon.dpi);
             }
-        } catch (InvalidProtocolBufferNanoException e) {
-            Log.e(TAG, "failed to decode widget", e);
         }
+
+        // future site of widget table mutation
     }
 
     /** create a new key, with an integer ID.
@@ -729,42 +711,18 @@
     }
 
     /** keys need to be strings, decode and parse. */
-    private Key backupKeyToKey(String backupKey) throws KeyParsingException {
+    private Key backupKeyToKey(String backupKey) throws InvalidBackupException {
         try {
             Key key = Key.parseFrom(Base64.decode(backupKey, Base64.DEFAULT));
             if (key.checksum != checkKey(key)) {
                 key = null;
-                throw new KeyParsingException("invalid key read from stream" + backupKey);
+                throw new InvalidBackupException("invalid key read from stream" + backupKey);
             }
             return key;
         } catch (InvalidProtocolBufferNanoException e) {
-            throw new KeyParsingException(e);
+            throw new InvalidBackupException(e);
         } catch (IllegalArgumentException e) {
-            throw new KeyParsingException(e);
-        }
-    }
-
-    private String getKeyName(Key key) {
-        if (TextUtils.isEmpty(key.name)) {
-            return Long.toString(key.id);
-        } else {
-            return key.name;
-        }
-
-    }
-
-    private String geKeyType(Key key) {
-        switch (key.type) {
-            case Key.FAVORITE:
-                return "favorite";
-            case Key.SCREEN:
-                return "screen";
-            case Key.ICON:
-                return "icon";
-            case Key.WIDGET:
-                return "widget";
-            default:
-                return "anonymous";
+            throw new InvalidBackupException(e);
         }
     }
 
@@ -781,7 +739,7 @@
     }
 
     /** Serialize a Favorite for persistence, including a checksum wrapper. */
-    private byte[] packFavorite(Cursor c) {
+    private Favorite packFavorite(Cursor c) {
         Favorite favorite = new Favorite();
         favorite.id = c.getLong(ID_INDEX);
         favorite.screen = c.getInt(SCREEN_INDEX);
@@ -819,7 +777,7 @@
                 favorite.intent = intent.toUri(0);
             } catch (URISyntaxException e) {
                 Log.e(TAG, "Invalid intent", e);
-           }
+            }
         }
         favorite.itemType = c.getInt(ITEM_TYPE_INDEX);
         if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
@@ -830,16 +788,13 @@
             }
         }
 
-        return writeCheckedBytes(favorite);
+        return favorite;
     }
 
     /** Deserialize a Favorite from persistence, after verifying checksum wrapper. */
-    private ContentValues unpackFavorite(byte[] buffer, int offset, int dataSize)
-            throws InvalidProtocolBufferNanoException {
-        Favorite favorite = new Favorite();
-        MessageNano.mergeFrom(favorite, readCheckedBytes(buffer, offset, dataSize));
-        if (VERBOSE) Log.v(TAG, "unpacked favorite " + favorite.itemType + ", " +
-                (TextUtils.isEmpty(favorite.title) ? favorite.id : favorite.title));
+    private ContentValues unpackFavorite(byte[] buffer, int dataSize)
+            throws IOException {
+        Favorite favorite = unpackProto(new Favorite(), buffer, dataSize);
         ContentValues values = new ContentValues();
         values.put(Favorites._ID, favorite.id);
         values.put(Favorites.SCREEN, favorite.screen);
@@ -871,6 +826,8 @@
                 UserManagerCompat.getInstance(mContext).getSerialNumberForUser(myUserHandle);
         values.put(LauncherSettings.Favorites.PROFILE_ID, userSerialNumber);
 
+        DeviceProfieData currentProfile = getDeviceProfieData();
+
         if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
             if (!TextUtils.isEmpty(favorite.appWidgetProvider)) {
                 values.put(Favorites.APPWIDGET_PROVIDER, favorite.appWidgetProvider);
@@ -880,29 +837,48 @@
                     LauncherAppWidgetInfo.FLAG_ID_NOT_VALID |
                     LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY |
                     LauncherAppWidgetInfo.FLAG_UI_NOT_READY);
+
+            // Verify placement
+            if (((favorite.cellX + favorite.spanX) > currentProfile.desktopCols)
+                    || ((favorite.cellY + favorite.spanY) > currentProfile.desktopRows)) {
+                restoreSuccessful = false;
+                throw new InvalidBackupException("Widget not in screen bounds, aborting restore");
+            }
         } else {
             // Let LauncherModel know we've been here.
             values.put(LauncherSettings.Favorites.RESTORED, 1);
+
+            // Verify placement
+            if (favorite.container == Favorites.CONTAINER_HOTSEAT) {
+                if ((favorite.screen >= currentProfile.hotseatCount)
+                        || (favorite.screen == currentProfile.allappsRank)) {
+                    restoreSuccessful = false;
+                    throw new InvalidBackupException("Item not in hotseat bounds, aborting restore");
+                }
+            } else {
+                if ((favorite.cellX >= currentProfile.desktopCols)
+                        || (favorite.cellY >= currentProfile.desktopRows)) {
+                    restoreSuccessful = false;
+                    throw new InvalidBackupException("Item not in desktop bounds, aborting restore");
+                }
+            }
         }
 
         return values;
     }
 
     /** Serialize a Screen for persistence, including a checksum wrapper. */
-    private byte[] packScreen(Cursor c) {
+    private Screen packScreen(Cursor c) {
         Screen screen = new Screen();
         screen.id = c.getLong(ID_INDEX);
         screen.rank = c.getInt(SCREEN_RANK_INDEX);
-
-        return writeCheckedBytes(screen);
+        return screen;
     }
 
     /** Deserialize a Screen from persistence, after verifying checksum wrapper. */
-    private ContentValues unpackScreen(byte[] buffer, int offset, int dataSize)
+    private ContentValues unpackScreen(byte[] buffer, int dataSize)
             throws InvalidProtocolBufferNanoException {
-        Screen screen = new Screen();
-        MessageNano.mergeFrom(screen, readCheckedBytes(buffer, offset, dataSize));
-        if (VERBOSE) Log.v(TAG, "unpacked screen " + screen.id + "/" + screen.rank);
+        Screen screen = unpackProto(new Screen(), buffer, dataSize);
         ContentValues values = new ContentValues();
         values.put(WorkspaceScreens._ID, screen.id);
         values.put(WorkspaceScreens.SCREEN_RANK, screen.rank);
@@ -910,27 +886,18 @@
     }
 
     /** Serialize an icon Resource for persistence, including a checksum wrapper. */
-    private byte[] packIcon(int dpi, Bitmap icon) {
+    private Resource packIcon(int dpi, Bitmap icon) {
         Resource res = new Resource();
         res.dpi = dpi;
         ByteArrayOutputStream os = new ByteArrayOutputStream();
         if (icon.compress(IMAGE_FORMAT, IMAGE_COMPRESSION_QUALITY, os)) {
             res.data = os.toByteArray();
         }
-        return writeCheckedBytes(res);
-    }
-
-    /** Deserialize an icon resource from persistence, after verifying checksum wrapper. */
-    private static Resource unpackIcon(byte[] buffer, int offset, int dataSize)
-            throws InvalidProtocolBufferNanoException {
-        Resource res = new Resource();
-        MessageNano.mergeFrom(res, readCheckedBytes(buffer, offset, dataSize));
-        if (VERBOSE) Log.v(TAG, "unpacked icon " + res.dpi + "/" + res.data.length);
         return res;
     }
 
     /** Serialize a widget for persistence, including a checksum wrapper. */
-    private byte[] packWidget(int dpi, WidgetPreviewLoader previewLoader, IconCache iconCache,
+    private Widget packWidget(int dpi, WidgetPreviewLoader previewLoader, IconCache iconCache,
             ComponentName provider) {
         final AppWidgetProviderInfo info = findAppWidgetProviderInfo(provider);
         Widget widget = new Widget();
@@ -956,16 +923,17 @@
                 widget.preview.dpi = dpi;
             }
         }
-        return writeCheckedBytes(widget);
+        return widget;
     }
 
-    /** Deserialize a widget from persistence, after verifying checksum wrapper. */
-    private Widget unpackWidget(byte[] buffer, int offset, int dataSize)
+    /**
+     * Deserialize a proto after verifying checksum wrapper.
+     */
+    private <T extends MessageNano> T unpackProto(T proto, byte[] buffer, int dataSize)
             throws InvalidProtocolBufferNanoException {
-        Widget widget = new Widget();
-        MessageNano.mergeFrom(widget, readCheckedBytes(buffer, offset, dataSize));
-        if (VERBOSE) Log.v(TAG, "unpacked widget " + widget.provider);
-        return widget;
+        MessageNano.mergeFrom(proto, readCheckedBytes(buffer, dataSize));
+        if (DEBUG) Log.d(TAG, "unpacked proto " + proto);
+        return proto;
     }
 
     /**
@@ -1001,9 +969,6 @@
                         if (result > 0) {
                             availableBytes -= result;
                             bytesRead += result;
-                            if (DEBUG && (bytesRead % 100 == 0)) {
-                                Log.d(TAG, "read some bytes: " + bytesRead);
-                            }
                         } else {
                             Log.w(TAG, "unexpected end of file while reading journal.");
                             // stop reading and see what there is to parse
@@ -1016,7 +981,7 @@
 
                     // check the buffer to see if we have a valid journal
                     try {
-                        MessageNano.mergeFrom(journal, readCheckedBytes(buffer, 0, bytesRead));
+                        MessageNano.mergeFrom(journal, readCheckedBytes(buffer, bytesRead));
                         // if we are here, then we have read a valid, checksum-verified journal
                         valid = true;
                         availableBytes = 0;
@@ -1044,46 +1009,17 @@
         return journal;
     }
 
-    private void writeRowToBackup(Key key, byte[] blob, Journal out,
+    private void writeRowToBackup(Key key, MessageNano proto, BackupDataOutput data)
+            throws IOException {
+        writeRowToBackup(keyToBackupKey(key), proto, data);
+    }
+
+    private void writeRowToBackup(String backupKey, MessageNano proto,
             BackupDataOutput data) throws IOException {
-        String backupKey = keyToBackupKey(key);
+        byte[] blob = writeCheckedBytes(proto);
         data.writeEntityHeader(backupKey, blob.length);
         data.writeEntityData(blob, blob.length);
-        out.rows++;
-        out.bytes += blob.length;
-        if (VERBOSE) Log.v(TAG, "saving " + geKeyType(key) + " " + backupKey + ": " +
-                getKeyName(key) + "/" + blob.length);
-        if(DEBUG_PAYLOAD) {
-            String encoded = Base64.encodeToString(blob, 0, blob.length, Base64.NO_WRAP);
-            final int chunkSize = 1024;
-            for (int offset = 0; offset < encoded.length(); offset += chunkSize) {
-                int end = offset + chunkSize;
-                end = Math.min(end, encoded.length());
-                Log.w(TAG, "wrote " + encoded.substring(offset, end));
-            }
-        }
-    }
-
-    private Set<String> getSavedIdsByType(int type, Journal in) {
-        Set<String> savedIds = new HashSet<String>();
-        for(int i = 0; i < in.key.length; i++) {
-            Key key = in.key[i];
-            if (key.type == type) {
-                savedIds.add(keyToBackupKey(key));
-            }
-        }
-        return savedIds;
-    }
-
-    private int removeDeletedKeysFromBackup(Set<String> deletedIds, BackupDataOutput data)
-            throws IOException {
-        int rows = 0;
-        for(String deleted: deletedIds) {
-            if (VERBOSE) Log.v(TAG, "dropping deleted item " + deleted);
-            data.writeEntityHeader(deleted, -1);
-            rows++;
-        }
-        return rows;
+        if (VERBOSE) Log.v(TAG, "Writing New entry " + backupKey);
     }
 
     /**
@@ -1119,10 +1055,10 @@
     }
 
     /** Unwrap a proto message from a CheckedMessage, verifying the checksum. */
-    private static byte[] readCheckedBytes(byte[] buffer, int offset, int dataSize)
+    private static byte[] readCheckedBytes(byte[] buffer, int dataSize)
             throws InvalidProtocolBufferNanoException {
         CheckedMessage wrapper = new CheckedMessage();
-        MessageNano.mergeFrom(wrapper, buffer, offset, dataSize);
+        MessageNano.mergeFrom(wrapper, buffer, 0, dataSize);
         CRC32 checksum = new CRC32();
         checksum.update(wrapper.payload);
         if (wrapper.checksum != checksum.getValue()) {
@@ -1161,7 +1097,9 @@
     }
 
 
-   // check if the launcher is in a state to support backup
+    /**
+     * @return true if the launcher is in a state to support backup
+     */
     private boolean launcherIsReady() {
         ContentResolver cr = mContext.getContentResolver();
         Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION, null, null, null);
@@ -1185,12 +1123,12 @@
                 .getSerialNumberForUser(UserHandleCompat.myUserHandle());
     }
 
-    private class KeyParsingException extends Throwable {
-        private KeyParsingException(Throwable cause) {
+    private class InvalidBackupException extends IOException {
+        private InvalidBackupException(Throwable cause) {
             super(cause);
         }
 
-        public KeyParsingException(String reason) {
+        public InvalidBackupException(String reason) {
             super(reason);
         }
     }
diff --git a/src/com/android/launcher3/LauncherCallbacks.java b/src/com/android/launcher3/LauncherCallbacks.java
new file mode 100644
index 0000000..a1f4e0b
--- /dev/null
+++ b/src/com/android/launcher3/LauncherCallbacks.java
@@ -0,0 +1,108 @@
+package com.android.launcher3;
+
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * LauncherCallbacks is an interface used to extend the Launcher activity. It includes many hooks
+ * in order to add additional functionality. Some of these are very general, and give extending
+ * classes the ability to react to Activity life-cycle or specific user interactions. Others
+ * are more specific and relate to replacing parts of the application, for example, the search
+ * interface or the wallpaper picker.
+ */
+public interface LauncherCallbacks {
+
+    /*
+     * Activity life-cycle methods. These methods are triggered after
+     * the code in the corresponding Launcher method is executed.
+     */
+    public void preOnCreate();
+    public void onCreate(Bundle savedInstanceState);
+    public void preOnResume();
+    public void onResume();
+    public void onStart();
+    public void onStop();
+    public void onPause();
+    public void onDestroy();
+    public void onSaveInstanceState(Bundle outState);
+    public void onPostCreate(Bundle savedInstanceState);
+    public void onNewIntent(Intent intent);
+    public void onActivityResult(int requestCode, int resultCode, Intent data);
+    public void onWindowFocusChanged(boolean hasFocus);
+    public boolean onPrepareOptionsMenu(Menu menu);
+    public void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args);
+    public void onHomeIntent();
+    public boolean handleBackPressed();
+
+    /*
+     * Extension points for providing custom behavior on certain user interactions.
+     */
+    public void onLauncherProviderChange();
+    public void finishBindingItems(final boolean upgradePath);
+    public void onClickAllAppsButton(View v);
+    public void bindAllApplications(ArrayList<AppInfo> apps);
+    public void onClickFolderIcon(View v);
+    public void onClickAppShortcut(View v);
+    public void onClickPagedViewIcon(View v);
+    public void onClickWallpaperPicker(View v);
+    public void onClickSettingsButton(View v);
+    public void onClickAddWidgetButton(View v);
+    public void onPageSwitch(View newPage, int newPageIndex);
+    public void onWorkspaceLockedChanged();
+    public void onDragStarted(View view);
+    public void onInteractionBegin();
+    public void onInteractionEnd();
+
+    /*
+     * Extension points for replacing the search experience
+     */
+    public boolean forceDisableVoiceButtonProxy();
+    public boolean providesSearch();
+    public boolean startSearch(String initialQuery, boolean selectInitialQuery,
+            Bundle appSearchData, Rect sourceBounds);
+    public void startVoice();
+    public boolean hasCustomContentToLeft();
+    public void populateCustomContentContainer();
+    public View getQsbBar();
+
+    /*
+     * Extensions points for adding / replacing some other aspects of the Launcher experience.
+     */
+    public Intent getFirstRunActivity();
+    public boolean hasFirstRunActivity();
+    public boolean hasDismissableIntroScreen();
+    public View getIntroScreen();
+    public boolean shouldMoveToDefaultScreenOnHomeIntent();
+    public boolean hasSettings();
+    public ComponentName getWallpaperPickerComponent();
+    public boolean overrideWallpaperDimensions();
+    public boolean isLauncherPreinstalled();
+
+    /**
+     * Returning true will immediately result in a call to {@link #setLauncherOverlayView(ViewGroup,
+     * com.android.launcher3.Launcher.LauncherOverlayCallbacks)}.
+     *
+     * @return true if this launcher extension will provide an overlay
+     */
+    public boolean hasLauncherOverlay();
+
+    /**
+     * Handshake to establish an overlay relationship
+     *
+     * @param container Full screen overlay ViewGroup into which custom views can be placed.
+     * @param callbacks A set of callbacks provided by Launcher in relation to the overlay
+     * @return an interface used to make requests and notify the Launcher in relation to the overlay
+     */
+    public Launcher.LauncherOverlay setLauncherOverlayView(InsettableFrameLayout container,
+            Launcher.LauncherOverlayCallbacks callbacks);
+
+}
diff --git a/src/com/android/launcher3/LauncherClings.java b/src/com/android/launcher3/LauncherClings.java
index 458d81f..ef8e8ab 100644
--- a/src/com/android/launcher3/LauncherClings.java
+++ b/src/com/android/launcher3/LauncherClings.java
@@ -27,7 +27,6 @@
 import android.os.Bundle;
 import android.os.UserManager;
 import android.provider.Settings;
-import android.view.ContextThemeWrapper;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -56,8 +55,7 @@
     /** Ctor */
     public LauncherClings(Launcher launcher) {
         mLauncher = launcher;
-        mInflater = LayoutInflater.from(new
-                ContextThemeWrapper(mLauncher, android.R.style.Theme_DeviceDefault));
+        mInflater = LayoutInflater.from(mLauncher);
     }
 
     @Override
diff --git a/src/com/android/launcher3/LauncherExtension.java b/src/com/android/launcher3/LauncherExtension.java
new file mode 100644
index 0000000..b264042
--- /dev/null
+++ b/src/com/android/launcher3/LauncherExtension.java
@@ -0,0 +1,354 @@
+package com.android.launcher3;
+
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.View;
+import android.view.ViewGroup;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * This class represents a very trivial LauncherExtension. It primarily serves as a simple
+ * class to exercise the LauncherOverlay interface.
+ */
+public class LauncherExtension extends Launcher {
+
+    //------ Activity methods -------//
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        setLauncherCallbacks(new LauncherExtensionCallbacks());
+        super.onCreate(savedInstanceState);
+    }
+
+    public class LauncherExtensionCallbacks implements LauncherCallbacks {
+
+        LauncherExtensionOverlay mLauncherOverlay = new LauncherExtensionOverlay();
+
+        @Override
+        public void preOnCreate() {
+        }
+
+        @Override
+        public void onCreate(Bundle savedInstanceState) {
+        }
+
+        @Override
+        public void preOnResume() {
+        }
+
+        @Override
+        public void onResume() {
+        }
+
+        @Override
+        public void onStart() {
+        }
+
+        @Override
+        public void onStop() {
+        }
+
+        @Override
+        public void onPause() {
+        }
+
+        @Override
+        public void onDestroy() {
+        }
+
+        @Override
+        public void onSaveInstanceState(Bundle outState) {
+        }
+
+        @Override
+        public void onPostCreate(Bundle savedInstanceState) {
+        }
+
+        @Override
+        public void onNewIntent(Intent intent) {
+        }
+
+        @Override
+        public void onActivityResult(int requestCode, int resultCode, Intent data) {
+        }
+
+        @Override
+        public void onWindowFocusChanged(boolean hasFocus) {
+        }
+
+        @Override
+        public boolean onPrepareOptionsMenu(Menu menu) {
+            return false;
+        }
+
+        @Override
+        public void dump(String prefix, FileDescriptor fd, PrintWriter w, String[] args) {
+        }
+
+        @Override
+        public void onHomeIntent() {
+        }
+
+        @Override
+        public boolean handleBackPressed() {
+            if (mLauncherOverlay.isOverlayPanelShowing()) {
+                mLauncherOverlay.hideOverlayPanel();
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void onLauncherProviderChange() {
+        }
+
+        @Override
+        public void finishBindingItems(boolean upgradePath) {
+        }
+
+        @Override
+        public void onClickAllAppsButton(View v) {
+        }
+
+        @Override
+        public void bindAllApplications(ArrayList<AppInfo> apps) {
+        }
+
+        @Override
+        public void onClickFolderIcon(View v) {
+        }
+
+        @Override
+        public void onClickAppShortcut(View v) {
+        }
+
+        @Override
+        public void onClickPagedViewIcon(View v) {
+        }
+
+        @Override
+        public void onClickWallpaperPicker(View v) {
+        }
+
+        @Override
+        public void onClickSettingsButton(View v) {
+        }
+
+        @Override
+        public void onClickAddWidgetButton(View v) {
+        }
+
+        @Override
+        public void onPageSwitch(View newPage, int newPageIndex) {
+        }
+
+        @Override
+        public void onWorkspaceLockedChanged() {
+        }
+
+        @Override
+        public void onDragStarted(View view) {
+        }
+
+        @Override
+        public void onInteractionBegin() {
+        }
+
+        @Override
+        public void onInteractionEnd() {
+        }
+
+        @Override
+        public boolean forceDisableVoiceButtonProxy() {
+            return false;
+        }
+
+        @Override
+        public boolean providesSearch() {
+            return true;
+        }
+
+        @Override
+        public boolean startSearch(String initialQuery, boolean selectInitialQuery,
+                Bundle appSearchData, Rect sourceBounds) {
+            return false;
+        }
+
+        @Override
+        public void startVoice() {
+        }
+
+        @Override
+        public boolean hasCustomContentToLeft() {
+            return false;
+        }
+
+        @Override
+        public void populateCustomContentContainer() {
+        }
+
+        @Override
+        public View getQsbBar() {
+            return mLauncherOverlay.getSearchBox();
+        }
+
+        @Override
+        public Intent getFirstRunActivity() {
+            return null;
+        }
+
+        @Override
+        public boolean hasFirstRunActivity() {
+            return false;
+        }
+
+        @Override
+        public boolean hasDismissableIntroScreen() {
+            return false;
+        }
+
+        @Override
+        public View getIntroScreen() {
+            return null;
+        }
+
+        @Override
+        public boolean shouldMoveToDefaultScreenOnHomeIntent() {
+            return true;
+        }
+
+        @Override
+        public boolean hasSettings() {
+            return false;
+        }
+
+        @Override
+        public ComponentName getWallpaperPickerComponent() {
+            return null;
+        }
+
+        @Override
+        public boolean overrideWallpaperDimensions() {
+            return false;
+        }
+
+        @Override
+        public boolean isLauncherPreinstalled() {
+            return false;
+        }
+
+        @Override
+        public boolean hasLauncherOverlay() {
+            return true;
+        }
+
+        @Override
+        public LauncherOverlay setLauncherOverlayView(InsettableFrameLayout container,
+                LauncherOverlayCallbacks callbacks) {
+
+            mLauncherOverlay.setOverlayCallbacks(callbacks);
+            mLauncherOverlay.setOverlayContainer(container);
+
+            return mLauncherOverlay;
+        }
+
+        class LauncherExtensionOverlay implements LauncherOverlay {
+            LauncherOverlayCallbacks mLauncherOverlayCallbacks;
+            ViewGroup mOverlayView;
+            View mSearchBox;
+            View mSearchOverlay;
+            boolean mShowOverlayFeedback;
+            int mProgress;
+            boolean mOverlayPanelShowing;
+
+            @Override
+            public void onScrollInteractionBegin() {
+                if (mLauncherOverlayCallbacks.canEnterFullImmersion()) {
+                    mShowOverlayFeedback = true;
+                    updatePanelOffset(0);
+                    mSearchOverlay.setVisibility(View.VISIBLE);
+                    mSearchOverlay.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                }
+            }
+
+            @Override
+            public void onScrollChange(int progress, boolean rtl) {
+                mProgress = progress;
+                if (mShowOverlayFeedback) {
+                    updatePanelOffset(progress);
+                }
+            }
+
+            private void updatePanelOffset(int progress) {
+                int panelWidth = mSearchOverlay.getMeasuredWidth();
+                int offset = (int) ((progress / 100f) * panelWidth);
+                mSearchOverlay.setTranslationX(- panelWidth + offset);
+            }
+
+            @Override
+            public void onScrollInteractionEnd() {
+                if (mProgress > 25 && mLauncherOverlayCallbacks.enterFullImmersion()) {
+                    ObjectAnimator oa = LauncherAnimUtils.ofFloat(mSearchOverlay, "translationX", 0);
+                    oa.addListener(new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator arg0) {
+                            mSearchOverlay.setLayerType(View.LAYER_TYPE_NONE, null);
+                        }
+                    });
+                    oa.start();
+                    mOverlayPanelShowing = true;
+                    mShowOverlayFeedback = false;
+                }
+            }
+
+            @Override
+            public void onScrollSettled() {
+                if (mShowOverlayFeedback) {
+                    mSearchOverlay.setVisibility(View.INVISIBLE);
+                    mSearchOverlay.setLayerType(View.LAYER_TYPE_NONE, null);
+                }
+                mShowOverlayFeedback = false;
+                mProgress = 0;
+            }
+
+            public void hideOverlayPanel() {
+                mLauncherOverlayCallbacks.exitFullImmersion();
+                mSearchOverlay.setVisibility(View.INVISIBLE);
+                mOverlayPanelShowing = false;
+            }
+
+            public boolean isOverlayPanelShowing() {
+                return mOverlayPanelShowing;
+            }
+
+            @Override
+            public void forceExitFullImmersion() {
+                hideOverlayPanel();
+            }
+
+            public void setOverlayContainer(InsettableFrameLayout container) {
+                mOverlayView = (ViewGroup) getLayoutInflater().inflate(
+                        R.layout.launcher_overlay_example, container);
+                mSearchOverlay = mOverlayView.findViewById(R.id.search_overlay);
+                mSearchBox = mOverlayView.findViewById(R.id.search_box);
+            }
+
+            public View getSearchBox() {
+                return mSearchBox;
+            }
+
+            public void setOverlayCallbacks(LauncherOverlayCallbacks callbacks) {
+                mLauncherOverlayCallbacks = callbacks;
+            }
+        };
+    }
+}
diff --git a/src/com/android/launcher3/LauncherFiles.java b/src/com/android/launcher3/LauncherFiles.java
new file mode 100644
index 0000000..fa05365
--- /dev/null
+++ b/src/com/android/launcher3/LauncherFiles.java
@@ -0,0 +1,40 @@
+package com.android.launcher3;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Central list of files the Launcher writes to the application data directory.
+ *
+ * To add a new Launcher file, create a String constant referring to the filename, and add it to
+ * ALL_FILES, as shown below.
+ */
+public class LauncherFiles {
+
+    private static final String XML = ".xml";
+
+    public static final String DEFAULT_WALLPAPER_THUMBNAIL = "default_thumb2.jpg";
+    public static final String DEFAULT_WALLPAPER_THUMBNAIL_OLD = "default_thumb.jpg";
+    public static final String LAUNCHER_DB = "launcher.db";
+    public static final String LAUNCHER_PREFERENCES = "launcher.preferences";
+    public static final String LAUNCHES_LOG = "launches.log";
+    public static final String SHARED_PREFERENCES_KEY = "com.android.launcher3.prefs";
+    public static final String STATS_LOG = "stats.log";
+    public static final String WALLPAPER_CROP_PREFERENCES_KEY =
+            WallpaperCropActivity.class.getName();
+    public static final String WALLPAPER_IMAGES_DB = "saved_wallpaper_images.db";
+    public static final String WIDGET_PREVIEWS_DB = "widgetpreviews.db";
+
+    public static final List<String> ALL_FILES = Collections.unmodifiableList(Arrays.asList(
+            DEFAULT_WALLPAPER_THUMBNAIL,
+            DEFAULT_WALLPAPER_THUMBNAIL_OLD,
+            LAUNCHER_DB,
+            LAUNCHER_PREFERENCES,
+            LAUNCHES_LOG,
+            SHARED_PREFERENCES_KEY + XML,
+            STATS_LOG,
+            WALLPAPER_CROP_PREFERENCES_KEY + XML,
+            WALLPAPER_IMAGES_DB,
+            WIDGET_PREVIEWS_DB));
+}
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index c64506d..954887d 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -30,6 +30,7 @@
 import android.content.Intent.ShortcutIconResource;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
+import android.content.pm.LauncherApps.Callback;
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
@@ -75,7 +76,6 @@
 import java.util.Map.Entry;
 import java.util.Set;
 import java.util.TreeMap;
-import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
  * Maintains in-memory state of the Launcher. It is expected that there should be only one
@@ -87,6 +87,7 @@
     static final boolean DEBUG_LOADERS = false;
     private static final boolean DEBUG_RECEIVER = false;
     private static final boolean REMOVE_UNRESTORED_ICONS = true;
+    private static final boolean ADD_MANAGED_PROFILE_SHORTCUTS = false;
 
     static final String TAG = "Launcher.Model";
 
@@ -110,6 +111,11 @@
     private boolean mIsLoaderTaskRunning;
     private volatile boolean mFlushingWorkerThread;
 
+    /**
+     * Maintain a set of packages per user, for which we added a shortcut on the workspace.
+     */
+    private static final String INSTALLED_SHORTCUTS_SET_PREFIX = "installed_shortcuts_set_for_user_";
+
     // Specific runnable types that are run on the main thread deferred handler, this allows us to
     // clear all queued binding runnables when the Launcher activity is destroyed.
     private static final int MAIN_THREAD_NORMAL_RUNNABLE = 0;
@@ -198,11 +204,13 @@
                                   ArrayList<ItemInfo> addAnimated,
                                   ArrayList<AppInfo> addedApps);
         public void bindAppsUpdated(ArrayList<AppInfo> apps);
-        public void bindAppsRestored(ArrayList<AppInfo> apps);
+        public void bindShortcutsChanged(ArrayList<ShortcutInfo> updated,
+                ArrayList<ShortcutInfo> removed, UserHandleCompat user);
+        public void bindWidgetsRestored(ArrayList<LauncherAppWidgetInfo> widgets);
         public void updatePackageState(ArrayList<PackageInstallInfo> installInfo);
         public void updatePackageBadge(String packageName);
         public void bindComponentsRemoved(ArrayList<String> packageNames,
-                        ArrayList<AppInfo> appInfos, UserHandleCompat user);
+                        ArrayList<AppInfo> appInfos, UserHandleCompat user, int reason);
         public void bindPackagesUpdated(ArrayList<Object> widgetsAndShortcuts);
         public void bindSearchablesChanged();
         public boolean isAllAppsButtonRank(int rank);
@@ -341,7 +349,7 @@
         // Process the updated package state
         Runnable r = new Runnable() {
             public void run() {
-                Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+                Callbacks callbacks = getCallback();
                 if (callbacks != null) {
                     callbacks.updatePackageState(installInfo);
                 }
@@ -354,7 +362,7 @@
         // Process the updated package badge
         Runnable r = new Runnable() {
             public void run() {
-                Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+                Callbacks callbacks = getCallback();
                 if (callbacks != null) {
                     callbacks.updatePackageBadge(packageName);
                 }
@@ -364,7 +372,7 @@
     }
 
     public void addAppsToAllApps(final Context ctx, final ArrayList<AppInfo> allAppsApps) {
-        final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+        final Callbacks callbacks = getCallback();
 
         if (allAppsApps == null) {
             throw new RuntimeException("allAppsApps must not be null");
@@ -373,32 +381,13 @@
             return;
         }
 
-        final ArrayList<AppInfo> restoredAppsFinal = new ArrayList<AppInfo>();
-        Iterator<AppInfo> iter = allAppsApps.iterator();
-        while (iter.hasNext()) {
-            ItemInfo a = iter.next();
-            if (LauncherModel.appWasPromise(ctx, a.getIntent(), a.user)) {
-                restoredAppsFinal.add((AppInfo) a);
-            }
-        }
-
         // Process the newly added applications and add them to the database first
         Runnable r = new Runnable() {
             public void run() {
                 runOnMainThread(new Runnable() {
                     public void run() {
-                        Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+                        Callbacks cb = getCallback();
                         if (callbacks == cb && cb != null) {
-                            if (!restoredAppsFinal.isEmpty()) {
-                                for (AppInfo info : restoredAppsFinal) {
-                                    final Intent intent = info.getIntent();
-                                    if (intent != null) {
-                                        mIconCache.deletePreloadedIcon(intent.getComponent(),
-                                                info.user);
-                                    }
-                                }
-                                callbacks.bindAppsUpdated(restoredAppsFinal);
-                            }
                             callbacks.bindAppsAdded(null, null, null, allAppsApps);
                         }
                     }
@@ -410,7 +399,7 @@
 
     public void addAndBindAddedWorkspaceApps(final Context context,
             final ArrayList<ItemInfo> workspaceApps) {
-        final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+        final Callbacks callbacks = getCallback();
 
         if (workspaceApps == null) {
             throw new RuntimeException("workspaceApps and allAppsApps must not be null");
@@ -423,7 +412,6 @@
             public void run() {
                 final ArrayList<ItemInfo> addedShortcutsFinal = new ArrayList<ItemInfo>();
                 final ArrayList<Long> addedWorkspaceScreensFinal = new ArrayList<Long>();
-                final ArrayList<AppInfo> restoredAppsFinal = new ArrayList<AppInfo>();
 
                 // Get the list of workspace screens.  We need to append to this list and
                 // can not use sBgWorkspaceScreens because loadWorkspace() may not have been
@@ -443,12 +431,7 @@
                         final Intent launchIntent = a.getIntent();
 
                         // Short-circuit this logic if the icon exists somewhere on the workspace
-                        if (LauncherModel.shortcutExists(context, name, launchIntent)) {
-                            // Only InstallShortcutReceiver sends us shortcutInfos, ignore them
-                            if (a instanceof AppInfo &&
-                                    LauncherModel.appWasPromise(context, launchIntent, a.user)) {
-                                restoredAppsFinal.add((AppInfo) a);
-                            }
+                        if (shortcutExists(context, name, launchIntent, a.user)) {
                             continue;
                         }
 
@@ -507,7 +490,7 @@
                 if (!addedShortcutsFinal.isEmpty()) {
                     runOnMainThread(new Runnable() {
                         public void run() {
-                            Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+                            Callbacks cb = getCallback();
                             if (callbacks == cb && cb != null) {
                                 final ArrayList<ItemInfo> addAnimated = new ArrayList<ItemInfo>();
                                 final ArrayList<ItemInfo> addNotAnimated = new ArrayList<ItemInfo>();
@@ -524,9 +507,6 @@
                                 }
                                 callbacks.bindAppsAdded(addedWorkspaceScreensFinal,
                                         addNotAnimated, addAnimated, null);
-                                if (!restoredAppsFinal.isEmpty()) {
-                                    callbacks.bindAppsUpdated(restoredAppsFinal);
-                                }
                             }
                         }
                     });
@@ -870,7 +850,8 @@
      * Returns true if the shortcuts already exists in the database.
      * we identify a shortcut by its title and intent.
      */
-    static boolean shortcutExists(Context context, String title, Intent intent) {
+    static boolean shortcutExists(Context context, String title, Intent intent,
+            UserHandleCompat user) {
         final ContentResolver cr = context.getContentResolver();
         final Intent intentWithPkg, intentWithoutPkg;
 
@@ -889,27 +870,18 @@
             intentWithPkg = intent;
             intentWithoutPkg = intent;
         }
+        String userSerial = Long.toString(UserManagerCompat.getInstance(context)
+                .getSerialNumberForUser(user));
         Cursor c = cr.query(LauncherSettings.Favorites.CONTENT_URI,
-            new String[] { "title", "intent" }, "title=? and (intent=? or intent=?)",
-            new String[] { title, intentWithPkg.toUri(0), intentWithoutPkg.toUri(0) }, null);
-        boolean result = false;
+            new String[] { "title", "intent", "profileId" },
+            "title=? and (intent=? or intent=?) and profileId=?",
+            new String[] { title, intentWithPkg.toUri(0), intentWithoutPkg.toUri(0), userSerial },
+            null);
         try {
-            result = c.moveToFirst();
+            return c.moveToFirst();
         } finally {
             c.close();
         }
-        return result;
-    }
-
-    /**
-     * Returns true if the promise shortcuts with the same package name exists on the workspace.
-     */
-    static boolean appWasPromise(Context context, Intent intent, UserHandleCompat user) {
-        final ComponentName component = intent.getComponent();
-        if (component == null) {
-            return false;
-        }
-        return !getItemsByPackageName(component.getPackageName(), user).isEmpty();
     }
 
     /**
@@ -1111,7 +1083,7 @@
      * @param context
      * @param item
      */
-    static void deleteItemsFromDatabase(Context context, final ArrayList<ItemInfo> items) {
+    static void deleteItemsFromDatabase(Context context, final ArrayList<? extends ItemInfo> items) {
         final ContentResolver cr = context.getContentResolver();
 
         Runnable r = new Runnable() {
@@ -1322,11 +1294,9 @@
              mPreviousConfigMcc = currentConfig.mcc;
         } else if (SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED.equals(action) ||
                    SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED.equals(action)) {
-            if (mCallbacks != null) {
-                Callbacks callbacks = mCallbacks.get();
-                if (callbacks != null) {
-                    callbacks.bindSearchablesChanged();
-                }
+            Callbacks callbacks = getCallback();
+            if (callbacks != null) {
+                callbacks.bindSearchablesChanged();
             }
         }
     }
@@ -1358,13 +1328,11 @@
      */
     public void startLoaderFromBackground() {
         boolean runLoader = false;
-        if (mCallbacks != null) {
-            Callbacks callbacks = mCallbacks.get();
-            if (callbacks != null) {
-                // Only actually run the loader if they're not paused.
-                if (!callbacks.setLoadOnResume()) {
-                    runLoader = true;
-                }
+        Callbacks callbacks = getCallback();
+        if (callbacks != null) {
+            // Only actually run the loader if they're not paused.
+            if (!callbacks.setLoadOnResume()) {
+                runLoader = true;
             }
         }
         if (runLoader) {
@@ -1758,8 +1726,7 @@
         }
 
         // check & update map of what's occupied; used to discard overlapping/invalid items
-        private boolean checkItemPlacement(HashMap<Long, ItemInfo[][]> occupied, ItemInfo item,
-                                           AtomicBoolean deleteOnInvalidPlacement) {
+        private boolean checkItemPlacement(HashMap<Long, ItemInfo[][]> occupied, ItemInfo item) {
             LauncherAppState app = LauncherAppState.getInstance();
             DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
             final int countX = (int) grid.numColumns;
@@ -1770,7 +1737,6 @@
                 // Return early if we detect that an item is under the hotseat button
                 if (mCallbacks == null ||
                         mCallbacks.get().isAllAppsButtonRank((int) item.screenId)) {
-                    deleteOnInvalidPlacement.set(true);
                     Log.e(TAG, "Error loading shortcut into hotseat " + item
                             + " into position (" + item.screenId + ":" + item.cellX + ","
                             + item.cellY + ") occupied by all apps");
@@ -1967,7 +1933,6 @@
                     UserHandleCompat user;
 
                     while (!mStopped && c.moveToNext()) {
-                        AtomicBoolean deleteOnInvalidPlacement = new AtomicBoolean(false);
                         try {
                             int itemType = c.getInt(itemTypeIndex);
                             boolean restored = 0 != c.getInt(restoredIndex);
@@ -1981,6 +1946,7 @@
                                 long serialNumber = c.getInt(profileIdIndex);
                                 user = mUserManager.getUserForSerialNumber(serialNumber);
                                 int promiseType = c.getInt(restoredIndex);
+                                int disabledState = 0;
                                 if (user == null) {
                                     // User has been deleted remove the item.
                                     itemsToRemove.add(id);
@@ -2054,14 +2020,13 @@
                                                 itemsToRemove.add(id);
                                                 continue;
                                             }
-                                        } else if (isSdCardReady) {
-                                            // Do not wait for external media load anymore.
-                                            // Log the invalid package, and remove it
-                                            Launcher.addDumpLog(TAG,
-                                                    "Invalid package removed: " + cn, true);
-                                            itemsToRemove.add(id);
-                                            continue;
-                                        } else {
+                                        } else if (launcherApps.isAppEnabled(
+                                                manager, cn.getPackageName(),
+                                                PackageManager.GET_UNINSTALLED_PACKAGES)) {
+                                            // Package is present but not available.
+                                            allowMissingTarget = true;
+                                            disabledState = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
+                                        } else if (!isSdCardReady) {
                                             // SdCard is not ready yet. Package might get available,
                                             // once it is ready.
                                             Launcher.addDumpLog(TAG, "Invalid package: " + cn
@@ -2074,6 +2039,14 @@
                                             pkgs.add(cn.getPackageName());
                                             allowMissingTarget = true;
                                             // Add the icon on the workspace anyway.
+
+                                        } else {
+                                            // Do not wait for external media load anymore.
+                                            // Log the invalid package, and remove it
+                                            Launcher.addDumpLog(TAG,
+                                                    "Invalid package removed: " + cn, true);
+                                            itemsToRemove.add(id);
+                                            continue;
                                         }
                                     } else if (cn == null) {
                                         // For shortcuts with no component, keep them as they are
@@ -2131,15 +2104,14 @@
                                     info.spanX = 1;
                                     info.spanY = 1;
                                     info.intent.putExtra(ItemInfo.EXTRA_PROFILE, serialNumber);
-                                    info.isDisabled = isSafeMode
-                                            && !Utilities.isSystemApp(context, intent);
+                                    info.isDisabled = disabledState;
+                                    if (isSafeMode && !Utilities.isSystemApp(context, intent)) {
+                                        info.isDisabled |= ShortcutInfo.FLAG_DISABLED_SAFEMODE;
+                                    }
 
                                     // check & update map of what's occupied
-                                    deleteOnInvalidPlacement.set(false);
-                                    if (!checkItemPlacement(occupied, info, deleteOnInvalidPlacement)) {
-                                        if (deleteOnInvalidPlacement.get()) {
-                                            itemsToRemove.add(id);
-                                        }
+                                    if (!checkItemPlacement(occupied, info)) {
+                                        itemsToRemove.add(id);
                                         break;
                                     }
 
@@ -2180,12 +2152,8 @@
                                 folderInfo.spanY = 1;
 
                                 // check & update map of what's occupied
-                                deleteOnInvalidPlacement.set(false);
-                                if (!checkItemPlacement(occupied, folderInfo,
-                                        deleteOnInvalidPlacement)) {
-                                    if (deleteOnInvalidPlacement.get()) {
-                                        itemsToRemove.add(id);
-                                    }
+                                if (!checkItemPlacement(occupied, folderInfo)) {
+                                    itemsToRemove.add(id);
                                     break;
                                 }
 
@@ -2268,7 +2236,7 @@
                                             // App restore has started. Update the flag
                                             appWidgetInfo.restoreStatus |=
                                                     LauncherAppWidgetInfo.FLAG_RESTORE_STARTED;
-                                        } else if (REMOVE_UNRESTORED_ICONS) {
+                                        } else if (REMOVE_UNRESTORED_ICONS && !isSafeMode) {
                                             Launcher.addDumpLog(TAG,
                                                     "Unrestored widget removed: " + component, true);
                                             itemsToRemove.add(id);
@@ -2293,12 +2261,8 @@
 
                                     appWidgetInfo.container = c.getInt(containerIndex);
                                     // check & update map of what's occupied
-                                    deleteOnInvalidPlacement.set(false);
-                                    if (!checkItemPlacement(occupied, appWidgetInfo,
-                                            deleteOnInvalidPlacement)) {
-                                        if (deleteOnInvalidPlacement.get()) {
-                                            itemsToRemove.add(id);
-                                        }
+                                    if (!checkItemPlacement(occupied, appWidgetInfo)) {
+                                        itemsToRemove.add(id);
                                         break;
                                     }
 
@@ -2852,6 +2816,8 @@
 
             // Clear the list of apps
             mBgAllAppsList.clear();
+            SharedPreferences prefs = mContext.getSharedPreferences(
+                    LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
             for (UserHandleCompat user : profiles) {
                 // Query for the set of apps
                 final long qiaTime = DEBUG_LOADERS ? SystemClock.uptimeMillis() : 0;
@@ -2862,6 +2828,7 @@
                     Log.d(TAG, "getActivityList got " + apps.size() + " apps for user " + user);
                 }
                 // Fail if we don't have any apps
+                // TODO: Fix this. Only fail for the current user.
                 if (apps == null || apps.isEmpty()) {
                     return;
                 }
@@ -2880,6 +2847,25 @@
                     // This builds the icon bitmaps.
                     mBgAllAppsList.add(new AppInfo(mContext, app, user, mIconCache, mLabelCache));
                 }
+
+                if (ADD_MANAGED_PROFILE_SHORTCUTS && !user.equals(UserHandleCompat.myUserHandle())) {
+                    // Add shortcuts for packages which were installed while launcher was dead.
+                    String shortcutsSetKey = INSTALLED_SHORTCUTS_SET_PREFIX
+                            + mUserManager.getSerialNumberForUser(user);
+                    Set<String> packagesAdded = prefs.getStringSet(shortcutsSetKey, Collections.EMPTY_SET);
+                    HashSet<String> newPackageSet = new HashSet<String>();
+
+                    for (LauncherActivityInfoCompat info : apps) {
+                        String packageName = info.getComponentName().getPackageName();
+                        if (!packagesAdded.contains(packageName)
+                                && !newPackageSet.contains(packageName)) {
+                            InstallShortcutReceiver.queueInstallShortcut(info, mContext);
+                        }
+                        newPackageSet.add(packageName);
+                    }
+
+                    prefs.edit().putStringSet(shortcutsSetKey, newPackageSet).commit();
+                }
             }
             // Huh? Shouldn't this be inside the Runnable below?
             final ArrayList<AppInfo> added = mBgAllAppsList.added;
@@ -2930,84 +2916,40 @@
             synchronized (sBgLock) {
                 final LauncherAppsCompat launcherApps = LauncherAppsCompat
                         .getInstance(mApp.getContext());
-                ArrayList<String> packagesRemoved;
+                final PackageManager manager = context.getPackageManager();
+                final ArrayList<String> packagesRemoved = new ArrayList<String>();
+                final ArrayList<String> packagesUnavailable = new ArrayList<String>();
                 for (Entry<UserHandleCompat, HashSet<String>> entry : sPendingPackages.entrySet()) {
                     UserHandleCompat user = entry.getKey();
-                    packagesRemoved = new ArrayList<String>();
+                    packagesRemoved.clear();
+                    packagesUnavailable.clear();
                     for (String pkg : entry.getValue()) {
                         if (!launcherApps.isPackageEnabledForProfile(pkg, user)) {
-                            Launcher.addDumpLog(TAG, "Package not found: " + pkg, true);
-                            packagesRemoved.add(pkg);
+                            boolean packageOnSdcard = launcherApps.isAppEnabled(
+                                    manager, pkg, PackageManager.GET_UNINSTALLED_PACKAGES);
+                            if (packageOnSdcard) {
+                                Launcher.addDumpLog(TAG, "Package found on sd-card: " + pkg, true);
+                                packagesUnavailable.add(pkg);
+                            } else {
+                                Launcher.addDumpLog(TAG, "Package not found: " + pkg, true);
+                                packagesRemoved.add(pkg);
+                            }
                         }
                     }
                     if (!packagesRemoved.isEmpty()) {
                         enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_REMOVE,
                                 packagesRemoved.toArray(new String[packagesRemoved.size()]), user));
                     }
+                    if (!packagesUnavailable.isEmpty()) {
+                        enqueuePackageUpdated(new PackageUpdatedTask(PackageUpdatedTask.OP_UNAVAILABLE,
+                                packagesUnavailable.toArray(new String[packagesUnavailable.size()]), user));
+                    }
                 }
                 sPendingPackages.clear();
             }
         }
     }
 
-    /**
-     * Workaround to re-check unrestored items, in-case they were installed but the Package-ADD
-     * runnable was missed by the launcher.
-     */
-    public void recheckRestoredItems(final Context context) {
-        Runnable r = new Runnable() {
-
-            @Override
-            public void run() {
-                LauncherAppsCompat launcherApps = LauncherAppsCompat.getInstance(context);
-                HashSet<String> installedPackages = new HashSet<String>();
-                UserHandleCompat user = UserHandleCompat.myUserHandle();
-                synchronized(sBgLock) {
-                    for (ItemInfo info : sBgItemsIdMap.values()) {
-                        if (info instanceof ShortcutInfo) {
-                            ShortcutInfo si = (ShortcutInfo) info;
-                            if (si.isPromise() && si.getTargetComponent() != null
-                                    && launcherApps.isPackageEnabledForProfile(
-                                            si.getTargetComponent().getPackageName(), user)) {
-                                installedPackages.add(si.getTargetComponent().getPackageName());
-                            }
-                        } else if (info instanceof LauncherAppWidgetInfo) {
-                            LauncherAppWidgetInfo widget = (LauncherAppWidgetInfo) info;
-                            if (widget.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
-                                    && launcherApps.isPackageEnabledForProfile(
-                                            widget.providerName.getPackageName(), user)) {
-                                installedPackages.add(widget.providerName.getPackageName());
-                            }
-                        }
-                    }
-                }
-
-                if (!installedPackages.isEmpty()) {
-                    final ArrayList<AppInfo> restoredApps = new ArrayList<AppInfo>();
-                    for (String pkg : installedPackages) {
-                        for (LauncherActivityInfoCompat info : launcherApps.getActivityList(pkg, user)) {
-                            restoredApps.add(new AppInfo(context, info, user, mIconCache, null));
-                        }
-                    }
-
-                    final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
-                    if (!restoredApps.isEmpty()) {
-                        mHandler.post(new Runnable() {
-                            public void run() {
-                                Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
-                                if (callbacks == cb && cb != null) {
-                                    callbacks.bindAppsRestored(restoredApps);
-                                }
-                            }
-                        });
-                    }
-
-                }
-            }
-        };
-        sWorker.post(r);
-    }
-
     private class PackageUpdatedTask implements Runnable {
         int mOp;
         String[] mPackages;
@@ -3038,6 +2980,31 @@
                         mIconCache.remove(packages[i], mUser);
                         mBgAllAppsList.addPackage(context, packages[i], mUser);
                     }
+
+                    // Auto add shortcuts for added packages.
+                    if (ADD_MANAGED_PROFILE_SHORTCUTS
+                            && !UserHandleCompat.myUserHandle().equals(mUser)) {
+                        SharedPreferences prefs = context.getSharedPreferences(
+                                LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
+                        String shortcutsSetKey = INSTALLED_SHORTCUTS_SET_PREFIX
+                                + mUserManager.getSerialNumberForUser(mUser);
+                        Set<String> shortcutSet = new HashSet<String>(
+                                prefs.getStringSet(shortcutsSetKey,Collections.EMPTY_SET));
+
+                        for (int i=0; i<N; i++) {
+                            if (!shortcutSet.contains(packages[i])) {
+                                shortcutSet.add(packages[i]);
+                                List<LauncherActivityInfoCompat> activities =
+                                        mLauncherApps.getActivityList(packages[i], mUser);
+                                if (activities != null && !activities.isEmpty()) {
+                                    InstallShortcutReceiver.queueInstallShortcut(
+                                            activities.get(0), context);
+                                }
+                            }
+                        }
+
+                        prefs.edit().putStringSet(shortcutsSetKey, shortcutSet).commit();
+                    }
                     break;
                 case OP_UPDATE:
                     for (int i=0; i<N; i++) {
@@ -3048,10 +3015,25 @@
                     }
                     break;
                 case OP_REMOVE:
+                    // Remove the packageName for the set of auto-installed shortcuts. This
+                    // will ensure that the shortcut when the app is installed again.
+                    if (ADD_MANAGED_PROFILE_SHORTCUTS
+                            && !UserHandleCompat.myUserHandle().equals(mUser)) {
+                        SharedPreferences prefs = context.getSharedPreferences(
+                                LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
+                        String shortcutsSetKey = INSTALLED_SHORTCUTS_SET_PREFIX
+                                + mUserManager.getSerialNumberForUser(mUser);
+                        HashSet<String> shortcutSet = new HashSet<String>(
+                                prefs.getStringSet(shortcutsSetKey, Collections.EMPTY_SET));
+                        shortcutSet.removeAll(Arrays.asList(mPackages));
+                        prefs.edit().putStringSet(shortcutsSetKey, shortcutSet).commit();
+                    }
+                    // Fall through
                 case OP_UNAVAILABLE:
+                    boolean clearCache = mOp == OP_REMOVE;
                     for (int i=0; i<N; i++) {
                         if (DEBUG_LOADERS) Log.d(TAG, "mAllAppsList.removePackage " + packages[i]);
-                        mBgAllAppsList.removePackage(packages[i], mUser);
+                        mBgAllAppsList.removePackage(packages[i], mUser, clearCache);
                         WidgetPreviewLoader.removePackageFromDb(
                                 mApp.getWidgetPreviewCacheDb(), packages[i]);
                     }
@@ -3075,12 +3057,15 @@
                 mBgAllAppsList.removed.clear();
             }
 
-            final Callbacks callbacks = mCallbacks != null ? mCallbacks.get() : null;
+            final Callbacks callbacks = getCallback();
             if (callbacks == null) {
                 Log.w(TAG, "Nobody to tell about the new app.  Launcher is probably loading.");
                 return;
             }
 
+            final HashMap<ComponentName, AppInfo> addedOrUpdatedApps =
+                    new HashMap<ComponentName, AppInfo>();
+
             if (added != null) {
                 // Ensure that we add all the workspace applications to the db
                 if (LauncherAppState.isDisableAllApps()) {
@@ -3089,28 +3074,20 @@
                 } else {
                     addAppsToAllApps(context, added);
                 }
+                for (AppInfo ai : added) {
+                    addedOrUpdatedApps.put(ai.componentName, ai);
+                }
             }
 
             if (modified != null) {
                 final ArrayList<AppInfo> modifiedFinal = modified;
-
-                // Update the launcher db to reflect the changes
-                for (AppInfo a : modifiedFinal) {
-                    ArrayList<ItemInfo> infos =
-                            getItemInfoForComponentName(a.componentName, mUser);
-                    for (ItemInfo i : infos) {
-                        if (isShortcutInfoUpdateable(i)) {
-                            ShortcutInfo info = (ShortcutInfo) i;
-                            info.title = a.title.toString();
-                            info.contentDescription = a.contentDescription;
-                            updateItemInDatabase(context, info);
-                        }
-                    }
+                for (AppInfo ai : modified) {
+                    addedOrUpdatedApps.put(ai.componentName, ai);
                 }
 
                 mHandler.post(new Runnable() {
                     public void run() {
-                        Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+                        Callbacks cb = getCallback();
                         if (callbacks == cb && cb != null) {
                             callbacks.bindAppsUpdated(modifiedFinal);
                         }
@@ -3118,41 +3095,174 @@
                 });
             }
 
+            // Update shortcut infos
+            if (mOp == OP_ADD || mOp == OP_UPDATE) {
+                final ArrayList<ShortcutInfo> updatedShortcuts = new ArrayList<ShortcutInfo>();
+                final ArrayList<ShortcutInfo> removedShortcuts = new ArrayList<ShortcutInfo>();
+                final ArrayList<LauncherAppWidgetInfo> widgets = new ArrayList<LauncherAppWidgetInfo>();
+
+                HashSet<String> packageSet = new HashSet<String>(Arrays.asList(packages));
+                synchronized (sBgLock) {
+                    for (ItemInfo info : sBgItemsIdMap.values()) {
+                        if (info instanceof ShortcutInfo && mUser.equals(info.user)) {
+                            ShortcutInfo si = (ShortcutInfo) info;
+                            boolean infoUpdated = false;
+                            boolean shortcutUpdated = false;
+
+                            // Update shortcuts which use iconResource.
+                            if ((si.iconResource != null)
+                                    && packageSet.contains(si.iconResource.packageName)) {
+                                Bitmap icon = Utilities.createIconBitmap(si.iconResource.packageName,
+                                        si.iconResource.resourceName, mIconCache, context);
+                                if (icon != null) {
+                                    si.setIcon(icon);
+                                    si.usingFallbackIcon = false;
+                                    infoUpdated = true;
+                                }
+                            }
+
+                            ComponentName cn = si.getTargetComponent();
+                            if (cn != null && packageSet.contains(cn.getPackageName())) {
+                                AppInfo appInfo = addedOrUpdatedApps.get(cn);
+
+                                if (si.isPromise()) {
+                                    mIconCache.deletePreloadedIcon(cn, mUser);
+                                    if (si.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
+                                        // Auto install icon
+                                        PackageManager pm = context.getPackageManager();
+                                        ResolveInfo matched = pm.resolveActivity(
+                                                new Intent(Intent.ACTION_MAIN)
+                                                .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER),
+                                                PackageManager.MATCH_DEFAULT_ONLY);
+                                        if (matched == null) {
+                                            // Try to find the best match activity.
+                                            Intent intent = pm.getLaunchIntentForPackage(
+                                                    cn.getPackageName());
+                                            if (intent != null) {
+                                                cn = intent.getComponent();
+                                                appInfo = addedOrUpdatedApps.get(cn);
+                                            }
+
+                                            if ((intent == null) || (appInfo == null)) {
+                                                removedShortcuts.add(si);
+                                                continue;
+                                            }
+                                            si.promisedIntent = intent;
+                                        }
+                                    }
+
+                                    // Restore the shortcut.
+                                    si.intent = si.promisedIntent;
+                                    si.promisedIntent = null;
+                                    si.status &= ~ShortcutInfo.FLAG_RESTORED_ICON
+                                            & ~ShortcutInfo.FLAG_AUTOINTALL_ICON
+                                            & ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
+
+                                    infoUpdated = true;
+                                    si.updateIcon(mIconCache);
+                                }
+
+                                if (appInfo != null && Intent.ACTION_MAIN.equals(si.intent.getAction())
+                                        && si.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
+                                    si.updateIcon(mIconCache);
+                                    si.title = appInfo.title.toString();
+                                    si.contentDescription = appInfo.contentDescription;
+                                    infoUpdated = true;
+                                }
+
+                                if ((si.isDisabled & ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE) != 0) {
+                                    // Since package was just updated, the target must be available now.
+                                    si.isDisabled &= ~ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
+                                    shortcutUpdated = true;
+                                }
+                            }
+
+                            if (infoUpdated || shortcutUpdated) {
+                                updatedShortcuts.add(si);
+                            }
+                            if (infoUpdated) {
+                                updateItemInDatabase(context, si);
+                            }
+                        } else if (info instanceof LauncherAppWidgetInfo) {
+                            LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info;
+                            if (mUser.equals(widgetInfo.user)
+                                    && widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
+                                    && packageSet.contains(widgetInfo.providerName.getPackageName())) {
+                                widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
+                                widgets.add(widgetInfo);
+                                updateItemInDatabase(context, widgetInfo);
+                            }
+                        }
+                    }
+                }
+
+                if (!updatedShortcuts.isEmpty() || !removedShortcuts.isEmpty()) {
+                    mHandler.post(new Runnable() {
+
+                        public void run() {
+                            Callbacks cb = getCallback();
+                            if (callbacks == cb && cb != null) {
+                                callbacks.bindShortcutsChanged(
+                                        updatedShortcuts, removedShortcuts, mUser);
+                            }
+                        }
+                    });
+                    if (!removedShortcuts.isEmpty()) {
+                        deleteItemsFromDatabase(context, removedShortcuts);
+                    }
+                }
+                if (!widgets.isEmpty()) {
+                    mHandler.post(new Runnable() {
+                        public void run() {
+                            Callbacks cb = getCallback();
+                            if (callbacks == cb && cb != null) {
+                                callbacks.bindWidgetsRestored(widgets);
+                            }
+                        }
+                    });
+                }
+            }
+
             final ArrayList<String> removedPackageNames =
                     new ArrayList<String>();
-            if (mOp == OP_REMOVE) {
+            if (mOp == OP_REMOVE || mOp == OP_UNAVAILABLE) {
                 // Mark all packages in the broadcast to be removed
                 removedPackageNames.addAll(Arrays.asList(packages));
             } else if (mOp == OP_UPDATE) {
                 // Mark disabled packages in the broadcast to be removed
-                final PackageManager pm = context.getPackageManager();
                 for (int i=0; i<N; i++) {
                     if (isPackageDisabled(context, packages[i], mUser)) {
                         removedPackageNames.add(packages[i]);
                     }
                 }
             }
-            // Remove all the components associated with this package
-            for (String pn : removedPackageNames) {
-                deletePackageFromDatabase(context, pn, mUser);
-            }
-            // Remove all the specific components
-            for (AppInfo a : removedApps) {
-                ArrayList<ItemInfo> infos = getItemInfoForComponentName(a.componentName, mUser);
-                deleteItemsFromDatabase(context, infos);
-            }
+
             if (!removedPackageNames.isEmpty() || !removedApps.isEmpty()) {
+                final int removeReason;
+                if (mOp == OP_UNAVAILABLE) {
+                    removeReason = ShortcutInfo.FLAG_DISABLED_NOT_AVAILABLE;
+                } else {
+                    // Remove all the components associated with this package
+                    for (String pn : removedPackageNames) {
+                        deletePackageFromDatabase(context, pn, mUser);
+                    }
+                    // Remove all the specific components
+                    for (AppInfo a : removedApps) {
+                        ArrayList<ItemInfo> infos = getItemInfoForComponentName(a.componentName, mUser);
+                        deleteItemsFromDatabase(context, infos);
+                    }
+                    removeReason = 0;
+                }
+
                 // Remove any queued items from the install queue
-                String spKey = LauncherAppState.getSharedPreferencesKey();
-                SharedPreferences sp =
-                        context.getSharedPreferences(spKey, Context.MODE_PRIVATE);
-                InstallShortcutReceiver.removeFromInstallQueue(sp, removedPackageNames);
+                InstallShortcutReceiver.removeFromInstallQueue(context, removedPackageNames, mUser);
                 // Call the components-removed callback
                 mHandler.post(new Runnable() {
                     public void run() {
-                        Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+                        Callbacks cb = getCallback();
                         if (callbacks == cb && cb != null) {
-                            callbacks.bindComponentsRemoved(removedPackageNames, removedApps, mUser);
+                            callbacks.bindComponentsRemoved(
+                                    removedPackageNames, removedApps, mUser, removeReason);
                         }
                     }
                 });
@@ -3163,7 +3273,7 @@
             mHandler.post(new Runnable() {
                 @Override
                 public void run() {
-                    Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+                    Callbacks cb = getCallback();
                     if (callbacks == cb && cb != null) {
                         callbacks.bindPackagesUpdated(widgetsAndShortcuts);
                     }
@@ -3173,7 +3283,7 @@
             // Write all the logs to disk
             mHandler.post(new Runnable() {
                 public void run() {
-                    Callbacks cb = mCallbacks != null ? mCallbacks.get() : null;
+                    Callbacks cb = getCallback();
                     if (callbacks == cb && cb != null) {
                         callbacks.dumpLogsToLocalData();
                     }
@@ -3402,26 +3512,6 @@
         return filterItemInfos(sBgItemsIdMap.values(), filter);
     }
 
-    public static boolean isShortcutInfoUpdateable(ItemInfo i) {
-        if (i instanceof ShortcutInfo) {
-            ShortcutInfo info = (ShortcutInfo) i;
-            // We need to check for ACTION_MAIN otherwise getComponent() might
-            // return null for some shortcuts (for instance, for shortcuts to
-            // web pages.)
-            Intent intent = info.intent;
-            ComponentName name = intent.getComponent();
-            if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION &&
-                    Intent.ACTION_MAIN.equals(intent.getAction()) && name != null) {
-                return true;
-            }
-            // placeholder shortcuts get special treatment, let them through too.
-            if (info.isPromise()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     /**
      * Make an ShortcutInfo object for a shortcut that isn't an application.
      */
@@ -3444,19 +3534,9 @@
         case LauncherSettings.Favorites.ICON_TYPE_RESOURCE:
             String packageName = c.getString(iconPackageIndex);
             String resourceName = c.getString(iconResourceIndex);
-            PackageManager packageManager = context.getPackageManager();
             info.customIcon = false;
             // the resource
-            try {
-                Resources resources = packageManager.getResourcesForApplication(packageName);
-                if (resources != null) {
-                    final int id = resources.getIdentifier(resourceName, null, null);
-                    icon = Utilities.createIconBitmap(
-                            mIconCache.getFullResIcon(resources, id), context);
-                }
-            } catch (Exception e) {
-                // drop this.  we have other places to look for icons
-            }
+            icon = Utilities.createIconBitmap(packageName, resourceName, mIconCache, context);
             // the db
             if (icon == null) {
                 icon = getIconFromCursor(c, iconIndex, context);
@@ -3503,17 +3583,6 @@
         }
     }
 
-    ShortcutInfo addShortcut(Context context, Intent data, long container, int screen,
-            int cellX, int cellY, boolean notify) {
-        final ShortcutInfo info = infoFromShortcutIntent(context, data, null);
-        if (info == null) {
-            return null;
-        }
-        addItemToDatabase(context, info, container, screen, cellX, cellY, notify);
-
-        return info;
-    }
-
     /**
      * Attempts to find an AppWidgetProviderInfo that matches the given component.
      */
@@ -3529,7 +3598,7 @@
         return null;
     }
 
-    ShortcutInfo infoFromShortcutIntent(Context context, Intent data, Bitmap fallbackIcon) {
+    ShortcutInfo infoFromShortcutIntent(Context context, Intent data) {
         Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
         String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
         Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
@@ -3544,24 +3613,15 @@
         boolean customIcon = false;
         ShortcutIconResource iconResource = null;
 
-        if (bitmap != null && bitmap instanceof Bitmap) {
-            icon = Utilities.createIconBitmap(new FastBitmapDrawable((Bitmap)bitmap), context);
+        if (bitmap instanceof Bitmap) {
+            icon = Utilities.createIconBitmap((Bitmap) bitmap, context);
             customIcon = true;
         } else {
             Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
-            if (extra != null && extra instanceof ShortcutIconResource) {
-                try {
-                    iconResource = (ShortcutIconResource) extra;
-                    final PackageManager packageManager = context.getPackageManager();
-                    Resources resources = packageManager.getResourcesForApplication(
-                            iconResource.packageName);
-                    final int id = resources.getIdentifier(iconResource.resourceName, null, null);
-                    icon = Utilities.createIconBitmap(
-                            mIconCache.getFullResIcon(resources, id),
-                            context);
-                } catch (Exception e) {
-                    Log.w(TAG, "Could not load shortcut icon: " + extra);
-                }
+            if (extra instanceof ShortcutIconResource) {
+                iconResource = (ShortcutIconResource) extra;
+                icon = Utilities.createIconBitmap(iconResource.packageName,
+                        iconResource.resourceName, mIconCache, context);
             }
         }
 
@@ -3571,12 +3631,8 @@
         // users wouldn't get here without intent forwarding anyway.
         info.user = UserHandleCompat.myUserHandle();
         if (icon == null) {
-            if (fallbackIcon != null) {
-                icon = fallbackIcon;
-            } else {
-                icon = mIconCache.getDefaultIcon(info.user);
-                info.usingFallbackIcon = true;
-            }
+            icon = mIconCache.getDefaultIcon(info.user);
+            info.usingFallbackIcon = true;
         }
         info.setIcon(icon);
 
@@ -3761,4 +3817,8 @@
             Log.d(TAG, "mLoaderTask=null");
         }
     }
+
+    public Callbacks getCallback() {
+        return mCallbacks != null ? mCallbacks.get() : null;
+    }
 }
diff --git a/src/com/android/launcher3/LauncherPreferencesBackupHelper.java b/src/com/android/launcher3/LauncherPreferencesBackupHelper.java
deleted file mode 100644
index 6f9c05c..0000000
--- a/src/com/android/launcher3/LauncherPreferencesBackupHelper.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.app.backup.BackupDataInputStream;
-import android.app.backup.SharedPreferencesBackupHelper;
-import android.content.Context;
-import android.util.Log;
-
-public class LauncherPreferencesBackupHelper extends SharedPreferencesBackupHelper {
-
-    private static final String TAG = "LauncherPreferencesBackupHelper";
-    private static final boolean VERBOSE = LauncherBackupAgentHelper.VERBOSE;
-
-    private final boolean mRestoreEnabled;
-
-    public LauncherPreferencesBackupHelper(Context context,  String sharedPreferencesKey,
-            boolean restoreEnabled) {
-        super(context, sharedPreferencesKey);
-        mRestoreEnabled = restoreEnabled;
-    }
-
-    @Override
-    public void restoreEntity(BackupDataInputStream data) {
-        if (mRestoreEnabled) {
-            if (VERBOSE) Log.v(TAG, "restoring preferences");
-            super.restoreEntity(data);
-        }
-    }
-}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 6cc1688..1715b02 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -16,7 +16,6 @@
 
 package com.android.launcher3;
 
-import android.app.SearchManager;
 import android.appwidget.AppWidgetHost;
 import android.appwidget.AppWidgetManager;
 import android.appwidget.AppWidgetProviderInfo;
@@ -31,12 +30,7 @@
 import android.content.Intent;
 import android.content.OperationApplicationException;
 import android.content.SharedPreferences;
-import android.content.pm.ActivityInfo;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
 import android.database.Cursor;
 import android.database.SQLException;
 import android.database.sqlite.SQLiteDatabase;
@@ -46,7 +40,6 @@
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.net.Uri;
-import android.os.Bundle;
 import android.provider.Settings;
 import android.text.TextUtils;
 import android.util.Log;
@@ -58,23 +51,16 @@
 import com.android.launcher3.compat.UserManagerCompat;
 import com.android.launcher3.config.ProviderConfig;
 
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
 import java.io.File;
-import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
 
 public class LauncherProvider extends ContentProvider {
     private static final String TAG = "Launcher.LauncherProvider";
     private static final boolean LOGD = false;
 
-    private static final String DATABASE_NAME = "launcher.db";
-
     private static final int DATABASE_VERSION = 20;
 
     static final String OLD_AUTHORITY = "com.android.launcher2.settings";
@@ -91,9 +77,6 @@
     static final String EMPTY_DATABASE_CREATED =
             "EMPTY_DATABASE_CREATED";
 
-    private static final String ACTION_APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE =
-            "com.android.launcher.action.APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE";
-
     private static final String URI_PARAM_IS_EXTERNAL_ADD = "isExternalAdd";
 
     private LauncherProviderChangeListener mListener;
@@ -162,12 +145,6 @@
         return db.insert(table, nullColumnHack, values);
     }
 
-    private static void deleteId(SQLiteDatabase db, long id) {
-        Uri uri = LauncherSettings.Favorites.getContentUri(id, false);
-        SqlArguments args = new SqlArguments(uri, null, null);
-        db.delete(args.table, args.where, args.args);
-    }
-
     @Override
     public Uri insert(Uri uri, ContentValues initialValues) {
         SqlArguments args = new SqlArguments(uri);
@@ -314,6 +291,14 @@
         mOpenHelper.createEmptyDB(mOpenHelper.getWritableDatabase());
     }
 
+    public void clearFlagEmptyDbCreated() {
+        String spKey = LauncherAppState.getSharedPreferencesKey();
+        getContext().getSharedPreferences(spKey, Context.MODE_PRIVATE)
+            .edit()
+            .remove(EMPTY_DATABASE_CREATED)
+            .commit();
+    }
+
     /**
      * Loads the default workspace based on the following priority scheme:
      *   1) From a package provided by play store
@@ -327,7 +312,7 @@
         if (sp.getBoolean(EMPTY_DATABASE_CREATED, false)) {
             Log.d(TAG, "loading default workspace");
 
-            WorkspaceLoader loader = AutoInstallsLayout.get(getContext(),
+            AutoInstallsLayout loader = AutoInstallsLayout.get(getContext(),
                     mOpenHelper.mAppWidgetHost, mOpenHelper);
 
             if (loader == null) {
@@ -337,38 +322,40 @@
                     int workspaceResId = partnerRes.getIdentifier(Partner.RES_DEFAULT_LAYOUT,
                             "xml", partner.getPackageName());
                     if (workspaceResId != 0) {
-                        loader = new SimpleWorkspaceLoader(mOpenHelper, partnerRes, workspaceResId);
+                        loader = new DefaultLayoutParser(getContext(), mOpenHelper.mAppWidgetHost,
+                                mOpenHelper, partnerRes, workspaceResId);
                     }
                 }
             }
 
+            final boolean usingExternallyProvidedLayout = loader != null;
             if (loader == null) {
-                loader = new SimpleWorkspaceLoader(mOpenHelper, getContext().getResources(),
-                        getDefaultWorkspaceResourceId());
+                loader = getDefaultLayoutParser();
             }
-
             // Populate favorites table with initial favorites
-            SharedPreferences.Editor editor = sp.edit().remove(EMPTY_DATABASE_CREATED);
-            mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), loader);
-            editor.commit();
+            if ((mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), loader) <= 0)
+                    && usingExternallyProvidedLayout) {
+                // Unable to load external layout. Cleanup and load the internal layout.
+                createEmptyDB();
+                mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(),
+                        getDefaultLayoutParser());
+            }
+            clearFlagEmptyDbCreated();
         }
     }
 
+    private DefaultLayoutParser getDefaultLayoutParser() {
+        int defaultLayout = LauncherAppState.getInstance()
+                .getDynamicGrid().getDeviceProfile().defaultLayoutId;
+        return new DefaultLayoutParser(getContext(), mOpenHelper.mAppWidgetHost,
+                mOpenHelper, getContext().getResources(), defaultLayout);
+    }
+
     public void migrateLauncher2Shortcuts() {
         mOpenHelper.migrateLauncher2Shortcuts(mOpenHelper.getWritableDatabase(),
                 Uri.parse(getContext().getString(R.string.old_launcher_provider_uri)));
     }
 
-    private static int getDefaultWorkspaceResourceId() {
-        LauncherAppState app = LauncherAppState.getInstance();
-        DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
-        if (LauncherAppState.isDisableAllApps()) {
-            return grid.defaultNoAllAppsLayoutId;
-        } else {
-            return grid.defaultLayoutId;
-        }
-    }
-
     private static interface ContentValuesCallback {
         public void onRow(ContentValues values);
     }
@@ -392,38 +379,7 @@
     }
 
     private static class DatabaseHelper extends SQLiteOpenHelper implements LayoutParserCallback {
-        private static final String TAG_RESOLVE = "resolve";
-        private static final String TAG_FAVORITES = "favorites";
-        private static final String TAG_FAVORITE = "favorite";
-        private static final String TAG_APPWIDGET = "appwidget";
-        private static final String TAG_SHORTCUT = "shortcut";
-        private static final String TAG_FOLDER = "folder";
-        private static final String TAG_PARTNER_FOLDER = "partner-folder";
-        private static final String TAG_EXTRA = "extra";
-        private static final String TAG_INCLUDE = "include";
-
-        // Style attrs -- "Favorite"
-        private static final String ATTR_CLASS_NAME = "className";
-        private static final String ATTR_PACKAGE_NAME = "packageName";
-        private static final String ATTR_CONTAINER = "container";
-        private static final String ATTR_SCREEN = "screen";
-        private static final String ATTR_X = "x";
-        private static final String ATTR_Y = "y";
-        private static final String ATTR_SPAN_X = "spanX";
-        private static final String ATTR_SPAN_Y = "spanY";
-        private static final String ATTR_ICON = "icon";
-        private static final String ATTR_TITLE = "title";
-        private static final String ATTR_URI = "uri";
-
-        // Style attrs -- "Include"
-        private static final String ATTR_WORKSPACE = "workspace";
-
-        // Style attrs -- "Extra"
-        private static final String ATTR_KEY = "key";
-        private static final String ATTR_VALUE = "value";
-
         private final Context mContext;
-        private final PackageManager mPackageManager;
         private final AppWidgetHost mAppWidgetHost;
         private long mMaxItemId = -1;
         private long mMaxScreenId = -1;
@@ -431,9 +387,8 @@
         private boolean mNewDbCreated = false;
 
         DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+            super(context, LauncherFiles.LAUNCHER_DB, null, DATABASE_VERSION);
             mContext = context;
-            mPackageManager = context.getPackageManager();
             mAppWidgetHost = new AppWidgetHost(context, Launcher.APPWIDGET_HOST_ID);
 
             // In the case where neither onCreate nor onUpgrade gets called, we read the maxId from
@@ -789,8 +744,8 @@
                 }
 
                 // Add default hotseat icons
-                loadFavorites(db, new SimpleWorkspaceLoader(this, mContext.getResources(),
-                        R.xml.update_workspace));
+                loadFavorites(db, new DefaultLayoutParser(mContext, mAppWidgetHost, this,
+                        mContext.getResources(), R.xml.update_workspace));
                 version = 9;
             }
 
@@ -1052,7 +1007,7 @@
                     long id = c.getLong(idIndex);
                     byte[] data = c.getBlob(iconIndex);
                     try {
-                        Bitmap bitmap = Utilities.resampleIconBitmap(
+                        Bitmap bitmap = Utilities.createIconBitmap(
                                 BitmapFactory.decodeByteArray(data, 0, data.length),
                                 mContext);
                         if (bitmap != null) {
@@ -1357,31 +1312,7 @@
             return rank;
         }
 
-        private static final void beginDocument(XmlPullParser parser, String firstElementName)
-                throws XmlPullParserException, IOException {
-            int type;
-            while ((type = parser.next()) != XmlPullParser.START_TAG
-                    && type != XmlPullParser.END_DOCUMENT) {
-                ;
-            }
-
-            if (type != XmlPullParser.START_TAG) {
-                throw new XmlPullParserException("No start tag found");
-            }
-
-            if (!parser.getName().equals(firstElementName)) {
-                throw new XmlPullParserException("Unexpected start tag: found " + parser.getName() +
-                        ", expected " + firstElementName);
-            }
-        }
-
-        private static Intent buildMainIntent() {
-            Intent intent = new Intent(Intent.ACTION_MAIN, null);
-            intent.addCategory(Intent.CATEGORY_LAUNCHER);
-            return intent;
-        }
-
-        private int loadFavorites(SQLiteDatabase db, WorkspaceLoader loader) {
+        private int loadFavorites(SQLiteDatabase db, AutoInstallsLayout loader) {
             ArrayList<Long> screenIds = new ArrayList<Long>();
             // TODO: Use multiple loaders with fall-back and transaction.
             int count = loader.loadLayout(db, screenIds);
@@ -1408,547 +1339,9 @@
             return count;
         }
 
-        /**
-         * Loads the default set of favorite packages from an xml file.
-         *
-         * @param db The database to write the values into
-         * @param filterContainerId The specific container id of items to load
-         * @param the set of screenIds which are used by the favorites
-         */
-        private int loadFavoritesRecursive(SQLiteDatabase db, Resources res, int workspaceResourceId,
-                ArrayList<Long> screenIds) {
-
-            ContentValues values = new ContentValues();
-            if (LOGD) Log.v(TAG, String.format("Loading favorites from resid=0x%08x", workspaceResourceId));
-
-            int count = 0;
-            try {
-                XmlResourceParser parser = res.getXml(workspaceResourceId);
-                beginDocument(parser, TAG_FAVORITES);
-
-                final int depth = parser.getDepth();
-
-                int type;
-                while (((type = parser.next()) != XmlPullParser.END_TAG ||
-                        parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
-
-                    if (type != XmlPullParser.START_TAG) {
-                        continue;
-                    }
-
-                    boolean added = false;
-                    final String name = parser.getName();
-
-                    if (TAG_INCLUDE.equals(name)) {
-
-                        final int resId = getAttributeResourceValue(parser, ATTR_WORKSPACE, 0);
-
-                        if (LOGD) Log.v(TAG, String.format(("%" + (2*(depth+1)) + "s<include workspace=%08x>"),
-                                "", resId));
-
-                        if (resId != 0 && resId != workspaceResourceId) {
-                            // recursively load some more favorites, why not?
-                            count += loadFavoritesRecursive(db, res, resId, screenIds);
-                            added = false;
-                        } else {
-                            Log.w(TAG, String.format("Skipping <include workspace=0x%08x>", resId));
-                        }
-
-                        if (LOGD) Log.v(TAG, String.format(("%" + (2*(depth+1)) + "s</include>"), ""));
-                        continue;
-                    }
-
-                    // Assuming it's a <favorite> at this point
-                    long container = LauncherSettings.Favorites.CONTAINER_DESKTOP;
-                    String strContainer = getAttributeValue(parser, ATTR_CONTAINER);
-                    if (strContainer != null) {
-                        container = Long.valueOf(strContainer);
-                    }
-
-                    String screen = getAttributeValue(parser, ATTR_SCREEN);
-                    String x = getAttributeValue(parser, ATTR_X);
-                    String y = getAttributeValue(parser, ATTR_Y);
-
-                    values.clear();
-                    values.put(LauncherSettings.Favorites.CONTAINER, container);
-                    values.put(LauncherSettings.Favorites.SCREEN, screen);
-                    values.put(LauncherSettings.Favorites.CELLX, x);
-                    values.put(LauncherSettings.Favorites.CELLY, y);
-
-                    if (LOGD) {
-                        final String title = getAttributeValue(parser, ATTR_TITLE);
-                        final String pkg = getAttributeValue(parser, ATTR_PACKAGE_NAME);
-                        final String something = title != null ? title : pkg;
-                        Log.v(TAG, String.format(
-                                ("%" + (2*(depth+1)) + "s<%s%s c=%d s=%s x=%s y=%s>"),
-                                "", name,
-                                (something == null ? "" : (" \"" + something + "\"")),
-                                container, screen, x, y));
-                    }
-
-                    if (TAG_FAVORITE.equals(name)) {
-                        long id = addAppShortcut(db, values, parser);
-                        added = id >= 0;
-                    } else if (TAG_APPWIDGET.equals(name)) {
-                        added = addAppWidget(parser, type, db, values);
-                    } else if (TAG_SHORTCUT.equals(name)) {
-                        long id = addUriShortcut(db, values, res, parser);
-                        added = id >= 0;
-                    } else if (TAG_RESOLVE.equals(name)) {
-                        // This looks through the contained favorites (or meta-favorites) and
-                        // attempts to add them as shortcuts in the fallback group's location
-                        // until one is added successfully.
-                        added = false;
-                        final int groupDepth = parser.getDepth();
-                        while ((type = parser.next()) != XmlPullParser.END_TAG ||
-                                parser.getDepth() > groupDepth) {
-                            if (type != XmlPullParser.START_TAG) {
-                                continue;
-                            }
-                            final String fallback_item_name = parser.getName();
-                            if (!added) {
-                                if (TAG_FAVORITE.equals(fallback_item_name)) {
-                                    final long id = addAppShortcut(db, values, parser);
-                                    added = id >= 0;
-                                } else {
-                                    Log.e(TAG, "Fallback groups can contain only favorites, found "
-                                            + fallback_item_name);
-                                }
-                            }
-                        }
-                    } else if (TAG_FOLDER.equals(name)) {
-                        // Folder contents are nested in this XML file
-                        added = loadFolder(db, values, res, parser);
-
-                    } else if (TAG_PARTNER_FOLDER.equals(name)) {
-                        // Folder contents come from an external XML resource
-                        final Partner partner = Partner.get(mPackageManager);
-                        if (partner != null) {
-                            final Resources partnerRes = partner.getResources();
-                            final int resId = partnerRes.getIdentifier(Partner.RES_FOLDER,
-                                    "xml", partner.getPackageName());
-                            if (resId != 0) {
-                                final XmlResourceParser partnerParser = partnerRes.getXml(resId);
-                                beginDocument(partnerParser, TAG_FOLDER);
-                                added = loadFolder(db, values, partnerRes, partnerParser);
-                            }
-                        }
-                    }
-                    if (added) {
-                        long screenId = Long.parseLong(screen);
-                        // Keep track of the set of screens which need to be added to the db.
-                        if (!screenIds.contains(screenId) &&
-                                container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                            screenIds.add(screenId);
-                        }
-                        count++;
-                    }
-                }
-            } catch (XmlPullParserException e) {
-                Log.w(TAG, "Got exception parsing favorites.", e);
-            } catch (IOException e) {
-                Log.w(TAG, "Got exception parsing favorites.", e);
-            } catch (RuntimeException e) {
-                Log.w(TAG, "Got exception parsing favorites.", e);
-            }
-            return count;
-        }
-
-        /**
-         * Parse folder items starting at {@link XmlPullParser} location. Allow recursive
-         * includes of items.
-         */
-        private void addToFolder(SQLiteDatabase db, Resources res, XmlResourceParser parser,
-                ArrayList<Long> folderItems, long folderId) throws IOException, XmlPullParserException {
-            int type;
-            int folderDepth = parser.getDepth();
-            while ((type = parser.next()) != XmlPullParser.END_TAG ||
-                    parser.getDepth() > folderDepth) {
-                if (type != XmlPullParser.START_TAG) {
-                    continue;
-                }
-                final String tag = parser.getName();
-
-                final ContentValues childValues = new ContentValues();
-                childValues.put(LauncherSettings.Favorites.CONTAINER, folderId);
-
-                if (LOGD) {
-                    final String pkg = getAttributeValue(parser, ATTR_PACKAGE_NAME);
-                    final String uri = getAttributeValue(parser, ATTR_URI);
-                    Log.v(TAG, String.format(("%" + (2*(folderDepth+1)) + "s<%s \"%s\">"), "",
-                            tag, uri != null ? uri : pkg));
-                }
-
-                if (TAG_FAVORITE.equals(tag) && folderId >= 0) {
-                    final long id = addAppShortcut(db, childValues, parser);
-                    if (id >= 0) {
-                        folderItems.add(id);
-                    }
-                } else if (TAG_SHORTCUT.equals(tag) && folderId >= 0) {
-                    final long id = addUriShortcut(db, childValues, res, parser);
-                    if (id >= 0) {
-                        folderItems.add(id);
-                    }
-                } else if (TAG_INCLUDE.equals(tag) && folderId >= 0) {
-                    addToFolder(db, res, parser, folderItems, folderId);
-                } else {
-                    throw new RuntimeException("Folders can contain only shortcuts");
-                }
-            }
-        }
-
-        /**
-         * Parse folder starting at current {@link XmlPullParser} location.
-         */
-        private boolean loadFolder(SQLiteDatabase db, ContentValues values, Resources res,
-                XmlResourceParser parser) throws IOException, XmlPullParserException {
-            final String title;
-            final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
-            if (titleResId != 0) {
-                title = res.getString(titleResId);
-            } else {
-                title = mContext.getResources().getString(R.string.folder_name);
-            }
-
-            values.put(LauncherSettings.Favorites.TITLE, title);
-            long folderId = addFolder(db, values);
-            boolean added = folderId >= 0;
-
-            ArrayList<Long> folderItems = new ArrayList<Long>();
-            addToFolder(db, res, parser, folderItems, folderId);
-
-            // We can only have folders with >= 2 items, so we need to remove the
-            // folder and clean up if less than 2 items were included, or some
-            // failed to add, and less than 2 were actually added
-            if (folderItems.size() < 2 && folderId >= 0) {
-                // Delete the folder
-                deleteId(db, folderId);
-
-                // If we have a single item, promote it to where the folder
-                // would have been.
-                if (folderItems.size() == 1) {
-                    final ContentValues childValues = new ContentValues();
-                    copyInteger(values, childValues, LauncherSettings.Favorites.CONTAINER);
-                    copyInteger(values, childValues, LauncherSettings.Favorites.SCREEN);
-                    copyInteger(values, childValues, LauncherSettings.Favorites.CELLX);
-                    copyInteger(values, childValues, LauncherSettings.Favorites.CELLY);
-
-                    final long id = folderItems.get(0);
-                    db.update(TABLE_FAVORITES, childValues,
-                            LauncherSettings.Favorites._ID + "=" + id, null);
-                } else {
-                    added = false;
-                }
-            }
-            return added;
-        }
-
-        // A meta shortcut attempts to resolve an intent specified as a URI in the XML, if a
-        // logical choice for what shortcut should be used for that intent exists, then it is
-        // added. Otherwise add nothing.
-        private long addAppShortcutByUri(SQLiteDatabase db, ContentValues values,
-                String intentUri) {
-            Intent metaIntent;
-            try {
-                metaIntent = Intent.parseUri(intentUri, 0);
-            } catch (URISyntaxException e) {
-                Log.e(TAG, "Unable to add meta-favorite: " + intentUri, e);
-                return -1;
-            }
-
-            ResolveInfo resolved = mPackageManager.resolveActivity(metaIntent,
-                    PackageManager.MATCH_DEFAULT_ONLY);
-            final List<ResolveInfo> appList = mPackageManager.queryIntentActivities(
-                    metaIntent, PackageManager.MATCH_DEFAULT_ONLY);
-
-            // Verify that the result is an app and not just the resolver dialog asking which
-            // app to use.
-            if (wouldLaunchResolverActivity(resolved, appList)) {
-                // If only one of the results is a system app then choose that as the default.
-                final ResolveInfo systemApp = getSingleSystemActivity(appList);
-                if (systemApp == null) {
-                    // There is no logical choice for this meta-favorite, so rather than making
-                    // a bad choice just add nothing.
-                    Log.w(TAG, "No preference or single system activity found for "
-                            + metaIntent.toString());
-                    return -1;
-                }
-                resolved = systemApp;
-            }
-            final ActivityInfo info = resolved.activityInfo;
-            final Intent intent = mPackageManager.getLaunchIntentForPackage(info.packageName);
-            if (intent == null) {
-                return -1;
-            }
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
-                    Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-
-            return addAppShortcut(db, values, info.loadLabel(mPackageManager).toString(), intent);
-        }
-
-        private ResolveInfo getSingleSystemActivity(List<ResolveInfo> appList) {
-            ResolveInfo systemResolve = null;
-            final int N = appList.size();
-            for (int i = 0; i < N; ++i) {
-                try {
-                    ApplicationInfo info = mPackageManager.getApplicationInfo(
-                            appList.get(i).activityInfo.packageName, 0);
-                    if ((info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
-                        if (systemResolve != null) {
-                            return null;
-                        } else {
-                            systemResolve = appList.get(i);
-                        }
-                    }
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.w(TAG, "Unable to get info about resolve results", e);
-                    return null;
-                }
-            }
-            return systemResolve;
-        }
-
-        private boolean wouldLaunchResolverActivity(ResolveInfo resolved,
-                List<ResolveInfo> appList) {
-            // If the list contains the above resolved activity, then it can't be
-            // ResolverActivity itself.
-            for (int i = 0; i < appList.size(); ++i) {
-                ResolveInfo tmp = appList.get(i);
-                if (tmp.activityInfo.name.equals(resolved.activityInfo.name)
-                        && tmp.activityInfo.packageName.equals(resolved.activityInfo.packageName)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private long addAppShortcut(SQLiteDatabase db, ContentValues values,
-                XmlResourceParser parser) {
-            final String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
-            final String className = getAttributeValue(parser, ATTR_CLASS_NAME);
-            final String uri = getAttributeValue(parser, ATTR_URI);
-
-            if (!TextUtils.isEmpty(packageName) && !TextUtils.isEmpty(className)) {
-                ActivityInfo info;
-                try {
-                    ComponentName cn;
-                    try {
-                        cn = new ComponentName(packageName, className);
-                        info = mPackageManager.getActivityInfo(cn, 0);
-                    } catch (PackageManager.NameNotFoundException nnfe) {
-                        String[] packages = mPackageManager.currentToCanonicalPackageNames(
-                                new String[] { packageName });
-                        cn = new ComponentName(packages[0], className);
-                        info = mPackageManager.getActivityInfo(cn, 0);
-                    }
-                    final Intent intent = buildMainIntent();
-                    intent.setComponent(cn);
-                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
-                            Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
-
-                    return addAppShortcut(db, values, info.loadLabel(mPackageManager).toString(),
-                            intent);
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.w(TAG, "Unable to add favorite: " + packageName +
-                            "/" + className, e);
-                }
-                return -1;
-            } else if (!TextUtils.isEmpty(uri)) {
-                // If no component specified try to find a shortcut to add from the URI.
-                return addAppShortcutByUri(db, values, uri);
-            } else {
-                Log.e(TAG, "Skipping invalid <favorite> with no component or uri");
-                return -1;
-            }
-        }
-
-        private long addAppShortcut(SQLiteDatabase db, ContentValues values, String title,
-                Intent intent) {
-            long id = generateNewItemId();
-            values.put(Favorites.INTENT, intent.toUri(0));
-            values.put(Favorites.TITLE, title);
-            values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPLICATION);
-            values.put(Favorites.SPANX, 1);
-            values.put(Favorites.SPANY, 1);
-            values.put(Favorites._ID, id);
-            if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
-                return -1;
-            } else {
-                return id;
-            }
-        }
-
-        private long addFolder(SQLiteDatabase db, ContentValues values) {
-            values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_FOLDER);
-            values.put(Favorites.SPANX, 1);
-            values.put(Favorites.SPANY, 1);
-            long id = generateNewItemId();
-            values.put(Favorites._ID, id);
-            if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) <= 0) {
-                return -1;
-            } else {
-                return id;
-            }
-        }
-
         private ComponentName getSearchWidgetProvider() {
-            SearchManager searchManager =
-                    (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
-            ComponentName searchComponent = searchManager.getGlobalSearchActivity();
-            if (searchComponent == null) return null;
-            return getProviderInPackage(searchComponent.getPackageName());
-        }
-
-        /**
-         * Gets an appwidget provider from the given package. If the package contains more than
-         * one appwidget provider, an arbitrary one is returned.
-         */
-        private ComponentName getProviderInPackage(String packageName) {
-            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
-            List<AppWidgetProviderInfo> providers = appWidgetManager.getInstalledProviders();
-            if (providers == null) return null;
-            final int providerCount = providers.size();
-            for (int i = 0; i < providerCount; i++) {
-                ComponentName provider = providers.get(i).provider;
-                if (provider != null && provider.getPackageName().equals(packageName)) {
-                    return provider;
-                }
-            }
-            return null;
-        }
-
-        private boolean addAppWidget(XmlResourceParser parser, int type,
-                SQLiteDatabase db, ContentValues values)
-                throws XmlPullParserException, IOException {
-
-            String packageName = getAttributeValue(parser, ATTR_PACKAGE_NAME);
-            String className = getAttributeValue(parser, ATTR_CLASS_NAME);
-
-            if (packageName == null || className == null) {
-                return false;
-            }
-
-            boolean hasPackage = true;
-            ComponentName cn = new ComponentName(packageName, className);
-            try {
-                mPackageManager.getReceiverInfo(cn, 0);
-            } catch (Exception e) {
-                String[] packages = mPackageManager.currentToCanonicalPackageNames(
-                        new String[] { packageName });
-                cn = new ComponentName(packages[0], className);
-                try {
-                    mPackageManager.getReceiverInfo(cn, 0);
-                } catch (Exception e1) {
-                    System.out.println("Can't find widget provider: " + className);
-                    hasPackage = false;
-                }
-            }
-
-            if (hasPackage) {
-                String spanX = getAttributeValue(parser, ATTR_SPAN_X);
-                String spanY = getAttributeValue(parser, ATTR_SPAN_Y);
-
-                values.put(Favorites.SPANX, spanX);
-                values.put(Favorites.SPANY, spanY);
-
-                // Read the extras
-                Bundle extras = new Bundle();
-                int widgetDepth = parser.getDepth();
-                while ((type = parser.next()) != XmlPullParser.END_TAG ||
-                        parser.getDepth() > widgetDepth) {
-                    if (type != XmlPullParser.START_TAG) {
-                        continue;
-                    }
-
-                    if (TAG_EXTRA.equals(parser.getName())) {
-                        String key = getAttributeValue(parser, ATTR_KEY);
-                        String value = getAttributeValue(parser, ATTR_VALUE);
-                        if (key != null && value != null) {
-                            extras.putString(key, value);
-                        } else {
-                            throw new RuntimeException("Widget extras must have a key and value");
-                        }
-                    } else {
-                        throw new RuntimeException("Widgets can contain only extras");
-                    }
-                }
-
-                return addAppWidget(db, values, cn, extras);
-            }
-
-            return false;
-        }
-
-        private boolean addAppWidget(SQLiteDatabase db, ContentValues values, ComponentName cn,
-               Bundle extras) {
-            boolean allocatedAppWidgets = false;
-            final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
-
-            try {
-                int appWidgetId = mAppWidgetHost.allocateAppWidgetId();
-
-                values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_APPWIDGET);
-                values.put(Favorites.APPWIDGET_ID, appWidgetId);
-                values.put(Favorites.APPWIDGET_PROVIDER, cn.flattenToString());
-                values.put(Favorites._ID, generateNewItemId());
-                dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values);
-
-                allocatedAppWidgets = true;
-
-                // TODO: need to check return value
-                appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, cn);
-
-                // Send a broadcast to configure the widget
-                if (extras != null && !extras.isEmpty()) {
-                    Intent intent = new Intent(ACTION_APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE);
-                    intent.setComponent(cn);
-                    intent.putExtras(extras);
-                    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
-                    mContext.sendBroadcast(intent);
-                }
-            } catch (RuntimeException ex) {
-                Log.e(TAG, "Problem allocating appWidgetId", ex);
-            }
-
-            return allocatedAppWidgets;
-        }
-
-        private long addUriShortcut(SQLiteDatabase db, ContentValues values, Resources res,
-                XmlResourceParser parser) {
-            final int iconResId = getAttributeResourceValue(parser, ATTR_ICON, 0);
-            final int titleResId = getAttributeResourceValue(parser, ATTR_TITLE, 0);
-
-            Intent intent;
-            String uri = null;
-            try {
-                uri = getAttributeValue(parser, ATTR_URI);
-                intent = Intent.parseUri(uri, 0);
-            } catch (URISyntaxException e) {
-                Log.w(TAG, "Shortcut has malformed uri: " + uri);
-                return -1; // Oh well
-            }
-
-            if (iconResId == 0 || titleResId == 0) {
-                Log.w(TAG, "Shortcut is missing title or icon resource ID");
-                return -1;
-            }
-
-            long id = generateNewItemId();
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
-            values.put(Favorites.INTENT, intent.toUri(0));
-            values.put(Favorites.TITLE, res.getString(titleResId));
-            values.put(Favorites.ITEM_TYPE, Favorites.ITEM_TYPE_SHORTCUT);
-            values.put(Favorites.SPANX, 1);
-            values.put(Favorites.SPANY, 1);
-            values.put(Favorites.ICON_TYPE, Favorites.ICON_TYPE_RESOURCE);
-            values.put(Favorites.ICON_PACKAGE, res.getResourcePackageName(iconResId));
-            values.put(Favorites.ICON_RESOURCE, res.getResourceName(iconResId));
-            values.put(Favorites._ID, id);
-
-            if (dbInsertAndCheck(this, db, TABLE_FAVORITES, null, values) < 0) {
-                return -1;
-            }
-            return id;
+            AppWidgetProviderInfo searchProvider = Utilities.getSearchWidgetProvider(mContext);
+            return (searchProvider == null) ? null : searchProvider.provider;
         }
 
         private void migrateLauncher2Shortcuts(SQLiteDatabase db, Uri uri) {
@@ -2039,6 +1432,12 @@
                                 userHandle = UserHandleCompat.myUserHandle();
                                 userSerialNumber = userManager.getSerialNumberForUser(userHandle);
                             }
+
+                            if (userHandle == null) {
+                                Launcher.addDumpLog(TAG, "skipping deleted user", true);
+                                continue;
+                            }
+
                             Launcher.addDumpLog(TAG, "migrating \""
                                 + c.getString(titleIndex) + "\" ("
                                 + cellX + "," + cellY + "@"
@@ -2077,9 +1476,13 @@
 
                                     // Canonicalize
                                     // the Play Store sets the package parameter, but Launcher
-                                    // does not, so we clear that out to keep them the same
+                                    // does not, so we clear that out to keep them the same.
+                                    // Also ignore intent flags for the purposes of deduping.
                                     intent.setPackage(null);
+                                    int flags = intent.getFlags();
+                                    intent.setFlags(0);
                                     final String key = intent.toUri(0);
+                                    intent.setFlags(flags);
                                     if (seenIntents.contains(key)) {
                                         Launcher.addDumpLog(TAG, "skipping duplicate", true);
                                         continue;
@@ -2250,38 +1653,6 @@
         return selectWhere.toString();
     }
 
-    /**
-     * Return attribute value, attempting launcher-specific namespace first
-     * before falling back to anonymous attribute.
-     */
-    private static String getAttributeValue(XmlResourceParser parser, String attribute) {
-        String value = parser.getAttributeValue(
-                "http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute);
-        if (value == null) {
-            value = parser.getAttributeValue(null, attribute);
-        }
-        return value;
-    }
-
-    /**
-     * Return attribute resource value, attempting launcher-specific namespace
-     * first before falling back to anonymous attribute.
-     */
-    private static int getAttributeResourceValue(XmlResourceParser parser, String attribute,
-            int defaultValue) {
-        int value = parser.getAttributeResourceValue(
-                "http://schemas.android.com/apk/res-auto/com.android.launcher3", attribute,
-                defaultValue);
-        if (value == defaultValue) {
-            value = parser.getAttributeResourceValue(null, attribute, defaultValue);
-        }
-        return value;
-    }
-
-    private static void copyInteger(ContentValues from, ContentValues to, String key) {
-        to.put(key, from.getAsInteger(key));
-    }
-
     static class SqlArguments {
         public final String table;
         public final String where;
@@ -2313,29 +1684,4 @@
             }
         }
     }
-
-    static interface WorkspaceLoader {
-        /**
-         * @param screenIds A mutable list of screen its
-         * @return the number of workspace items added.
-         */
-        int loadLayout(SQLiteDatabase db, ArrayList<Long> screenIds);
-    }
-
-    private static class SimpleWorkspaceLoader implements WorkspaceLoader {
-        private final Resources mRes;
-        private final int mWorkspaceId;
-        private final DatabaseHelper mHelper;
-
-        SimpleWorkspaceLoader(DatabaseHelper helper, Resources res, int workspaceId) {
-            mHelper = helper;
-            mRes = res;
-            mWorkspaceId = workspaceId;
-        }
-
-        @Override
-        public int loadLayout(SQLiteDatabase db, ArrayList<Long> screenIds) {
-            return mHelper.loadFavoritesRecursive(db, mRes, mWorkspaceId, screenIds);
-        }
-    }
 }
diff --git a/src/com/android/launcher3/LauncherRootView.java b/src/com/android/launcher3/LauncherRootView.java
new file mode 100644
index 0000000..e8c11c4
--- /dev/null
+++ b/src/com/android/launcher3/LauncherRootView.java
@@ -0,0 +1,17 @@
+package com.android.launcher3;
+
+import android.content.Context;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+
+public class LauncherRootView extends InsettableFrameLayout {
+    public LauncherRootView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected boolean fitSystemWindows(Rect insets) {
+        setInsets(insets);
+        return true; // I'll take it from here
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 48fc0c9..7d65f46 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -204,6 +204,8 @@
 
     protected boolean mAllowLongPress = true;
 
+    private boolean mWasInOverscroll = false;
+
     // Page Indicator
     private int mPageIndicatorViewId;
     private PageIndicator mPageIndicator;
@@ -625,6 +627,7 @@
 
     // a method that subclasses can override to add behavior
     protected void onPageEndMoving() {
+        mWasInOverscroll = false;
     }
 
     /**
@@ -663,6 +666,7 @@
         if (isXBeforeFirstPage) {
             super.scrollTo(0, y);
             if (mAllowOverScroll) {
+                mWasInOverscroll = true;
                 if (isRtl) {
                     overScroll(x - mMaxScrollX);
                 } else {
@@ -672,6 +676,7 @@
         } else if (isXAfterLastPage) {
             super.scrollTo(mMaxScrollX, y);
             if (mAllowOverScroll) {
+                mWasInOverscroll = true;
                 if (isRtl) {
                     overScroll(x);
                 } else {
@@ -679,6 +684,10 @@
                 }
             }
         } else {
+            if (mWasInOverscroll) {
+                overScroll(0);
+                mWasInOverscroll = false;
+            }
             mOverScrollX = x;
             super.scrollTo(x, y);
         }
@@ -1513,6 +1522,7 @@
                 mLastMotionXRemainder = 0;
                 mTouchX = getViewportOffsetX() + getScrollX();
                 mSmoothingTime = System.nanoTime() / NANOTIME_DIV;
+                onScrollInteractionBegin();
                 pageBeginMoving();
             }
         }
@@ -1752,6 +1762,7 @@
             mActivePointerId = ev.getPointerId(0);
 
             if (mTouchState == TOUCH_STATE_SCROLLING) {
+                onScrollInteractionBegin();
                 pageBeginMoving();
             }
             break;
@@ -1940,6 +1951,7 @@
                             getScrollY(), vX, 0, Integer.MIN_VALUE, Integer.MAX_VALUE, 0, 0);
                     invalidate();
                 }
+                onScrollInteractionEnd();
             } else if (mTouchState == TOUCH_STATE_PREV_PAGE) {
                 // at this point we have not moved beyond the touch slop
                 // (otherwise mTouchState would be TOUCH_STATE_SCROLLING), so
@@ -2025,6 +2037,15 @@
         mActivePointerId = INVALID_POINTER;
     }
 
+    /**
+     * Triggered by scrolling via touch
+     */
+    protected void onScrollInteractionBegin() {
+    }
+
+    protected void onScrollInteractionEnd() {
+    }
+
     protected void onUnhandledTap(MotionEvent ev) {
         ((Launcher) getContext()).onClick(this);
     }
diff --git a/src/com/android/launcher3/PagedViewWidgetImageView.java b/src/com/android/launcher3/PagedViewWidgetImageView.java
index 71f5eea..7d82795 100644
--- a/src/com/android/launcher3/PagedViewWidgetImageView.java
+++ b/src/com/android/launcher3/PagedViewWidgetImageView.java
@@ -21,7 +21,7 @@
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
-class PagedViewWidgetImageView extends ImageView {
+public class PagedViewWidgetImageView extends ImageView {
     public boolean mAllowRequestLayout = true;
 
     public PagedViewWidgetImageView(Context context, AttributeSet attrs) {
diff --git a/src/com/android/launcher3/PagedViewWithDraggableItems.java b/src/com/android/launcher3/PagedViewWithDraggableItems.java
index 2a29c33..0e59369 100644
--- a/src/com/android/launcher3/PagedViewWithDraggableItems.java
+++ b/src/com/android/launcher3/PagedViewWithDraggableItems.java
@@ -91,6 +91,10 @@
         return super.onTouchEvent(ev);
     }
 
+    public void trimMemory() {
+        mLastTouchedItem = null;
+    }
+
     @Override
     public boolean onTouch(View v, MotionEvent event) {
         mLastTouchedItem = v;
diff --git a/src/com/android/launcher3/PendingAppWidgetHostView.java b/src/com/android/launcher3/PendingAppWidgetHostView.java
index d23a330..179c60a 100644
--- a/src/com/android/launcher3/PendingAppWidgetHostView.java
+++ b/src/com/android/launcher3/PendingAppWidgetHostView.java
@@ -41,9 +41,9 @@
     private final LauncherAppWidgetInfo mInfo;
     private final int mStartState;
     private final Intent mIconLookupIntent;
+    private final boolean mDisabledForSafeMode;
 
     private Bitmap mIcon;
-    private PreloadIconDrawable mDrawable;
 
     private Drawable mCenterDrawable;
     private Drawable mTopCornerDrawable;
@@ -53,11 +53,13 @@
     private final TextPaint mPaint;
     private Layout mSetupTextLayout;
 
-    public PendingAppWidgetHostView(Context context, LauncherAppWidgetInfo info) {
+    public PendingAppWidgetHostView(Context context, LauncherAppWidgetInfo info,
+            boolean disabledForSafeMode) {
         super(context);
         mInfo = info;
         mStartState = info.restoreStatus;
         mIconLookupIntent = new Intent().setComponent(info.providerName);
+        mDisabledForSafeMode = disabledForSafeMode;
 
         mPaint = new TextPaint();
         mPaint.setColor(0xFFFFFFFF);
@@ -106,14 +108,21 @@
             return;
         }
         mIcon = icon;
-        if (mDrawable != null) {
-            mDrawable.setCallback(null);
-            mDrawable = null;
+        if (mCenterDrawable != null) {
+            mCenterDrawable.setCallback(null);
+            mCenterDrawable = null;
         }
         if (mIcon != null) {
-            // The view displays two modes, one with a setup icon and another with a preload icon
-            // in the center.
-            if (isReadyForClickSetup()) {
+            // The view displays three modes,
+            //   1) App icon in the center
+            //   2) Preload icon in the center
+            //   3) Setup icon in the center and app icon in the top right corner.
+            if (mDisabledForSafeMode) {
+                FastBitmapDrawable disabledIcon = Utilities.createIconDrawable(mIcon);
+                disabledIcon.setGhostModeEnabled(true);
+                mCenterDrawable = disabledIcon;
+                mTopCornerDrawable = null;
+            } else if (isReadyForClickSetup()) {
                 mCenterDrawable = getResources().getDrawable(R.drawable.ic_setting);
                 mTopCornerDrawable = new FastBitmapDrawable(mIcon);
             } else {
@@ -123,8 +132,9 @@
                 }
 
                 FastBitmapDrawable drawable = Utilities.createIconDrawable(mIcon);
-                mDrawable = new PreloadIconDrawable(drawable, sPreloaderTheme);
-                mDrawable.setCallback(this);
+                mCenterDrawable = new PreloadIconDrawable(drawable, sPreloaderTheme);
+                mCenterDrawable.setCallback(this);
+                mTopCornerDrawable = null;
                 applyState();
             }
             mDrawableSizeChanged = true;
@@ -133,12 +143,12 @@
 
     @Override
     protected boolean verifyDrawable(Drawable who) {
-        return (who == mDrawable) || super.verifyDrawable(who);
+        return (who == mCenterDrawable) || super.verifyDrawable(who);
     }
 
     public void applyState() {
-        if (mDrawable != null) {
-            mDrawable.setLevel(Math.max(mInfo.installProgress, 0));
+        if (mCenterDrawable != null) {
+            mCenterDrawable.setLevel(Math.max(mInfo.installProgress, 0));
         }
     }
 
@@ -158,23 +168,30 @@
 
     @Override
     protected void onDraw(Canvas canvas) {
-        if (mDrawable != null) {
+        if (mCenterDrawable == null) {
+            // Nothing to draw
+            return;
+        }
+
+        if (mTopCornerDrawable == null) {
             if (mDrawableSizeChanged) {
+                int outset = (mCenterDrawable instanceof PreloadIconDrawable) ?
+                        ((PreloadIconDrawable) mCenterDrawable).getOutset() : 0;
                 int maxSize = LauncherAppState.getInstance().getDynamicGrid()
-                        .getDeviceProfile().iconSizePx + 2 * mDrawable.getOutset();
+                        .getDeviceProfile().iconSizePx + 2 * outset;
                 int size = Math.min(maxSize, Math.min(
                         getWidth() - getPaddingLeft() - getPaddingRight(),
                         getHeight() - getPaddingTop() - getPaddingBottom()));
 
                 mRect.set(0, 0, size, size);
-                mRect.inset(mDrawable.getOutset(), mDrawable.getOutset());
+                mRect.inset(outset, outset);
                 mRect.offsetTo((getWidth() - mRect.width()) / 2, (getHeight() - mRect.height()) / 2);
-                mDrawable.setBounds(mRect);
+                mCenterDrawable.setBounds(mRect);
                 mDrawableSizeChanged = false;
             }
-
-            mDrawable.draw(canvas);
-        } else if ((mCenterDrawable != null) && (mTopCornerDrawable != null)) {
+            mCenterDrawable.draw(canvas);
+        } else  {
+            // Draw the top corner icon and "Setup" text is possible
             if (mDrawableSizeChanged) {
                 DeviceProfile grid = getDeviceProfile();
                 int iconSize = grid.iconSizePx;
diff --git a/src/com/android/launcher3/SearchDropTargetBar.java b/src/com/android/launcher3/SearchDropTargetBar.java
index 435dbda..99c2e08 100644
--- a/src/com/android/launcher3/SearchDropTargetBar.java
+++ b/src/com/android/launcher3/SearchDropTargetBar.java
@@ -19,9 +19,9 @@
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ObjectAnimator;
+import android.animation.ValueAnimator;
 import android.content.Context;
 import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
 import android.util.AttributeSet;
 import android.view.View;
 import android.view.animation.AccelerateInterpolator;
@@ -37,7 +37,7 @@
     private static final int sTransitionOutDuration = 175;
 
     private ObjectAnimator mDropTargetBarAnim;
-    private ObjectAnimator mQSBSearchBarAnim;
+    private ValueAnimator mQSBSearchBarAnim;
     private static final AccelerateInterpolator sAccelerateInterpolator =
             new AccelerateInterpolator();
 
@@ -49,7 +49,6 @@
     private int mBarHeight;
     private boolean mDeferOnDragEnd = false;
 
-    private Drawable mPreviousBackground;
     private boolean mEnableDropDownDropTargets;
 
     public SearchDropTargetBar(Context context, AttributeSet attrs) {
@@ -69,29 +68,42 @@
         dragController.setFlingToDeleteDropTarget(mDeleteDropTarget);
         mInfoDropTarget.setLauncher(launcher);
         mDeleteDropTarget.setLauncher(launcher);
-        mQSBSearchBar = launcher.getQsbBar();
-        if (mEnableDropDownDropTargets) {
-            mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
-                    -mBarHeight);
+    }
+
+    public void setQsbSearchBar(View qsb) {
+        mQSBSearchBar = qsb;
+        if (mQSBSearchBar != null) {
+            if (mEnableDropDownDropTargets) {
+                mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "translationY", 0,
+                        -mBarHeight);
+            } else {
+                mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
+            }
+            setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
         } else {
-            mQSBSearchBarAnim = LauncherAnimUtils.ofFloat(mQSBSearchBar, "alpha", 1f, 0f);
+            // Create a no-op animation of the search bar is null
+            mQSBSearchBarAnim = ValueAnimator.ofFloat(0, 0);
+            mQSBSearchBarAnim.setDuration(sTransitionInDuration);
         }
-        setupAnimation(mQSBSearchBarAnim, mQSBSearchBar);
     }
 
     private void prepareStartAnimation(View v) {
         // Enable the hw layers before the animation starts (will be disabled in the onAnimationEnd
         // callback below)
-        v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        if (v != null) {
+            v.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+        }
     }
 
-    private void setupAnimation(ObjectAnimator anim, final View v) {
+    private void setupAnimation(ValueAnimator anim, final View v) {
         anim.setInterpolator(sAccelerateInterpolator);
         anim.setDuration(sTransitionInDuration);
         anim.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                v.setLayerType(View.LAYER_TYPE_NONE, null);
+                if (v != null) {
+                    v.setLayerType(View.LAYER_TYPE_NONE, null);
+                }
             }
         });
     }
@@ -145,9 +157,9 @@
             mQSBSearchBarAnim.reverse();
         } else {
             mQSBSearchBarAnim.cancel();
-            if (mEnableDropDownDropTargets) {
+            if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
                 mQSBSearchBar.setTranslationY(0);
-            } else {
+            } else if (mQSBSearchBar != null) {
                 mQSBSearchBar.setAlpha(1f);
             }
         }
@@ -161,9 +173,9 @@
             mQSBSearchBarAnim.start();
         } else {
             mQSBSearchBarAnim.cancel();
-            if (mEnableDropDownDropTargets) {
+            if (mQSBSearchBar != null && mEnableDropDownDropTargets) {
                 mQSBSearchBar.setTranslationY(-mBarHeight);
-            } else {
+            } else if (mQSBSearchBar != null) {
                 mQSBSearchBar.setAlpha(0f);
             }
         }
@@ -213,20 +225,6 @@
         }
     }
 
-    public void onSearchPackagesChanged(boolean searchVisible, boolean voiceVisible) {
-        if (mQSBSearchBar != null) {
-            Drawable bg = mQSBSearchBar.getBackground();
-            if (bg != null && (!searchVisible && !voiceVisible)) {
-                // Save the background and disable it
-                mPreviousBackground = bg;
-                mQSBSearchBar.setBackgroundResource(0);
-            } else if (mPreviousBackground != null && (searchVisible || voiceVisible)) {
-                // Restore the background
-                mQSBSearchBar.setBackground(mPreviousBackground);
-            }
-        }
-    }
-
     public Rect getSearchBarBounds() {
         if (mQSBSearchBar != null) {
             final int[] pos = new int[2];
diff --git a/src/com/android/launcher3/ShortcutInfo.java b/src/com/android/launcher3/ShortcutInfo.java
index daf3434..01f7931 100644
--- a/src/com/android/launcher3/ShortcutInfo.java
+++ b/src/com/android/launcher3/ShortcutInfo.java
@@ -88,10 +88,20 @@
     private Bitmap mIcon;
 
     /**
+     * Indicates that the icon is disabled due to safe mode restrictions.
+     */
+    public static final int FLAG_DISABLED_SAFEMODE = 1;
+
+    /**
+     * Indicates that the icon is disabled as the app is not available.
+     */
+    public static final int FLAG_DISABLED_NOT_AVAILABLE = 2;
+
+    /**
      * Could be disabled, if the the app is installed but unavailable (eg. in safe mode or when
      * sd-card is not available).
      */
-    boolean isDisabled = false;
+    int isDisabled = DEFAULT;
 
     int status;
 
diff --git a/src/com/android/launcher3/Stats.java b/src/com/android/launcher3/Stats.java
index f3977e4..a879865 100644
--- a/src/com/android/launcher3/Stats.java
+++ b/src/com/android/launcher3/Stats.java
@@ -38,12 +38,10 @@
     public static final String EXTRA_CELLX = "cellX";
     public static final String EXTRA_CELLY = "cellY";
 
-    private static final String LOG_FILE_NAME = "launches.log";
     private static final int LOG_VERSION = 1;
     private static final int LOG_TAG_VERSION = 0x1;
     private static final int LOG_TAG_LAUNCH = 0x1000;
 
-    private static final String STATS_FILE_NAME = "stats.log";
     private static final int STATS_VERSION = 1;
     private static final int INITIAL_STATS_SIZE = 100;
 
@@ -69,7 +67,8 @@
 
         if (LOCAL_LAUNCH_LOG) {
             try {
-                mLog = new DataOutputStream(mLauncher.openFileOutput(LOG_FILE_NAME, Context.MODE_APPEND));
+                mLog = new DataOutputStream(mLauncher.openFileOutput(
+                        LauncherFiles.LAUNCHES_LOG, Context.MODE_APPEND));
                 mLog.writeInt(LOG_TAG_VERSION);
                 mLog.writeInt(LOG_VERSION);
             } catch (FileNotFoundException e) {
@@ -160,7 +159,8 @@
     private void saveStats() {
         DataOutputStream stats = null;
         try {
-            stats = new DataOutputStream(mLauncher.openFileOutput(STATS_FILE_NAME + ".tmp", Context.MODE_PRIVATE));
+            stats = new DataOutputStream(mLauncher.openFileOutput(
+                    LauncherFiles.STATS_LOG + ".tmp", Context.MODE_PRIVATE));
             stats.writeInt(STATS_VERSION);
             final int N = mHistogram.size();
             stats.writeInt(N);
@@ -170,8 +170,8 @@
             }
             stats.close();
             stats = null;
-            mLauncher.getFileStreamPath(STATS_FILE_NAME + ".tmp")
-                     .renameTo(mLauncher.getFileStreamPath(STATS_FILE_NAME));
+            mLauncher.getFileStreamPath(LauncherFiles.STATS_LOG + ".tmp")
+                     .renameTo(mLauncher.getFileStreamPath(LauncherFiles.STATS_LOG));
         } catch (FileNotFoundException e) {
             Log.e(TAG, "unable to create stats data: " + e);
         } catch (IOException e) {
@@ -190,7 +190,7 @@
         mHistogram = new ArrayList<Integer>(INITIAL_STATS_SIZE);
         DataInputStream stats = null;
         try {
-            stats = new DataInputStream(mLauncher.openFileInput(STATS_FILE_NAME));
+            stats = new DataInputStream(mLauncher.openFileInput(LauncherFiles.STATS_LOG));
             final int version = stats.readInt();
             if (version == STATS_VERSION) {
                 final int N = stats.readInt();
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 1a7c9fc..215d63d 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -16,7 +16,11 @@
 
 package com.android.launcher3;
 
+import android.annotation.TargetApi;
 import android.app.Activity;
+import android.app.SearchManager;
+import android.appwidget.AppWidgetManager;
+import android.appwidget.AppWidgetProviderInfo;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
 import android.content.Context;
@@ -54,8 +58,6 @@
 
     private static int sIconWidth = -1;
     private static int sIconHeight = -1;
-    public static int sIconTextureWidth = -1;
-    public static int sIconTextureHeight = -1;
 
     private static final Rect sOldBounds = new Rect();
     private static final Canvas sCanvas = new Canvas();
@@ -89,10 +91,10 @@
      * Resizes an icon drawable to the correct icon size.
      */
     static void resizeIconDrawable(Drawable icon) {
-        icon.setBounds(0, 0, sIconTextureWidth, sIconTextureHeight);
+        icon.setBounds(0, 0, sIconWidth, sIconHeight);
     }
 
-    private static boolean isPropertyEnabled(String propertyName) {
+    public static boolean isPropertyEnabled(String propertyName) {
         return Log.isLoggable(propertyName, Log.VERBOSE);
     }
 
@@ -110,29 +112,39 @@
     }
 
     /**
-     * Returns a bitmap suitable for the all apps view. Used to convert pre-ICS
-     * icon bitmaps that are stored in the database (which were 74x74 pixels at hdpi size)
-     * to the proper size (48dp)
+     * Returns a bitmap suitable for the all apps view. If the package or the resource do not
+     * exist, it returns null.
+     */
+    static Bitmap createIconBitmap(String packageName, String resourceName, IconCache cache,
+            Context context) {
+        PackageManager packageManager = context.getPackageManager();
+        // the resource
+        try {
+            Resources resources = packageManager.getResourcesForApplication(packageName);
+            if (resources != null) {
+                final int id = resources.getIdentifier(resourceName, null, null);
+                return createIconBitmap(
+                        resources.getDrawableForDensity(id, cache.getFullResIconDpi()), context);
+            }
+        } catch (Exception e) {
+            // Icon not found.
+        }
+        return null;
+    }
+
+    /**
+     * Returns a bitmap which is of the appropriate size to be displayed as an icon
      */
     static Bitmap createIconBitmap(Bitmap icon, Context context) {
-        int textureWidth = sIconTextureWidth;
-        int textureHeight = sIconTextureHeight;
-        int sourceWidth = icon.getWidth();
-        int sourceHeight = icon.getHeight();
-        if (sourceWidth > textureWidth && sourceHeight > textureHeight) {
-            // Icon is bigger than it should be; clip it (solves the GB->ICS migration case)
-            return Bitmap.createBitmap(icon,
-                    (sourceWidth - textureWidth) / 2,
-                    (sourceHeight - textureHeight) / 2,
-                    textureWidth, textureHeight);
-        } else if (sourceWidth == textureWidth && sourceHeight == textureHeight) {
-            // Icon is the right size, no need to change it
-            return icon;
-        } else {
-            // Icon is too small, render to a larger bitmap
-            final Resources resources = context.getResources();
-            return createIconBitmap(new BitmapDrawable(resources, icon), context);
+        synchronized (sCanvas) { // we share the statics :-(
+            if (sIconWidth == -1) {
+                initStatics(context);
+            }
         }
+        if (sIconWidth == icon.getWidth() && sIconHeight == icon.getHeight()) {
+            return icon;
+        }
+        return createIconBitmap(new BitmapDrawable(context.getResources(), icon), context);
     }
 
     /**
@@ -172,8 +184,8 @@
             }
 
             // no intrinsic size --> use default size
-            int textureWidth = sIconTextureWidth;
-            int textureHeight = sIconTextureHeight;
+            int textureWidth = sIconWidth;
+            int textureHeight = sIconHeight;
 
             final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
                     Bitmap.Config.ARGB_8888);
@@ -205,30 +217,6 @@
     }
 
     /**
-     * Returns a Bitmap representing the thumbnail of the specified Bitmap.
-     *
-     * @param bitmap The bitmap to get a thumbnail of.
-     * @param context The application's context.
-     *
-     * @return A thumbnail for the specified bitmap or the bitmap itself if the
-     *         thumbnail could not be created.
-     */
-    static Bitmap resampleIconBitmap(Bitmap bitmap, Context context) {
-        synchronized (sCanvas) { // we share the statics :-(
-            if (sIconWidth == -1) {
-                initStatics(context);
-            }
-
-            if (bitmap.getWidth() == sIconWidth && bitmap.getHeight() == sIconHeight) {
-                return bitmap;
-            } else {
-                final Resources resources = context.getResources();
-                return createIconBitmap(new BitmapDrawable(resources, bitmap), context);
-            }
-        }
-    }
-
-    /**
      * Given a coordinate relative to the descendant, find the coordinate in a parent view's
      * coordinates.
      *
@@ -330,12 +318,10 @@
     private static void initStatics(Context context) {
         final Resources resources = context.getResources();
         sIconWidth = sIconHeight = (int) resources.getDimension(R.dimen.app_icon_size);
-        sIconTextureWidth = sIconTextureHeight = sIconWidth;
     }
 
     public static void setIconSize(int widthPx) {
         sIconWidth = sIconHeight = widthPx;
-        sIconTextureWidth = sIconTextureHeight = widthPx;
     }
 
     public static void scaleRect(Rect r, float scale) {
@@ -513,4 +499,47 @@
         }
         return null;
     }
+
+    @TargetApi(Build.VERSION_CODES.KITKAT)
+    public static boolean isViewAttachedToWindow(View v) {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            return v.isAttachedToWindow();
+        } else {
+            // A proxy call which returns null, if the view is not attached to the window.
+            return v.getKeyDispatcherState() != null;
+        }
+    }
+
+    /**
+     * Returns a widget with category {@link AppWidgetProviderInfo#WIDGET_CATEGORY_SEARCHBOX}
+     * provided by the same package which is set to be global search activity.
+     * If widgetCategory is not supported, or no such widget is found, returns the first widget
+     * provided by the package.
+     */
+    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
+    public static AppWidgetProviderInfo getSearchWidgetProvider(Context context) {
+        SearchManager searchManager =
+                (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
+        ComponentName searchComponent = searchManager.getGlobalSearchActivity();
+        if (searchComponent == null) return null;
+        String providerPkg = searchComponent.getPackageName();
+
+        AppWidgetProviderInfo defaultWidgetForSearchPackage = null;
+
+        AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
+        for (AppWidgetProviderInfo info : appWidgetManager.getInstalledProviders()) {
+            if (info.provider.getPackageName().equals(providerPkg)) {
+                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
+                    if ((info.widgetCategory & AppWidgetProviderInfo.WIDGET_CATEGORY_SEARCHBOX) != 0) {
+                        return info;
+                    } else if (defaultWidgetForSearchPackage == null) {
+                        defaultWidgetForSearchPackage = info;
+                    }
+                } else {
+                    return info;
+                }
+            }
+        }
+        return defaultWidgetForSearchPackage;
+    }
 }
diff --git a/src/com/android/launcher3/WidgetPreviewLoader.java b/src/com/android/launcher3/WidgetPreviewLoader.java
index 5aa7190..4e6fe1f 100644
--- a/src/com/android/launcher3/WidgetPreviewLoader.java
+++ b/src/com/android/launcher3/WidgetPreviewLoader.java
@@ -12,6 +12,7 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteDiskIOException;
 import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteReadOnlyDatabaseException;
 import android.graphics.Bitmap;
 import android.graphics.Bitmap.Config;
 import android.graphics.BitmapFactory;
@@ -26,8 +27,8 @@
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
 import android.os.AsyncTask;
+import android.os.Build;
 import android.util.Log;
-
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 
 import java.io.ByteArrayOutputStream;
@@ -130,8 +131,8 @@
     private final PaintCache mDefaultAppWidgetPreviewPaint = new PaintCache();
     private final BitmapFactoryOptionsCache mCachedBitmapFactoryOptions = new BitmapFactoryOptionsCache();
 
-    private final HashMap<String, WeakReference<Bitmap>> mLoadedPreviews = new HashMap<>();
-    private final ArrayList<SoftReference<Bitmap>> mUnusedBitmaps = new ArrayList<>();
+    private final HashMap<String, WeakReference<Bitmap>> mLoadedPreviews = new HashMap<String, WeakReference<Bitmap>>();
+    private final ArrayList<SoftReference<Bitmap>> mUnusedBitmaps = new ArrayList<SoftReference<Bitmap>>();
 
     private final Context mContext;
     private final int mAppIconSize;
@@ -165,14 +166,24 @@
                 LauncherAppState.getSharedPreferencesKey(), Context.MODE_PRIVATE);
         final String lastVersionName = sp.getString(ANDROID_INCREMENTAL_VERSION_NAME_KEY, null);
         final String versionName = android.os.Build.VERSION.INCREMENTAL;
+        final boolean isLollipopOrGreater = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
         if (!versionName.equals(lastVersionName)) {
-            // clear all the previews whenever the system version changes, to ensure that previews
-            // are up-to-date for any apps that might have been updated with the system
-            clearDb();
-
-            SharedPreferences.Editor editor = sp.edit();
-            editor.putString(ANDROID_INCREMENTAL_VERSION_NAME_KEY, versionName);
-            editor.commit();
+            try {
+                // clear all the previews whenever the system version changes, to ensure that
+                // previews are up-to-date for any apps that might have been updated with the system
+                clearDb();
+            } catch (SQLiteReadOnlyDatabaseException e) {
+                if (isLollipopOrGreater) {
+                    // Workaround for Bug. 18554839, if we fail to clear the db due to the read-only
+                    // issue, then ignore this error and leave the old previews
+                } else {
+                    throw e;
+                }
+            } finally {
+                SharedPreferences.Editor editor = sp.edit();
+                editor.putString(ANDROID_INCREMENTAL_VERSION_NAME_KEY, versionName);
+                editor.commit();
+            }
         }
     }
 
@@ -287,7 +298,6 @@
 
     static class CacheDb extends SQLiteOpenHelper {
         final static int DB_VERSION = 2;
-        final static String DB_NAME = "widgetpreviews.db";
         final static String TABLE_NAME = "shortcut_and_widget_previews";
         final static String COLUMN_NAME = "name";
         final static String COLUMN_SIZE = "size";
@@ -295,7 +305,8 @@
         Context mContext;
 
         public CacheDb(Context context) {
-            super(context, new File(context.getCacheDir(), DB_NAME).getPath(), null, DB_VERSION);
+            super(context, new File(context.getCacheDir(),
+                    LauncherFiles.WIDGET_PREVIEWS_DB).getPath(), null, DB_VERSION);
             // Store the context for later use
             mContext = context;
         }
@@ -638,7 +649,7 @@
             c.setBitmap(null);
         }
         // Render the icon
-        Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info));
+        Drawable icon = mutateOnMainThread(mIconCache.getFullResIcon(info.activityInfo));
 
         int paddingTop = mContext.
                 getResources().getDimensionPixelOffset(R.dimen.shortcut_preview_padding_top);
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 774996e..8bd7991 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -67,6 +67,7 @@
 
 import com.android.launcher3.FolderIcon.FolderRingAnimator;
 import com.android.launcher3.Launcher.CustomContentCallbacks;
+import com.android.launcher3.Launcher.LauncherOverlay;
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.compat.PackageInstallerCompat.PackageInstallInfo;
@@ -282,6 +283,7 @@
     private float[] mNewAlphas;
     private int mLastChildCount = -1;
     private float mTransitionProgress;
+    private Animator mStateAnimator = null;
 
     float mOverScrollEffect = 0f;
 
@@ -289,6 +291,13 @@
     private boolean mDeferDropAfterUninstall;
     private boolean mUninstallSuccessful;
 
+    // State related to Launcher Overlay
+    LauncherOverlay mLauncherOverlay;
+    boolean mScrollInteractionBegan;
+    boolean mStartedSendingScrollEvents;
+    boolean mShouldSendPageSettled;
+    int mLastOverlaySroll = 0;
+
     private final Runnable mBindPages = new Runnable() {
         @Override
         public void run() {
@@ -1249,6 +1258,66 @@
             stripEmptyScreens();
             mStripScreensOnPageStopMoving = false;
         }
+
+        if (mShouldSendPageSettled) {
+            mLauncherOverlay.onScrollSettled();
+            mShouldSendPageSettled = false;
+        }
+    }
+
+    protected void onScrollInteractionBegin() {
+        super.onScrollInteractionEnd();
+        mScrollInteractionBegan = true;
+    }
+
+    protected void onScrollInteractionEnd() {
+        super.onScrollInteractionEnd();
+        mScrollInteractionBegan = false;
+        if (mStartedSendingScrollEvents) {
+            mStartedSendingScrollEvents = false;
+            mLauncherOverlay.onScrollInteractionEnd();
+        }
+    }
+
+    public void setLauncherOverlay(LauncherOverlay overlay) {
+        mLauncherOverlay = overlay;
+    }
+
+    @Override
+    protected void overScroll(float amount) {
+        boolean isRtl = isLayoutRtl();
+        boolean shouldOverScroll = (amount <= 0 && (!hasCustomContent() || isRtl)) ||
+                (amount >= 0 && (!hasCustomContent() || !isRtl));
+
+        boolean shouldScrollOverlay = mLauncherOverlay != null &&
+                ((amount <= 0 && !isRtl) || (amount >= 0 && isRtl));
+
+        boolean shouldZeroOverlay = mLauncherOverlay != null && mLastOverlaySroll != 0 &&
+                ((amount >= 0 && !isRtl) || (amount <= 0 && isRtl));
+
+        if (shouldScrollOverlay) {
+            if (!mStartedSendingScrollEvents && mScrollInteractionBegan) {
+                mStartedSendingScrollEvents = true;
+                mLauncherOverlay.onScrollInteractionBegin();
+                mShouldSendPageSettled = true;
+            }
+            int screenSize = getViewportWidth();
+            float f = (amount / screenSize);
+
+            int progress = (int) Math.abs((f * 100));
+
+            mLastOverlaySroll = progress;
+            mLauncherOverlay.onScrollChange(progress, isRtl);
+        } else if (shouldOverScroll) {
+            dampedOverScroll(amount);
+            mOverScrollEffect = acceleratedOverFactor(amount);
+        } else {
+            mOverScrollEffect = 0;
+        }
+
+        if (shouldZeroOverlay) {
+            mLauncherOverlay.onScrollChange(0, isRtl);
+        }
     }
 
     @Override
@@ -1261,14 +1330,11 @@
             if (mCustomContentCallbacks != null) {
                 mCustomContentCallbacks.onShow(false);
                 mCustomContentShowTime = System.currentTimeMillis();
-                mLauncher.updateVoiceButtonProxyVisible(false);
             }
         } else if (hasCustomContent() && getNextPage() != 0 && mCustomContentShowing) {
             mCustomContentShowing = false;
             if (mCustomContentCallbacks != null) {
                 mCustomContentCallbacks.onHide();
-                mLauncher.resetQSBScroll();
-                mLauncher.updateVoiceButtonProxyVisible(false);
             }
         }
     }
@@ -1711,18 +1777,6 @@
         }
     }
 
-    @Override
-    protected void overScroll(float amount) {
-        boolean shouldOverScroll = (amount < 0 && (!hasCustomContent() || isLayoutRtl())) ||
-                (amount > 0 && (!hasCustomContent() || !isLayoutRtl()));
-        if (shouldOverScroll) {
-            dampedOverScroll(amount);
-            mOverScrollEffect = acceleratedOverFactor(amount);
-        } else {
-            mOverScrollEffect = 0;
-        }
-    }
-
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         mWindowToken = getWindowToken();
@@ -2148,16 +2202,6 @@
         return -offsetFromTopEdge + mInsets.top + offsetToCenterInOverview;
     }
 
-    boolean shouldVoiceButtonProxyBeVisible() {
-        if (isOnOrMovingToCustomContent()) {
-            return false;
-        }
-        if (mState != State.NORMAL) {
-            return false;
-        }
-        return true;
-    }
-
     public void updateInteractionForState() {
         if (mState != State.NORMAL) {
             mLauncher.onInteractionBegin();
@@ -2200,6 +2244,13 @@
 
         AnimatorSet anim = animated ? LauncherAnimUtils.createAnimatorSet() : null;
 
+        // We only want a single instance of a workspace animation to be running at once, so
+        // we cancel any incomplete transition.
+        if (mStateAnimator != null) {
+            mStateAnimator.cancel();
+        }
+        mStateAnimator = anim;
+
         final State oldState = mState;
         final boolean oldStateIsNormal = (oldState == State.NORMAL);
         final boolean oldStateIsSpringLoaded = (oldState == State.SPRING_LOADED);
@@ -2354,10 +2405,6 @@
                 .alpha(finalHotseatAndPageIndicatorAlpha).withLayer();
             hotseatAlpha.addListener(new AlphaUpdateListener(hotseat));
 
-            Animator searchBarAlpha = new LauncherViewPropertyAnimator(searchBar)
-                .alpha(finalSearchBarAlpha).withLayer();
-            searchBarAlpha.addListener(new AlphaUpdateListener(searchBar));
-
             Animator overviewPanelAlpha = new LauncherViewPropertyAnimator(overviewPanel)
                 .alpha(finalOverviewPanelAlpha).withLayer();
             overviewPanelAlpha.addListener(new AlphaUpdateListener(overviewPanel));
@@ -2365,11 +2412,9 @@
             // For animation optimations, we may need to provide the Launcher transition
             // with a set of views on which to force build layers in certain scenarios.
             hotseat.setLayerType(View.LAYER_TYPE_HARDWARE, null);
-            searchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
             overviewPanel.setLayerType(View.LAYER_TYPE_HARDWARE, null);
             if (layerViews != null) {
                 layerViews.add(hotseat);
-                layerViews.add(searchBar);
                 layerViews.add(overviewPanel);
             }
 
@@ -2386,13 +2431,29 @@
             overviewPanelAlpha.setDuration(duration);
             pageIndicatorAlpha.setDuration(duration);
             hotseatAlpha.setDuration(duration);
-            searchBarAlpha.setDuration(duration);
+
+            if (searchBar != null) {
+                Animator searchBarAlpha = new LauncherViewPropertyAnimator(searchBar)
+                    .alpha(finalSearchBarAlpha).withLayer();
+                searchBarAlpha.addListener(new AlphaUpdateListener(searchBar));
+                searchBar.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+                if (layerViews != null) {
+                    layerViews.add(searchBar);
+                }
+                searchBarAlpha.setDuration(duration);
+                anim.play(searchBarAlpha);
+            }
 
             anim.play(overviewPanelAlpha);
             anim.play(hotseatAlpha);
-            anim.play(searchBarAlpha);
             anim.play(pageIndicatorAlpha);
             anim.setStartDelay(delay);
+            anim.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mStateAnimator = null;
+                }
+            });
         } else {
             overviewPanel.setAlpha(finalOverviewPanelAlpha);
             AlphaUpdateListener.updateVisibility(overviewPanel);
@@ -2402,14 +2463,15 @@
                 pageIndicator.setAlpha(finalHotseatAndPageIndicatorAlpha);
                 AlphaUpdateListener.updateVisibility(pageIndicator);
             }
-            searchBar.setAlpha(finalSearchBarAlpha);
-            AlphaUpdateListener.updateVisibility(searchBar);
+            if (searchBar != null) {
+                searchBar.setAlpha(finalSearchBarAlpha);
+                AlphaUpdateListener.updateVisibility(searchBar);
+            }
             updateCustomContentVisibility();
             setScaleX(mNewScale);
             setScaleY(mNewScale);
             setTranslationY(finalWorkspaceTranslationY);
         }
-        mLauncher.updateVoiceButtonProxyVisible(false);
 
         if (stateIsNormal) {
             animateBackgroundGradient(0f, animated);
@@ -4629,6 +4691,34 @@
         });
     }
 
+    public void disableShortcutsByPackageName(final ArrayList<String> packages,
+            final UserHandleCompat user, final int reason) {
+        final HashSet<String> packageNames = new HashSet<String>();
+        packageNames.addAll(packages);
+
+        mapOverItems(MAP_RECURSE, new ItemOperator() {
+            @Override
+            public boolean evaluate(ItemInfo info, View v, View parent) {
+                if (info instanceof ShortcutInfo && v instanceof BubbleTextView) {
+                    ShortcutInfo shortcutInfo = (ShortcutInfo) info;
+                    ComponentName cn = shortcutInfo.getTargetComponent();
+                    if (user.equals(shortcutInfo.user) && cn != null
+                            && packageNames.contains(cn.getPackageName())) {
+                        shortcutInfo.isDisabled |= reason;
+                        BubbleTextView shortcut = (BubbleTextView) v;
+                        shortcut.applyFromShortcutInfo(shortcutInfo, mIconCache, true, false);
+
+                        if (parent != null) {
+                            parent.invalidate();
+                        }
+                    }
+                }
+                // process all the shortcuts
+                return false;
+            }
+        });
+    }
+
     // Removes ALL items that match a given package name, this is usually called when a package
     // has been removed and we want to remove all components (widgets, shortcuts, apps) that
     // belong to that package.
@@ -4666,20 +4756,11 @@
         removeItemsByComponentName(cns, user);
     }
 
-    // Removes items that match the application info specified, when applications are removed
-    // as a part of an update, this is called to ensure that other widgets and application
-    // shortcuts are not removed.
-    void removeItemsByApplicationInfo(final ArrayList<AppInfo> appInfos, UserHandleCompat user) {
-        // Just create a hash table of all the specific components that this will affect
-        HashSet<ComponentName> cns = new HashSet<ComponentName>();
-        for (AppInfo info : appInfos) {
-            cns.add(info.componentName);
-        }
-
-        // Remove all the things
-        removeItemsByComponentName(cns, user);
-    }
-
+    /**
+     * Removes items that match the item info specified. When applications are removed
+     * as a part of an update, this is called to ensure that other widgets and application
+     * shortcuts are not removed.
+     */
     void removeItemsByComponentName(final HashSet<ComponentName> componentNames,
             final UserHandleCompat user) {
         ArrayList<CellLayout> cellLayouts = getWorkspaceAndHotseatCellLayouts();
@@ -4800,118 +4881,28 @@
         }
     }
 
-    void updateShortcutsAndWidgets(ArrayList<AppInfo> apps) {
-        // Break the appinfo list per user
-        final HashMap<UserHandleCompat, ArrayList<AppInfo>> appsPerUser =
-                new HashMap<UserHandleCompat, ArrayList<AppInfo>>();
-        for (AppInfo info : apps) {
-            ArrayList<AppInfo> filtered = appsPerUser.get(info.user);
-            if (filtered == null) {
-                filtered = new ArrayList<AppInfo>();
-                appsPerUser.put(info.user, filtered);
-            }
-            filtered.add(info);
-        }
-
-        for (Map.Entry<UserHandleCompat, ArrayList<AppInfo>> entry : appsPerUser.entrySet()) {
-            updateShortcutsAndWidgetsPerUser(entry.getValue(), entry.getKey());
-        }
-    }
-
-    private void updateShortcutsAndWidgetsPerUser(ArrayList<AppInfo> apps,
-            final UserHandleCompat user) {
-        // Create a map of the apps to test against
-        final HashMap<ComponentName, AppInfo> appsMap = new HashMap<ComponentName, AppInfo>();
-        final HashSet<String> pkgNames = new HashSet<String>();
-        for (AppInfo ai : apps) {
-            appsMap.put(ai.componentName, ai);
-            pkgNames.add(ai.componentName.getPackageName());
-        }
-        final HashSet<ComponentName> iconsToRemove = new HashSet<ComponentName>();
-
+    void updateShortcuts(ArrayList<ShortcutInfo> shortcuts) {
+        final HashSet<ShortcutInfo> updates = new HashSet<ShortcutInfo>(shortcuts);
         mapOverItems(MAP_RECURSE, new ItemOperator() {
             @Override
             public boolean evaluate(ItemInfo info, View v, View parent) {
-                if (info instanceof ShortcutInfo && v instanceof BubbleTextView) {
-                    ShortcutInfo shortcutInfo = (ShortcutInfo) info;
-                    ComponentName cn = shortcutInfo.getTargetComponent();
-                    AppInfo appInfo = appsMap.get(cn);
-                    if (user.equals(shortcutInfo.user) && cn != null
-                            && LauncherModel.isShortcutInfoUpdateable(info)
-                            && pkgNames.contains(cn.getPackageName())) {
-                        boolean promiseStateChanged = false;
-                        boolean infoUpdated = false;
-                        if (shortcutInfo.isPromise()) {
-                            if (shortcutInfo.hasStatusFlag(ShortcutInfo.FLAG_AUTOINTALL_ICON)) {
-                                // Auto install icon
-                                PackageManager pm = getContext().getPackageManager();
-                                ResolveInfo matched = pm.resolveActivity(
-                                        new Intent(Intent.ACTION_MAIN)
-                                        .setComponent(cn).addCategory(Intent.CATEGORY_LAUNCHER),
-                                        PackageManager.MATCH_DEFAULT_ONLY);
-                                if (matched == null) {
-                                    // Try to find the best match activity.
-                                    Intent intent = pm.getLaunchIntentForPackage(
-                                            cn.getPackageName());
-                                    if (intent != null) {
-                                        cn = intent.getComponent();
-                                        appInfo = appsMap.get(cn);
-                                    }
+                if (info instanceof ShortcutInfo && v instanceof BubbleTextView &&
+                        updates.contains(info)) {
+                    ShortcutInfo si = (ShortcutInfo) info;
+                    BubbleTextView shortcut = (BubbleTextView) v;
+                    boolean oldPromiseState = shortcut.getCompoundDrawables()[1]
+                            instanceof PreloadIconDrawable;
+                    shortcut.applyFromShortcutInfo(si, mIconCache, true,
+                            si.isPromise() != oldPromiseState);
 
-                                    if ((intent == null) || (appsMap == null)) {
-                                        // Could not find a default activity. Remove this item.
-                                        iconsToRemove.add(shortcutInfo.getTargetComponent());
-
-                                        // process next shortcut.
-                                        return false;
-                                    }
-                                    shortcutInfo.promisedIntent = intent;
-                                }
-                            }
-
-                            // Restore the shortcut.
-                            shortcutInfo.intent = shortcutInfo.promisedIntent;
-                            shortcutInfo.promisedIntent = null;
-                            shortcutInfo.status &= ~ShortcutInfo.FLAG_RESTORED_ICON
-                                    & ~ShortcutInfo.FLAG_AUTOINTALL_ICON
-                                    & ~ShortcutInfo.FLAG_INSTALL_SESSION_ACTIVE;
-
-                            promiseStateChanged = true;
-                            infoUpdated = true;
-                            shortcutInfo.updateIcon(mIconCache);
-                            LauncherModel.updateItemInDatabase(getContext(), shortcutInfo);
-                        }
-
-
-                        if (appInfo != null) {
-                            shortcutInfo.updateIcon(mIconCache);
-                            shortcutInfo.title = appInfo.title.toString();
-                            shortcutInfo.contentDescription = appInfo.contentDescription;
-                            infoUpdated = true;
-                        }
-
-                        if (infoUpdated) {
-                            BubbleTextView shortcut = (BubbleTextView) v;
-                            shortcut.applyFromShortcutInfo(shortcutInfo,
-                                    mIconCache, true, promiseStateChanged);
-
-                            if (parent != null) {
-                                parent.invalidate();
-                            }
-                        }
+                    if (parent != null) {
+                        parent.invalidate();
                     }
                 }
                 // process all the shortcuts
                 return false;
             }
         });
-
-        if (!iconsToRemove.isEmpty()) {
-            removeItemsByComponentName(iconsToRemove, user);
-        }
-        if (user.equals(UserHandleCompat.myUserHandle())) {
-            restorePendingWidgets(pkgNames);
-        }
     }
 
     public void removeAbandonedPromise(String packageName, UserHandleCompat user) {
@@ -4954,9 +4945,11 @@
     }
 
     public void updatePackageState(ArrayList<PackageInstallInfo> installInfos) {
-        HashSet<String> completedPackages = new HashSet<String>();
-
         for (final PackageInstallInfo installInfo : installInfos) {
+            if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLED) {
+                continue;
+            }
+
             mapOverItems(MAP_RECURSE, new ItemOperator() {
                 @Override
                 public boolean evaluate(ItemInfo info, View v, View parent) {
@@ -4984,42 +4977,10 @@
                     return false;
                 }
             });
-
-            if (installInfo.state == PackageInstallerCompat.STATUS_INSTALLED) {
-                completedPackages.add(installInfo.packageName);
-            }
-        }
-
-        // Note that package states are sent only for myUser
-        if (!completedPackages.isEmpty()) {
-            restorePendingWidgets(completedPackages);
         }
     }
 
-    private void restorePendingWidgets(final Set<String> installedPackaged) {
-        final ArrayList<LauncherAppWidgetInfo> changedInfo = new ArrayList<LauncherAppWidgetInfo>();
-
-        // Iterate non recursively as widgets can't be inside a folder.
-        mapOverItems(MAP_NO_RECURSE, new ItemOperator() {
-
-            @Override
-            public boolean evaluate(ItemInfo info, View v, View parent) {
-                if (info instanceof LauncherAppWidgetInfo) {
-                    LauncherAppWidgetInfo widgetInfo = (LauncherAppWidgetInfo) info;
-                    if (widgetInfo.hasRestoreFlag(LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY)
-                            && installedPackaged.contains(widgetInfo.providerName.getPackageName())) {
-
-                        changedInfo.add(widgetInfo);
-
-                        // Remove the provider not ready flag
-                        widgetInfo.restoreStatus &= ~LauncherAppWidgetInfo.FLAG_PROVIDER_NOT_READY;
-                        LauncherModel.updateItemInDatabase(getContext(), widgetInfo);
-                    }
-                }
-                // process all the widget
-                return false;
-            }
-        });
+    void widgetsRestored(ArrayList<LauncherAppWidgetInfo> changedInfo) {
         if (!changedInfo.isEmpty()) {
             DeferredWidgetRefresh widgetRefresh = new DeferredWidgetRefresh(changedInfo,
                     mLauncher.getAppWidgetHost());
@@ -5029,6 +4990,13 @@
                 widgetRefresh.run();
             } else {
                 // widgetRefresh will automatically run when the packages are updated.
+                // For now just update the progress bars
+                for (LauncherAppWidgetInfo info : changedInfo) {
+                    if (info.hostView instanceof PendingAppWidgetHostView) {
+                        info.installProgress = 100;
+                        ((PendingAppWidgetHostView) info.hostView).applyState();
+                    }
+                }
             }
         }
     }
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompat.java b/src/com/android/launcher3/compat/LauncherAppsCompat.java
index 6efcc00..5858bc8 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompat.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompat.java
@@ -19,8 +19,10 @@
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.graphics.Rect;
-import android.os.Build;
 import android.os.Bundle;
 
 import com.android.launcher3.Utilities;
@@ -73,4 +75,13 @@
     public abstract boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user);
     public abstract boolean isActivityEnabledForProfile(ComponentName component,
             UserHandleCompat user);
+
+    public boolean isAppEnabled(PackageManager pm, String packageName, int flags) {
+        try {
+            ApplicationInfo info = pm.getApplicationInfo(packageName, flags);
+            return info != null && info.enabled;
+        } catch (NameNotFoundException e) {
+            return false;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/com/android/launcher3/compat/LauncherAppsCompatV16.java b/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
index 7e5e6bf..e47b9a5 100644
--- a/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
+++ b/src/com/android/launcher3/compat/LauncherAppsCompatV16.java
@@ -22,7 +22,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.ResolveInfo;
@@ -112,12 +111,7 @@
     }
 
     public boolean isPackageEnabledForProfile(String packageName, UserHandleCompat user) {
-        try {
-            PackageInfo info = mPm.getPackageInfo(packageName, 0);
-            return info != null && info.applicationInfo.enabled;
-        } catch (NameNotFoundException e) {
-            return false;
-        }
+        return isAppEnabled(mPm, packageName, 0);
     }
 
     public boolean isActivityEnabledForProfile(ComponentName component, UserHandleCompat user) {
@@ -198,8 +192,13 @@
                     callback.onPackagesAvailable(packages, user, replacing);
                 }
             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) {
-                final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING,
-                        Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT);
+                // This intent is broadcasted when moving a package or mounting/un-mounting
+                // external storage.
+                // However on Kitkat this is also sent when a package is being updated, and
+                // contains an extra Intent.EXTRA_REPLACING=true for that case.
+                // Using false as default for Intent.EXTRA_REPLACING gives correct value on
+                // lower devices as the intent is not sent when the app is updating/replacing.
+                final boolean replacing = intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                 String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                 for (OnAppsChangedCallbackCompat callback : getCallbacks()) {
                     callback.onPackagesUnavailable(packages, user, replacing);
diff --git a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
index 16ad379..601f04c 100644
--- a/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
+++ b/src/com/android/launcher3/compat/PackageInstallerCompatVL.java
@@ -20,6 +20,7 @@
 import android.content.pm.PackageInstaller;
 import android.content.pm.PackageInstaller.SessionCallback;
 import android.content.pm.PackageInstaller.SessionInfo;
+import android.os.Handler;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -29,15 +30,18 @@
 import java.util.ArrayList;
 import java.util.HashSet;
 
-public class PackageInstallerCompatVL extends PackageInstallerCompat {
+public class PackageInstallerCompatVL extends PackageInstallerCompat implements Runnable {
 
     private static final String TAG = "PackageInstallerCompatVL";
     private static final boolean DEBUG = false;
 
+    // All updates to these sets must happen on the {@link #mWorker} thread.
     private final SparseArray<SessionInfo> mPendingReplays = new SparseArray<SessionInfo>();
     private final HashSet<String> mPendingBadgeUpdates = new HashSet<String>();
+
     private final PackageInstaller mInstaller;
     private final IconCache mCache;
+    private final Handler mWorker;
 
     private boolean mResumed;
     private boolean mBound;
@@ -46,16 +50,23 @@
         mInstaller = context.getPackageManager().getPackageInstaller();
         LauncherAppState.setApplicationContext(context.getApplicationContext());
         mCache = LauncherAppState.getInstance().getIconCache();
+        mWorker = new Handler();
 
         mResumed = false;
         mBound = false;
 
-        mInstaller.registerSessionCallback(mCallback);
+        mInstaller.registerSessionCallback(mCallback, mWorker);
 
         // On start, send updates for all active sessions
-        for (SessionInfo info : mInstaller.getAllSessions()) {
-            mPendingReplays.append(info.getSessionId(), info);
-        }
+        mWorker.post(new Runnable() {
+
+            @Override
+            public void run() {
+                for (SessionInfo info : mInstaller.getAllSessions()) {
+                    mPendingReplays.append(info.getSessionId(), info);
+                }
+            }
+        });
     }
 
     @Override
@@ -81,12 +92,13 @@
 
     @Override
     public void onStop() {
+        mInstaller.unregisterSessionCallback(mCallback);
     }
 
     @Override
     public void onFinishBind() {
         mBound = true;
-        replayUpdates(null);
+        mWorker.post(this);
     }
 
     @Override
@@ -97,7 +109,7 @@
     @Override
     public void onResume() {
         mResumed = true;
-        replayUpdates(null);
+        mWorker.post(this);
     }
 
     @Override
@@ -105,13 +117,19 @@
         // No op
     }
 
+    @Override
+    public void run() {
+        // Called on mWorker thread.
+        replayUpdates(null);
+    }
+
     private void replayUpdates(PackageInstallInfo newInfo) {
         if (DEBUG) Log.d(TAG, "updates resumed");
         if (!mResumed || !mBound) {
             // Not yet ready
             return;
         }
-        if ((mPendingReplays.size() == 0) && (newInfo == null) && mPendingBadgeUpdates.isEmpty()) {
+        if ((mPendingReplays.size() == 0) && (newInfo == null)) {
             // Nothing to update
             return;
         }