diff --git a/build.gradle b/build.gradle
index f98021c..ffe4455 100644
--- a/build.gradle
+++ b/build.gradle
@@ -12,8 +12,8 @@
 apply plugin: 'com.google.protobuf'
 
 android {
-    compileSdkVersion 'android-N'
-    buildToolsVersion '24.0.0-rc3'
+    compileSdkVersion 25
+    buildToolsVersion '24.0.0'
 
     defaultConfig {
         applicationId "com.android.launcher3"
diff --git a/protos/backup.proto b/protos/backup.proto
deleted file mode 100644
index 62f935c..0000000
--- a/protos/backup.proto
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.
- */
-
-syntax = "proto2";
-
-package launcher_backup;
-
-option java_package = "com.android.launcher3.backup.nano";
-option java_outer_classname = "BackupProtos";
-
-message Key {
-  enum Type {
-    FAVORITE = 1;
-    SCREEN = 2;
-    ICON = 3;
-    WIDGET = 4;
-  }
-  required Type type = 1;
-  optional string name = 2;  // keep this short
-  optional int64 id = 3;
-  optional int64 checksum = 4;
-}
-
-message CheckedMessage {
-  required bytes payload = 1;
-  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 {
-  // Type of the app, this target represents
-  enum TargetType {
-    TARGET_NONE = 0;
-    TARGET_PHONE = 1;
-    TARGET_MESSENGER = 2;
-    TARGET_EMAIL = 3;
-    TARGET_BROWSER = 4;
-    TARGET_GALLERY = 5;
-    TARGET_CAMERA = 6;
-  }
-
-  required int64 id = 1;
-  required int32 itemType = 2;
-  optional string title = 3;
-  optional int32 container = 4;
-  optional int32 screen = 5;
-  optional int32 cellX = 6;
-  optional int32 cellY = 7;
-  optional int32 spanX = 8;
-  optional int32 spanY = 9;
-  optional int32 displayMode = 10;
-  optional int32 appWidgetId = 11;
-  optional string appWidgetProvider = 12;
-  optional string intent = 13;
-  optional string uri = 14;
-  optional int32 iconType = 15 [deprecated = true];
-  optional string iconPackage = 16;
-  optional string iconResource = 17;
-  optional bytes icon = 18;
-
-  // Added in backup version 4
-  optional TargetType targetType = 19 [default = TARGET_NONE];
-  optional int32 rank = 20;
-}
-
-message Screen {
-  required int64 id = 1;
-  optional int32 rank = 2;
-}
-
-message Resource {
-  required int32 dpi = 1;
-  required bytes data = 2;
-}
-
-message Widget {
-  required string provider = 1;
-  optional string label = 2;
-  optional bool configure = 3;
-  optional Resource icon = 4;
-  optional Resource preview = 5;
-
-  // Added in backup version 3
-  // Assume that a widget is resizable upto 2x2 if no data is available
-  optional int32 minSpanX = 6 [default = 2];
-  optional int32 minSpanY = 7 [default = 2];
-}
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index c8a05b7..f3d0eaa 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -64,6 +64,7 @@
     <dimen name="all_apps_grid_section_y_offset">8dp</dimen>
     <dimen name="all_apps_grid_section_text_size">24sp</dimen>
     <dimen name="all_apps_search_bar_height">60dp</dimen>
+    <dimen name="all_apps_search_bar_margin_top">5dp</dimen>
     <dimen name="all_apps_search_bar_icon_margin_right">4dp</dimen>
     <dimen name="all_apps_search_bar_icon_margin_top">1dp</dimen>
     <dimen name="all_apps_icon_top_bottom_padding">8dp</dimen>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 65baf46..1ac6620 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -63,7 +63,7 @@
     <string name="hotseat_out_of_space">No more room in the Favorites tray</string>
 
     <!-- All applications label -->
-    <string name="all_apps_button_label">Apps</string>
+    <string name="all_apps_button_label">Apps list</string>
     <!-- Label for button in all applications label to go back home (to the workspace / desktop)
          for accessibilty (spoken when the button gets focus). -->
     <string name="all_apps_home_button_label">Home</string>
@@ -149,9 +149,9 @@
 
     <!-- Strings for settings -->
     <!-- Title for Allow Rotation setting. [CHAR LIMIT=50] -->
-    <string name="allow_rotation_title">Allow homescreen rotation</string>
+    <string name="allow_rotation_title">Allow Home screen rotation</string>
     <!-- Text explaining when the home screen will get rotated. [CHAR LIMIT=100] -->
-    <string name="allow_rotation_desc">When device is rotated</string>
+    <string name="allow_rotation_desc">When phone is rotated</string>
     <!-- Text explaining that rotation is disabled in Display settings. 'Display' refers to the Display section in system settings [CHAR LIMIT=100] -->
     <string name="allow_rotation_blocked_desc">Current Display setting doesn\'t permit rotation</string>
 
diff --git a/src/com/android/launcher3/CommonAppTypeParser.java b/src/com/android/launcher3/CommonAppTypeParser.java
index a4a92b6..c2bd883 100644
--- a/src/com/android/launcher3/CommonAppTypeParser.java
+++ b/src/com/android/launcher3/CommonAppTypeParser.java
@@ -25,7 +25,6 @@
 
 import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback;
 import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.backup.nano.BackupProtos.Favorite;
 import com.android.launcher3.util.Thunk;
 
 import org.xmlpull.v1.XmlPullParserException;
@@ -43,6 +42,12 @@
 
     private static final int RESTORE_FLAG_BIT_SHIFT = 4;
 
+    public static final int TARGET_PHONE = 1;
+    public static final int TARGET_MESSENGER = 2;
+    public static final int TARGET_EMAIL = 3;
+    public static final int TARGET_BROWSER = 4;
+    public static final int TARGET_GALLERY = 5;
+    public static final int TARGET_CAMERA = 6;
 
     private final long mItemId;
     @Thunk final int mResId;
@@ -118,22 +123,22 @@
 
     public static int getResourceForItemType(int type) {
         switch (type) {
-            case Favorite.TARGET_PHONE:
+            case TARGET_PHONE:
                 return R.xml.app_target_phone;
 
-            case Favorite.TARGET_MESSENGER:
+            case TARGET_MESSENGER:
                 return R.xml.app_target_messenger;
 
-            case Favorite.TARGET_EMAIL:
+            case TARGET_EMAIL:
                 return R.xml.app_target_email;
 
-            case Favorite.TARGET_BROWSER:
+            case TARGET_BROWSER:
                 return R.xml.app_target_browser;
 
-            case Favorite.TARGET_GALLERY:
+            case TARGET_GALLERY:
                 return R.xml.app_target_gallery;
 
-            case Favorite.TARGET_CAMERA:
+            case TARGET_CAMERA:
                 return R.xml.app_target_camera;
 
             default:
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 556246f..763daf4 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -944,6 +944,10 @@
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onStop();
         }
+
+        if (Utilities.isNycMR1OrAbove()) {
+            mAppWidgetHost.stopListening();
+        }
     }
 
     @Override
@@ -954,6 +958,10 @@
         if (mLauncherCallbacks != null) {
             mLauncherCallbacks.onStart();
         }
+
+        if (Utilities.isNycMR1OrAbove()) {
+            mAppWidgetHost.startListening();
+        }
     }
 
     @Override
diff --git a/src/com/android/launcher3/LauncherAppWidgetHost.java b/src/com/android/launcher3/LauncherAppWidgetHost.java
index 3bb7381..d3e5350 100644
--- a/src/com/android/launcher3/LauncherAppWidgetHost.java
+++ b/src/com/android/launcher3/LauncherAppWidgetHost.java
@@ -67,12 +67,6 @@
         }
     }
 
-    @Override
-    public void stopListening() {
-        super.stopListening();
-        clearViews();
-    }
-
     public void addProviderChangeListener(Runnable callback) {
         mProviderChangeListeners.add(callback);
     }
diff --git a/src/com/android/launcher3/LauncherBackupAgentHelper.java b/src/com/android/launcher3/LauncherBackupAgentHelper.java
deleted file mode 100644
index c2ab20a..0000000
--- a/src/com/android/launcher3/LauncherBackupAgentHelper.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * 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.
- */
-
-package com.android.launcher3;
-
-import android.app.backup.BackupAgentHelper;
-import android.app.backup.BackupDataInput;
-import android.app.backup.BackupManager;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.database.Cursor;
-import android.os.ParcelFileDescriptor;
-import android.util.Log;
-
-import com.android.launcher3.model.GridSizeMigrationTask;
-
-import java.io.IOException;
-
-public class LauncherBackupAgentHelper extends BackupAgentHelper {
-
-    private static final String TAG = "LauncherBAHelper";
-
-    private static final String KEY_LAST_NOTIFIED_TIME = "backup_manager_last_notified";
-
-    private static final String LAUNCHER_DATA_PREFIX = "L";
-
-    static final boolean VERBOSE = false;
-    static final boolean DEBUG = false;
-
-    /**
-     * Notify the backup manager that out database is dirty.
-     *
-     * <P>This does not force an immediate backup.
-     *
-     * @param context application context
-     */
-    public static void dataChanged(Context context) {
-        dataChanged(context, 0);
-    }
-
-    /**
-     * Notify the backup manager that out database is dirty.
-     *
-     * <P>This does not force an immediate backup.
-     *
-     * @param context application context
-     * @param throttleMs duration in ms for which two consecutive calls to backup manager should
-     *                   not be made.
-     */
-    public static void dataChanged(Context context, long throttleMs) {
-        SharedPreferences prefs = Utilities.getPrefs(context);
-        long now = System.currentTimeMillis();
-        long lastTime = prefs.getLong(KEY_LAST_NOTIFIED_TIME, 0);
-
-        // User can manually change the system time, which could lead to now < lastTime.
-        // Re-backup in that case, as the backup will have a wrong lastModifiedTime.
-        if (now < lastTime || now >= (lastTime + throttleMs)) {
-            BackupManager.dataChanged(context.getPackageName());
-            prefs.edit().putLong(KEY_LAST_NOTIFIED_TIME, now).apply();
-        }
-    }
-
-    private LauncherBackupHelper mHelper;
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mHelper = new LauncherBackupHelper(this);
-        addHelper(LAUNCHER_DATA_PREFIX, mHelper);
-    }
-
-    @Override
-    public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState)
-            throws IOException {
-        if (!Utilities.ATLEAST_LOLLIPOP) {
-            // 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;
-        }
-
-        // Clear dB before restore
-        LauncherSettings.Settings.call(getContentResolver(),
-                LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
-
-        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, 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) {
-            LauncherSettings.Settings.call(getContentResolver(),
-                    LauncherSettings.Settings.METHOD_CLEAR_EMPTY_DB_FLAG);
-            LauncherClings.markFirstRunClingDismissed(this);
-
-            // Rank was added in v4.
-            if (mHelper.restoredBackupVersion <= 3) {
-                LauncherSettings.Settings.call(getContentResolver(),
-                        LauncherSettings.Settings.METHOD_UPDATE_FOLDER_ITEMS_RANK);
-            }
-
-            if (GridSizeMigrationTask.ENABLED && mHelper.shouldAttemptWorkspaceMigration()) {
-                GridSizeMigrationTask.markForMigration(getApplicationContext(),
-                        mHelper.widgetSizes, mHelper.migrationCompatibleProfileData);
-            }
-
-            LauncherSettings.Settings.call(getContentResolver(),
-                    LauncherSettings.Settings.METHOD_CONVERT_SHORTCUTS_TO_ACTIVITIES);
-        } else {
-            if (VERBOSE) Log.v(TAG, "Nothing was restored, clearing DB");
-            LauncherSettings.Settings.call(getContentResolver(),
-                    LauncherSettings.Settings.METHOD_CREATE_EMPTY_DB);
-        }
-    }
-}
diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
deleted file mode 100644
index e987a9b..0000000
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ /dev/null
@@ -1,1257 +0,0 @@
-/*
- * 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.
- */
-package com.android.launcher3;
-
-import android.app.backup.BackupDataInputStream;
-import android.app.backup.BackupDataOutput;
-import android.app.backup.BackupHelper;
-import android.app.backup.BackupManager;
-import android.content.ComponentName;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
-import android.content.res.XmlResourceParser;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Point;
-import android.graphics.drawable.Drawable;
-import android.os.ParcelFileDescriptor;
-import android.text.TextUtils;
-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.nano.BackupProtos;
-import com.android.launcher3.backup.nano.BackupProtos.CheckedMessage;
-import com.android.launcher3.backup.nano.BackupProtos.DeviceProfieData;
-import com.android.launcher3.backup.nano.BackupProtos.Favorite;
-import com.android.launcher3.backup.nano.BackupProtos.Journal;
-import com.android.launcher3.backup.nano.BackupProtos.Key;
-import com.android.launcher3.backup.nano.BackupProtos.Resource;
-import com.android.launcher3.backup.nano.BackupProtos.Screen;
-import com.android.launcher3.backup.nano.BackupProtos.Widget;
-import com.android.launcher3.compat.AppWidgetManagerCompat;
-import com.android.launcher3.compat.UserHandleCompat;
-import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.model.GridSizeMigrationTask;
-import com.android.launcher3.util.Thunk;
-import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
-import com.google.protobuf.nano.MessageNano;
-
-import org.xmlpull.v1.XmlPullParser;
-import org.xmlpull.v1.XmlPullParserException;
-
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-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 int BACKUP_VERSION = 4;
-    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;
-
-    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.ITEM_TYPE,               // 11
-        Favorites.SCREEN,                  // 12
-        Favorites.SPANX,                   // 13
-        Favorites.SPANY,                   // 14
-        Favorites.TITLE,                   // 15
-        Favorites.PROFILE_ID,              // 16
-        Favorites.RANK,                    // 17
-    };
-
-    private static final int ID_INDEX = 0;
-    private static final int ID_MODIFIED = 1;
-    private static final int INTENT_INDEX = 2;
-    private static final int APPWIDGET_PROVIDER_INDEX = 3;
-    private static final int APPWIDGET_ID_INDEX = 4;
-    private static final int CELLX_INDEX = 5;
-    private static final int CELLY_INDEX = 6;
-    private static final int CONTAINER_INDEX = 7;
-    private static final int ICON_INDEX = 8;
-    private static final int ICON_PACKAGE_INDEX = 9;
-    private static final int ICON_RESOURCE_INDEX = 10;
-    private static final int ITEM_TYPE_INDEX = 11;
-    private static final int SCREEN_INDEX = 12;
-    private static final int SPANX_INDEX = 13;
-    private static final int SPANY_INDEX = 14;
-    private static final int TITLE_INDEX = 15;
-    private static final int RANK_INDEX = 17;
-
-    private static final String[] SCREEN_PROJECTION = {
-        WorkspaceScreens._ID,              // 0
-        WorkspaceScreens.MODIFIED,         // 1
-        WorkspaceScreens.SCREEN_RANK       // 2
-    };
-
-    private static final int SCREEN_RANK_INDEX = 2;
-
-    @Thunk final Context mContext;
-    private final HashSet<String> mExistingKeys;
-    private final ArrayList<Key> mKeys;
-    private final ItemTypeMatcher[] mItemTypeMatchers;
-    private final long mUserSerial;
-
-    private BackupManager mBackupManager;
-    private byte[] mBuffer = new byte[512];
-    private long mLastBackupRestoreTime;
-    private boolean mBackupDataWasUpdated;
-
-    private IconCache mIconCache;
-    private DeviceProfieData mDeviceProfileData;
-    private InvariantDeviceProfile mIdp;
-
-    DeviceProfieData migrationCompatibleProfileData;
-    HashSet<String> widgetSizes = new HashSet<>();
-
-    boolean restoreSuccessful;
-    int restoredBackupVersion = 1;
-
-    // When migrating from a device which different hotseat configuration, the icons are shifted
-    // to center along the new all-apps icon.
-    private int mHotseatShift = 0;
-
-    public LauncherBackupHelper(Context context) {
-        mContext = context;
-        mExistingKeys = new HashSet<String>();
-        mKeys = new ArrayList<Key>();
-        restoreSuccessful = true;
-        mItemTypeMatchers = new ItemTypeMatcher[CommonAppTypeParser.SUPPORTED_TYPE_COUNT];
-
-        UserManagerCompat userManager = UserManagerCompat.getInstance(mContext);
-        mUserSerial = userManager.getSerialNumberForUser(UserHandleCompat.myUserHandle());
-    }
-
-    private void dataChanged() {
-        if (mBackupManager == null) {
-            mBackupManager = new BackupManager(mContext);
-        }
-        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));
-            }
-        }
-        restoredBackupVersion = journal.backupVersion;
-    }
-
-    /**
-     * Back up launcher data so we can restore the user's state on a new device.
-     *
-     * <P>The journal is a timestamp and a list of keys that were saved as of that time.
-     *
-     * <P>Keys may come back in any order, so each key/value is one complete row of the database.
-     *
-     * @param oldState notes from the last backup
-     * @param data incremental key/value pairs to persist off-device
-     * @param newState notes for the next backup
-     */
-    @Override
-    public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data,
-            ParcelFileDescriptor newState) {
-        if (VERBOSE) Log.v(TAG, "onBackup");
-
-        Journal in = readJournal(oldState);
-        if (!launcherIsReady()) {
-            dataChanged();
-            // Perform backup later.
-            writeJournal(newState, in);
-            return;
-        }
-
-        if (mDeviceProfileData == null) {
-            LauncherAppState app = LauncherAppState.getInstance();
-            mIdp = app.getInvariantDeviceProfile();
-            mDeviceProfileData = initDeviceProfileData(mIdp);
-            mIconCache = app.getIconCache();
-        }
-
-        Log.v(TAG, "lastBackupTime = " + in.t);
-        mKeys.clear();
-        applyJournal(in);
-
-        // 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();
-        mBackupDataWasUpdated = false;
-        try {
-            backupFavorites(data);
-            backupScreens(data);
-            backupIcons(data);
-            backupWidgets(data);
-
-            // 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));
-            }
-            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);
-                mBackupDataWasUpdated = true;
-            }
-
-            mExistingKeys.clear();
-            if (!mBackupDataWasUpdated) {
-                // Check if any metadata has changed
-                mBackupDataWasUpdated = (in.profile == null)
-                        || !Arrays.equals(DeviceProfieData.toByteArray(in.profile),
-                            DeviceProfieData.toByteArray(mDeviceProfileData))
-                        || (in.backupVersion != BACKUP_VERSION)
-                        || (in.appVersion != getAppVersion());
-            }
-
-            if (mBackupDataWasUpdated) {
-                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);
-            } else {
-                if (DEBUG) Log.d(TAG, "Nothing was written during backup");
-            }
-        } catch (IOException e) {
-            Log.e(TAG, "launcher backup has failed", e);
-        }
-
-        writeNewStateDescription(newState);
-    }
-
-    /**
-     * @return true if the backup corresponding to oldstate can be successfully applied
-     * to this device.
-     */
-    private boolean isBackupCompatible(Journal oldState) {
-        DeviceProfieData currentProfile = mDeviceProfileData;
-        DeviceProfieData oldProfile = oldState.profile;
-
-        if (oldProfile == null || oldProfile.desktopCols == 0) {
-            // Profile info is not valid, ignore the check.
-            return true;
-        }
-
-        boolean isHotseatCompatible = false;
-        if (currentProfile.allappsRank >= oldProfile.hotseatCount) {
-            isHotseatCompatible = true;
-            mHotseatShift = 0;
-        }
-
-        if ((currentProfile.allappsRank >= oldProfile.allappsRank)
-                && ((currentProfile.hotseatCount - currentProfile.allappsRank) >=
-                        (oldProfile.hotseatCount - oldProfile.allappsRank))) {
-            // There is enough space on both sides of the hotseat.
-            isHotseatCompatible = true;
-            mHotseatShift = currentProfile.allappsRank - oldProfile.allappsRank;
-        }
-
-        if (!isHotseatCompatible) {
-            return false;
-        }
-        if ((currentProfile.desktopCols >= oldProfile.desktopCols)
-                && (currentProfile.desktopRows >= oldProfile.desktopRows)) {
-            return true;
-        }
-
-        if (GridSizeMigrationTask.ENABLED) {
-            // One time migrate the workspace when launcher starts.
-            migrationCompatibleProfileData = initDeviceProfileData(mIdp);
-            migrationCompatibleProfileData.desktopCols = oldProfile.desktopCols;
-            migrationCompatibleProfileData.desktopRows = oldProfile.desktopRows;
-            migrationCompatibleProfileData.hotseatCount = oldProfile.hotseatCount;
-            migrationCompatibleProfileData.allappsRank = oldProfile.allappsRank;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Restore launcher configuration from the restored data stream.
-     * 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 (!restoreSuccessful) {
-            return;
-        }
-
-        if (mDeviceProfileData == null) {
-            // This call does not happen on a looper thread. So LauncherAppState
-            // can't be created . Instead initialize required dependencies directly.
-            mIdp = new InvariantDeviceProfile(mContext);
-            mDeviceProfileData = initDeviceProfileData(mIdp);
-            mIconCache = new IconCache(mContext, mIdp);
-        }
-
-        int dataSize = data.size();
-        if (mBuffer.length < dataSize) {
-            mBuffer = new byte[dataSize];
-        }
-        try {
-            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, mBuffer, dataSize);
-                    break;
-
-                case Key.SCREEN:
-                    restoreScreen(key, mBuffer, dataSize);
-                    break;
-
-                case Key.ICON:
-                    restoreIcon(key, mBuffer, dataSize);
-                    break;
-
-                case Key.WIDGET:
-                    restoreWidget(key, mBuffer, dataSize);
-                    break;
-
-                default:
-                    Log.w(TAG, "unknown restore entity type: " + key.type);
-                    mKeys.remove(key);
-                    break;
-            }
-        } catch (IOException e) {
-            Log.w(TAG, "ignoring unparsable backup entry", e);
-        }
-    }
-
-    /**
-     * Record the restore state for the next backup.
-     *
-     * @param newState notes about the backup state after restore.
-     */
-    @Override
-    public void writeNewStateDescription(ParcelFileDescriptor newState) {
-        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 = mDeviceProfileData;
-        return journal;
-    }
-
-    private int getAppVersion() {
-        try {
-            return mContext.getPackageManager()
-                    .getPackageInfo(mContext.getPackageName(), 0).versionCode;
-        } catch (NameNotFoundException e) {
-            return 0;
-        }
-    }
-
-    private DeviceProfieData initDeviceProfileData(InvariantDeviceProfile profile) {
-        DeviceProfieData data = new DeviceProfieData();
-        data.desktopRows = profile.numRows;
-        data.desktopCols = profile.numColumns;
-        data.hotseatCount = profile.numHotseatIcons;
-        return data;
-    }
-
-    /**
-     * Write all modified favorites to the data stream.
-     *
-     * @param data output stream for key/value pairs
-     * @throws IOException
-     */
-    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);
-        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);
-                mKeys.add(key);
-                final String backupKey = keyToBackupKey(key);
-
-                // Favorite proto changed in v4. Backup again if the version is old.
-                if (!mExistingKeys.contains(backupKey) || updateTime >= mLastBackupRestoreTime
-                        || restoredBackupVersion < 4) {
-                    writeRowToBackup(key, packFavorite(cursor), data);
-                } else {
-                    if (DEBUG) Log.d(TAG, "favorite already backup up: " + id);
-                }
-            }
-        } finally {
-            cursor.close();
-        }
-    }
-
-    /**
-     * Read a favorite from the stream.
-     *
-     * <P>Keys arrive in any order, so screens and containers may not exist yet.
-     *
-     * @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
-     */
-    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));
-
-        ContentResolver cr = mContext.getContentResolver();
-        ContentValues values = unpackFavorite(buffer, dataSize);
-        cr.insert(Favorites.CONTENT_URI, values);
-    }
-
-    /**
-     * Write all modified screens to the data stream.
-     *
-     * @param data output stream for key/value pairs
-     * @throws IOException
-     */
-    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);
-        try {
-            cursor.moveToPosition(-1);
-            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);
-                mKeys.add(key);
-                final String backupKey = keyToBackupKey(key);
-                if (!mExistingKeys.contains(backupKey) || updateTime >= mLastBackupRestoreTime) {
-                    writeRowToBackup(key, packScreen(cursor), data);
-                } else {
-                    if (VERBOSE) Log.v(TAG, "screen already backup up " + id);
-                }
-            }
-        } finally {
-            cursor.close();
-        }
-    }
-
-    /**
-     * Read a screen from the stream.
-     *
-     * <P>Keys arrive in any order, so children of this screen may already exist.
-     *
-     * @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
-     */
-    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));
-
-        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 data output stream for key/value pairs
-     */
-    private void backupIcons(BackupDataOutput data) throws IOException {
-        // persist icons that haven't been persisted yet
-        final ContentResolver cr = mContext.getContentResolver();
-        final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
-        final UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
-        int backupUpIconCount = 0;
-
-        // Don't backup apps in other profiles for now.
-        String where = "(" + Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPLICATION + " OR " +
-                Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_SHORTCUT + " OR " +
-                Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_DEEP_SHORTCUT + ") AND " +
-                getUserSelectionArg();
-        Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
-                where, null, null);
-        try {
-            cursor.moveToPosition(-1);
-            while(cursor.moveToNext()) {
-                final long id = cursor.getLong(ID_INDEX);
-                final String intentDescription = cursor.getString(INTENT_INDEX);
-                try {
-                    Intent intent = Intent.parseUri(intentDescription, 0);
-                    ComponentName cn = intent.getComponent();
-                    Key key = null;
-                    String backupKey = null;
-                    if (cn != null) {
-                        key = getKey(Key.ICON, cn.flattenToShortString());
-                        backupKey = keyToBackupKey(key);
-                    } else {
-                        Log.w(TAG, "empty intent on application favorite: " + id);
-                    }
-                    if (mExistingKeys.contains(backupKey)) {
-                        if (DEBUG) Log.d(TAG, "already saved icon " + backupKey);
-
-                        // remember that we already backed this up previously
-                        mKeys.add(key);
-                    } else if (backupKey != null) {
-                        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);
-                            if (icon != null && !mIconCache.isDefaultIcon(icon, myUserHandle)) {
-                                writeRowToBackup(key, packIcon(dpi, icon), data);
-                                mKeys.add(key);
-                                backupUpIconCount ++;
-                            }
-                        } else {
-                            if (VERBOSE) Log.v(TAG, "deferring icon backup " + backupKey);
-                            // too many icons for this pass, request another.
-                            dataChanged();
-                        }
-                    }
-                } catch (URISyntaxException e) {
-                    Log.e(TAG, "invalid URI on application favorite: " + id);
-                } catch (IOException e) {
-                    Log.e(TAG, "unable to save application icon for favorite: " + id);
-                }
-
-            }
-        } finally {
-            cursor.close();
-        }
-    }
-
-    /**
-     * Read an icon from the stream.
-     *
-     * <P>Keys arrive in any order, so shortcuts that use this icon may already exist.
-     *
-     * @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
-     */
-    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));
-
-        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);
-        } else {
-            if (VERBOSE) Log.v(TAG, "saving restored icon as: " + key.name);
-            mIconCache.preloadIcon(ComponentName.unflattenFromString(key.name), icon, res.dpi,
-                    "" /* label */, mUserSerial, mIdp);
-        }
-    }
-
-    /**
-     * Write all the static widget resources we need to render placeholders
-     * for a package that is not installed.
-     *
-     * @param data output stream for key/value pairs
-     * @throws IOException
-     */
-    private void backupWidgets(BackupDataOutput data) throws IOException {
-        // persist static widget info that hasn't been persisted yet
-        final ContentResolver cr = mContext.getContentResolver();
-        final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
-        int backupWidgetCount = 0;
-
-        String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPWIDGET + " AND "
-                + getUserSelectionArg();
-        Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
-                where, null, null);
-        AppWidgetManagerCompat widgetManager = AppWidgetManagerCompat.getInstance(mContext);
-        try {
-            cursor.moveToPosition(-1);
-            while(cursor.moveToNext()) {
-                final long id = cursor.getLong(ID_INDEX);
-                final String providerName = cursor.getString(APPWIDGET_PROVIDER_INDEX);
-                final ComponentName provider = ComponentName.unflattenFromString(providerName);
-
-                Key key = null;
-                String backupKey = null;
-                if (provider != null) {
-                    key = getKey(Key.WIDGET, providerName);
-                    backupKey = keyToBackupKey(key);
-                } else {
-                    Log.w(TAG, "empty intent on appwidget: " + id);
-                }
-
-                // Widget backup proto changed in v3. So add it again if the original backup is old.
-                if (mExistingKeys.contains(backupKey) && restoredBackupVersion >= 3) {
-                    if (DEBUG) Log.d(TAG, "already saved widget " + backupKey);
-
-                    // remember that we already backed this up previously
-                    mKeys.add(key);
-                } else if (backupKey != null) {
-                    if (DEBUG) Log.d(TAG, "I can count this high: " + backupWidgetCount);
-                    if (backupWidgetCount < MAX_WIDGETS_PER_PASS) {
-                        LauncherAppWidgetProviderInfo widgetInfo = widgetManager
-                                .getLauncherAppWidgetInfo(cursor.getInt(APPWIDGET_ID_INDEX));
-                        if (widgetInfo != null) {
-                            if (DEBUG) Log.d(TAG, "saving widget " + backupKey);
-                            writeRowToBackup(key, packWidget(dpi, widgetInfo), data);
-                            mKeys.add(key);
-                            backupWidgetCount ++;
-                        }
-                    } else {
-                        if (VERBOSE) Log.v(TAG, "deferring widget backup " + backupKey);
-                        // too many widgets for this pass, request another.
-                        dataChanged();
-                    }
-                }
-            }
-        } finally {
-            cursor.close();
-        }
-    }
-
-    /**
-     * Read a widget from the stream.
-     *
-     * <P>Keys arrive in any order, so widgets that use this data may already exist.
-     *
-     * @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
-     */
-    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));
-        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 {
-                mIconCache.preloadIcon(ComponentName.unflattenFromString(widget.provider),
-                        icon, widget.icon.dpi, widget.label, mUserSerial, mIdp);
-            }
-        }
-
-        // Cache widget min sizes incase migration is required.
-        widgetSizes.add(widget.provider + "#" + widget.minSpanX + "," + widget.minSpanY);
-    }
-
-    /** create a new key, with an integer ID.
-     *
-     * <P> Keys contain their own checksum instead of using
-     * the heavy-weight CheckedMessage wrapper.
-     */
-    private Key getKey(int type, long id) {
-        Key key = new Key();
-        key.type = type;
-        key.id = id;
-        key.checksum = checkKey(key);
-        return key;
-    }
-
-    /** create a new key for a named object.
-     *
-     * <P> Keys contain their own checksum instead of using
-     * the heavy-weight CheckedMessage wrapper.
-     */
-    private Key getKey(int type, String name) {
-        Key key = new Key();
-        key.type = type;
-        key.name = name;
-        key.checksum = checkKey(key);
-        return key;
-    }
-
-    /** keys need to be strings, serialize and encode. */
-    private String keyToBackupKey(Key key) {
-        return Base64.encodeToString(Key.toByteArray(key), Base64.NO_WRAP);
-    }
-
-    /** keys need to be strings, decode and parse. */
-    private Key backupKeyToKey(String backupKey) throws InvalidBackupException {
-        try {
-            Key key = Key.parseFrom(Base64.decode(backupKey, Base64.DEFAULT));
-            if (key.checksum != checkKey(key)) {
-                throw new InvalidBackupException("invalid key read from stream" + backupKey);
-            }
-            return key;
-        } catch (InvalidProtocolBufferNanoException | IllegalArgumentException e) {
-            throw new InvalidBackupException(e);
-        }
-    }
-
-    /** Compute the checksum over the important bits of a key. */
-    private long checkKey(Key key) {
-        CRC32 checksum = new CRC32();
-        checksum.update(key.type);
-        checksum.update((int) (key.id & 0xffff));
-        checksum.update((int) ((key.id >> 32) & 0xffff));
-        if (!TextUtils.isEmpty(key.name)) {
-            checksum.update(key.name.getBytes());
-        }
-        return checksum.getValue();
-    }
-
-    /**
-     * @return true if its an hotseat item, that can be replaced during restore.
-     * TODO: Extend check for folders in hotseat.
-     */
-    private boolean isReplaceableHotseatItem(Favorite favorite) {
-        return favorite.container == Favorites.CONTAINER_HOTSEAT
-                && favorite.intent != null
-                && (favorite.itemType == Favorites.ITEM_TYPE_APPLICATION
-                || favorite.itemType == Favorites.ITEM_TYPE_SHORTCUT
-                || favorite.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT);
-    }
-
-    /** Serialize a Favorite for persistence, including a checksum wrapper. */
-    private Favorite packFavorite(Cursor c) {
-        Favorite favorite = new Favorite();
-        favorite.id = c.getLong(ID_INDEX);
-        favorite.screen = c.getInt(SCREEN_INDEX);
-        favorite.container = c.getInt(CONTAINER_INDEX);
-        favorite.cellX = c.getInt(CELLX_INDEX);
-        favorite.cellY = c.getInt(CELLY_INDEX);
-        favorite.spanX = c.getInt(SPANX_INDEX);
-        favorite.spanY = c.getInt(SPANY_INDEX);
-        favorite.rank = c.getInt(RANK_INDEX);
-
-        String title = c.getString(TITLE_INDEX);
-        if (!TextUtils.isEmpty(title)) {
-            favorite.title = title;
-        }
-        String intentDescription = c.getString(INTENT_INDEX);
-        Intent intent = null;
-        if (!TextUtils.isEmpty(intentDescription)) {
-            try {
-                intent = Intent.parseUri(intentDescription, 0);
-                intent.removeExtra(ItemInfo.EXTRA_PROFILE);
-                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) {
-            favorite.appWidgetId = c.getInt(APPWIDGET_ID_INDEX);
-            String appWidgetProvider = c.getString(APPWIDGET_PROVIDER_INDEX);
-            if (!TextUtils.isEmpty(appWidgetProvider)) {
-                favorite.appWidgetProvider = appWidgetProvider;
-            }
-        } else if (favorite.itemType == Favorites.ITEM_TYPE_SHORTCUT
-                || favorite.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
-            String iconPackage = c.getString(ICON_PACKAGE_INDEX);
-            String iconResource = c.getString(ICON_RESOURCE_INDEX);
-            if (!TextUtils.isEmpty(iconPackage) && !TextUtils.isEmpty(iconResource)) {
-                favorite.iconResource = iconResource;
-                favorite.iconPackage = iconPackage;
-            }
-
-            byte[] blob = c.getBlob(ICON_INDEX);
-            if (blob != null && blob.length > 0) {
-                favorite.icon = blob;
-            }
-        }
-
-        if (isReplaceableHotseatItem(favorite)) {
-            if (intent != null && intent.getComponent() != null) {
-                PackageManager pm = mContext.getPackageManager();
-                ActivityInfo activity = null;;
-                try {
-                    activity = pm.getActivityInfo(intent.getComponent(), 0);
-                } catch (NameNotFoundException e) {
-                    Log.e(TAG, "Target not found", e);
-                }
-                if (activity == null) {
-                    return favorite;
-                }
-                for (int i = 0; i < mItemTypeMatchers.length; i++) {
-                    if (mItemTypeMatchers[i] == null) {
-                        mItemTypeMatchers[i] = new ItemTypeMatcher(
-                                CommonAppTypeParser.getResourceForItemType(i));
-                    }
-                    if (mItemTypeMatchers[i].matches(activity, pm)) {
-                        favorite.targetType = i;
-                        break;
-                    }
-                }
-            }
-        }
-
-        return favorite;
-    }
-
-    /** Deserialize a Favorite from persistence, after verifying checksum wrapper. */
-    private ContentValues unpackFavorite(byte[] buffer, int dataSize)
-            throws IOException {
-        Favorite favorite = unpackProto(new Favorite(), buffer, dataSize);
-
-        // If it is a hotseat item, move it accordingly.
-        if (favorite.container == Favorites.CONTAINER_HOTSEAT) {
-            favorite.screen += mHotseatShift;
-        }
-
-        ContentValues values = new ContentValues();
-        values.put(Favorites._ID, favorite.id);
-        values.put(Favorites.SCREEN, favorite.screen);
-        values.put(Favorites.CONTAINER, favorite.container);
-        values.put(Favorites.CELLX, favorite.cellX);
-        values.put(Favorites.CELLY, favorite.cellY);
-        values.put(Favorites.SPANX, favorite.spanX);
-        values.put(Favorites.SPANY, favorite.spanY);
-        values.put(Favorites.RANK, favorite.rank);
-
-        if (favorite.itemType == Favorites.ITEM_TYPE_SHORTCUT
-                || favorite.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) {
-            values.put(Favorites.ICON_PACKAGE, favorite.iconPackage);
-            values.put(Favorites.ICON_RESOURCE, favorite.iconResource);
-            values.put(Favorites.ICON, favorite.icon);
-        }
-
-        if (!TextUtils.isEmpty(favorite.title)) {
-            values.put(Favorites.TITLE, favorite.title);
-        } else {
-            values.put(Favorites.TITLE, "");
-        }
-        if (!TextUtils.isEmpty(favorite.intent)) {
-            values.put(Favorites.INTENT, favorite.intent);
-        }
-        values.put(Favorites.ITEM_TYPE, favorite.itemType);
-
-        UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
-        long userSerialNumber =
-                UserManagerCompat.getInstance(mContext).getSerialNumberForUser(myUserHandle);
-        values.put(LauncherSettings.Favorites.PROFILE_ID, userSerialNumber);
-
-        // If we will attempt grid resize, use the original profile to validate grid size, as
-        // anything which fits in the original grid should fit in the current grid after
-        // grid migration.
-        DeviceProfieData currentProfile = migrationCompatibleProfileData == null
-                ? mDeviceProfileData : migrationCompatibleProfileData;
-
-        if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
-            if (!TextUtils.isEmpty(favorite.appWidgetProvider)) {
-                values.put(Favorites.APPWIDGET_PROVIDER, favorite.appWidgetProvider);
-            }
-            values.put(Favorites.APPWIDGET_ID, favorite.appWidgetId);
-            values.put(LauncherSettings.Favorites.RESTORED,
-                    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 {
-            // Check if it is an hotseat item, that can be replaced.
-            if (isReplaceableHotseatItem(favorite)
-                    && favorite.targetType != Favorite.TARGET_NONE
-                    && favorite.targetType < CommonAppTypeParser.SUPPORTED_TYPE_COUNT) {
-                Log.e(TAG, "Added item type flag");
-                values.put(LauncherSettings.Favorites.RESTORED,
-                        1 | CommonAppTypeParser.encodeItemTypeToFlag(favorite.targetType));
-            } 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 Screen packScreen(Cursor c) {
-        Screen screen = new Screen();
-        screen.id = c.getLong(ID_INDEX);
-        screen.rank = c.getInt(SCREEN_RANK_INDEX);
-        return screen;
-    }
-
-    /** Deserialize a Screen from persistence, after verifying checksum wrapper. */
-    private ContentValues unpackScreen(byte[] buffer, int dataSize)
-            throws InvalidProtocolBufferNanoException {
-        Screen screen = unpackProto(new Screen(), buffer, dataSize);
-        ContentValues values = new ContentValues();
-        values.put(WorkspaceScreens._ID, screen.id);
-        values.put(WorkspaceScreens.SCREEN_RANK, screen.rank);
-        return values;
-    }
-
-    /** Serialize an icon Resource for persistence, including a checksum wrapper. */
-    private Resource packIcon(int dpi, Bitmap icon) {
-        Resource res = new Resource();
-        res.dpi = dpi;
-        res.data = Utilities.flattenBitmap(icon);
-        return res;
-    }
-
-    /** Serialize a widget for persistence, including a checksum wrapper. */
-    private Widget packWidget(int dpi, LauncherAppWidgetProviderInfo info) {
-        Widget widget = new Widget();
-        widget.provider = info.provider.flattenToShortString();
-        widget.label = info.label;
-        widget.configure = info.configure != null;
-        if (info.icon != 0) {
-            widget.icon = new Resource();
-            Drawable fullResIcon = mIconCache.getFullResIcon(info.provider.getPackageName(), info.icon);
-            Bitmap icon = Utilities.createIconBitmap(fullResIcon, mContext);
-            widget.icon.data = Utilities.flattenBitmap(icon);
-            widget.icon.dpi = dpi;
-        }
-
-        Point spans = info.getMinSpans(mIdp, mContext);
-        widget.minSpanX = spans.x;
-        widget.minSpanY = spans.y;
-        return widget;
-    }
-
-    /**
-     * Deserialize a proto after verifying checksum wrapper.
-     */
-    private <T extends MessageNano> T unpackProto(T proto, byte[] buffer, int dataSize)
-            throws InvalidProtocolBufferNanoException {
-        MessageNano.mergeFrom(proto, readCheckedBytes(buffer, dataSize));
-        if (DEBUG) Log.d(TAG, "unpacked proto " + proto);
-        return proto;
-    }
-
-    /**
-     * Read the old journal from the input file.
-     *
-     * In the event of any error, just pretend we didn't have a journal,
-     * in that case, do a full backup.
-     *
-     * @param oldState the read-0only file descriptor pointing to the old journal
-     * @return a Journal protocol buffer
-     */
-    private Journal readJournal(ParcelFileDescriptor oldState) {
-        Journal journal = new Journal();
-        if (oldState == null) {
-            return journal;
-        }
-        FileInputStream inStream = new FileInputStream(oldState.getFileDescriptor());
-        try {
-            int availableBytes = inStream.available();
-            if (DEBUG) Log.d(TAG, "available " + availableBytes);
-            if (availableBytes < MAX_JOURNAL_SIZE) {
-                byte[] buffer = new byte[availableBytes];
-                int bytesRead = 0;
-                boolean valid = false;
-                InvalidProtocolBufferNanoException lastProtoException = null;
-                while (availableBytes > 0) {
-                    try {
-                        // OMG what are you doing? This is crazy inefficient!
-                        // If we read a byte that is not ours, we will cause trouble: b/12491813
-                        // However, we don't know how many bytes to expect (oops).
-                        // So we have to step through *slowly*, watching for the end.
-                        int result = inStream.read(buffer, bytesRead, 1);
-                        if (result > 0) {
-                            availableBytes -= result;
-                            bytesRead += result;
-                        } else {
-                            Log.w(TAG, "unexpected end of file while reading journal.");
-                            // stop reading and see what there is to parse
-                            availableBytes = 0;
-                        }
-                    } catch (IOException e) {
-                        buffer = null;
-                        availableBytes = 0;
-                    }
-
-                    // check the buffer to see if we have a valid journal
-                    try {
-                        MessageNano.mergeFrom(journal, readCheckedBytes(buffer, bytesRead));
-                        // if we are here, then we have read a valid, checksum-verified journal
-                        valid = true;
-                        availableBytes = 0;
-                        if (VERBOSE) Log.v(TAG, "read " + bytesRead + " bytes of journal");
-                    } catch (InvalidProtocolBufferNanoException e) {
-                        // if we don't have the whole journal yet, mergeFrom will throw. keep going.
-                        lastProtoException = e;
-                        journal.clear();
-                    }
-                }
-                if (DEBUG) Log.d(TAG, "journal bytes read: " + bytesRead);
-                if (!valid) {
-                    Log.w(TAG, "could not find a valid journal", lastProtoException);
-                }
-            }
-        } catch (IOException e) {
-            Log.w(TAG, "failed to close the journal", e);
-        } finally {
-            try {
-                inStream.close();
-            } catch (IOException e) {
-                Log.w(TAG, "failed to close the journal", e);
-            }
-        }
-        return journal;
-    }
-
-    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 {
-        byte[] blob = writeCheckedBytes(proto);
-        data.writeEntityHeader(backupKey, blob.length);
-        data.writeEntityData(blob, blob.length);
-        mBackupDataWasUpdated = true;
-        if (VERBOSE) Log.v(TAG, "Writing New entry " + backupKey);
-    }
-
-    /**
-     * Write the new journal to the output file.
-     *
-     * In the event of any error, just pretend we didn't have a journal,
-     * in that case, do a full backup.
-
-     * @param newState the write-only file descriptor pointing to the new journal
-     * @param journal a Journal protocol buffer
-     */
-    private void writeJournal(ParcelFileDescriptor newState, Journal journal) {
-        try {
-            FileOutputStream outStream = new FileOutputStream(newState.getFileDescriptor());
-            final byte[] journalBytes = writeCheckedBytes(journal);
-            outStream.write(journalBytes);
-            outStream.close();
-            if (VERBOSE) Log.v(TAG, "wrote " + journalBytes.length + " bytes of journal");
-        } catch (IOException e) {
-            Log.w(TAG, "failed to write backup journal", e);
-        }
-    }
-
-    /** Wrap a proto in a CheckedMessage and compute the checksum. */
-    private byte[] writeCheckedBytes(MessageNano proto) {
-        CheckedMessage wrapper = new CheckedMessage();
-        wrapper.payload = MessageNano.toByteArray(proto);
-        CRC32 checksum = new CRC32();
-        checksum.update(wrapper.payload);
-        wrapper.checksum = checksum.getValue();
-        return MessageNano.toByteArray(wrapper);
-    }
-
-    /** Unwrap a proto message from a CheckedMessage, verifying the checksum. */
-    private static byte[] readCheckedBytes(byte[] buffer, int dataSize)
-            throws InvalidProtocolBufferNanoException {
-        CheckedMessage wrapper = new CheckedMessage();
-        MessageNano.mergeFrom(wrapper, buffer, 0, dataSize);
-        CRC32 checksum = new CRC32();
-        checksum.update(wrapper.payload);
-        if (wrapper.checksum != checksum.getValue()) {
-            throw new InvalidProtocolBufferNanoException("checksum does not match");
-        }
-        return wrapper.payload;
-    }
-
-    /**
-     * @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);
-        if (cursor == null) {
-            // launcher data has been wiped, do nothing
-            return false;
-        }
-        cursor.close();
-
-        if (LauncherAppState.getInstanceNoCreate() == null) {
-            // launcher services are unavailable, try again later
-            return false;
-        }
-
-        return true;
-    }
-
-    private String getUserSelectionArg() {
-        return Favorites.PROFILE_ID + '=' + UserManagerCompat.getInstance(mContext)
-                .getSerialNumberForUser(UserHandleCompat.myUserHandle());
-    }
-
-    @Thunk class InvalidBackupException extends IOException {
-
-        private static final long serialVersionUID = 8931456637211665082L;
-
-        @Thunk InvalidBackupException(Throwable cause) {
-            super(cause);
-        }
-
-        @Thunk InvalidBackupException(String reason) {
-            super(reason);
-        }
-    }
-
-    public boolean shouldAttemptWorkspaceMigration() {
-        return migrationCompatibleProfileData != null;
-    }
-
-    /**
-     * A class to check if an activity can handle one of the intents from a list of
-     * predefined intents.
-     */
-    private class ItemTypeMatcher {
-
-        private final ArrayList<Intent> mIntents;
-
-        ItemTypeMatcher(int xml_res) {
-            mIntents = xml_res == 0 ? new ArrayList<Intent>() : parseIntents(xml_res);
-        }
-
-        private ArrayList<Intent> parseIntents(int xml_res) {
-            ArrayList<Intent> intents = new ArrayList<Intent>();
-            XmlResourceParser parser = mContext.getResources().getXml(xml_res);
-            try {
-                DefaultLayoutParser.beginDocument(parser, DefaultLayoutParser.TAG_RESOLVE);
-                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;
-                    } else if (DefaultLayoutParser.TAG_FAVORITE.equals(parser.getName())) {
-                        final String uri = DefaultLayoutParser.getAttributeValue(
-                                parser, DefaultLayoutParser.ATTR_URI);
-                        intents.add(Intent.parseUri(uri, 0));
-                    }
-                }
-            } catch (URISyntaxException | XmlPullParserException | IOException e) {
-                Log.e(TAG, "Unable to parse " + xml_res, e);
-            } finally {
-                parser.close();
-            }
-            return intents;
-        }
-
-        public boolean matches(ActivityInfo activity, PackageManager pm) {
-            for (Intent intent : mIntents) {
-                intent.setPackage(activity.packageName);
-                ResolveInfo info = pm.resolveActivity(intent, 0);
-                if (info != null && (info.activityInfo.name.equals(activity.name)
-                        || info.activityInfo.name.equals(activity.targetActivity))) {
-                    return true;
-                }
-            }
-            return false;
-        }
-    }
-}
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index f5b32ed..a79df0d 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -382,14 +382,6 @@
                 loadDefaultFavoritesIfNecessary();
                 return null;
             }
-            case LauncherSettings.Settings.METHOD_UPDATE_FOLDER_ITEMS_RANK: {
-                mOpenHelper.updateFolderItemsRank(mOpenHelper.getWritableDatabase(), false);
-                return null;
-            }
-            case LauncherSettings.Settings.METHOD_CONVERT_SHORTCUTS_TO_ACTIVITIES: {
-                mOpenHelper.convertShortcutsToLauncherActivities(mOpenHelper.getWritableDatabase());
-                return null;
-            }
             case LauncherSettings.Settings.METHOD_DELETE_DB: {
                 // Are you sure? (y/n)
                 mOpenHelper.createEmptyDB(mOpenHelper.getWritableDatabase());
@@ -439,8 +431,6 @@
      * Overridden in tests
      */
     protected void notifyListeners() {
-        // always notify the backup agent
-        LauncherBackupAgentHelper.dataChanged(getContext());
         mListenerHandler.sendEmptyMessage(ChangeListenerWrapper.MSG_LAUNCHER_PROVIDER_CHANGED);
     }
 
diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java
index c213c8d..8157eb3 100644
--- a/src/com/android/launcher3/LauncherSettings.java
+++ b/src/com/android/launcher3/LauncherSettings.java
@@ -285,9 +285,6 @@
         public static final String METHOD_CLEAR_EMPTY_DB_FLAG = "clear_empty_db_flag";
 
         public static final String METHOD_DELETE_EMPTY_FOLDERS = "delete_empty_folders";
-        public static final String METHOD_UPDATE_FOLDER_ITEMS_RANK = "update_folder_items_rank";
-        public static final String METHOD_CONVERT_SHORTCUTS_TO_ACTIVITIES =
-                "convert_shortcuts_to_launcher_activities";
 
         public static final String METHOD_NEW_ITEM_ID = "generate_new_item_id";
         public static final String METHOD_NEW_SCREEN_ID = "generate_new_screen_id";
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 2d3e8dd..a37fe5b 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -251,7 +251,7 @@
         if (mPageIndicatorViewId > -1) {
             mPageIndicator = (PageIndicator) parent.findViewById(mPageIndicatorViewId);
             mPageIndicator.setMarkersCount(getChildCount());
-            mPageIndicator.setContentDescription(getCurrentPageDescription());
+            mPageIndicator.setContentDescription(getPageIndicatorDescription());
         }
     }
 
@@ -442,7 +442,7 @@
     private void updatePageIndicator() {
         // Update the page indicator (when we aren't reordering)
         if (mPageIndicator != null) {
-            mPageIndicator.setContentDescription(getCurrentPageDescription());
+            mPageIndicator.setContentDescription(getPageIndicatorDescription());
             if (!isReordering(false)) {
                 mPageIndicator.setActiveMarker(getNextPage());
             }
@@ -2276,6 +2276,10 @@
         return false;
     }
 
+    protected String getPageIndicatorDescription() {
+        return getCurrentPageDescription();
+    }
+
     protected String getCurrentPageDescription() {
         return getContext().getString(R.string.default_scroll_format,
                 getNextPage() + 1, getChildCount());
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index a056c59..1b3f5df 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -3191,9 +3191,6 @@
         return (d.dragInfo instanceof LauncherAppWidgetInfo ||
                 d.dragInfo instanceof PendingAddWidgetInfo);
     }
-    private boolean isExternalDragWidget(DragObject d) {
-        return d.dragSource != this && isDragWidget(d);
-    }
 
     public void onDragOver(DragObject d) {
         // Skip drag over events while we are dragging over side pages
@@ -3215,7 +3212,7 @@
         final View child = (mDragInfo == null) ? null : mDragInfo.cell;
         // Identify whether we have dragged over a side page
         if (workspaceInModalState()) {
-            if (mLauncher.getHotseat() != null && !isExternalDragWidget(d)) {
+            if (mLauncher.getHotseat() != null && !isDragWidget(d)) {
                 if (isPointInSelfOverHotseat(d.x, d.y)) {
                     layout = mLauncher.getHotseat().getLayout();
                 }
@@ -4427,6 +4424,11 @@
     }
 
     @Override
+    protected String getPageIndicatorDescription() {
+        return getResources().getString(R.string.all_apps_button_label);
+    }
+
+    @Override
     protected String getCurrentPageDescription() {
         if (hasCustomContent() && getNextPage() == 0) {
             return mCustomContentDescription;
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index 79a15b9..30cd607 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -32,7 +32,6 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
-import android.view.inputmethod.InputMethodManager;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 
@@ -153,6 +152,7 @@
     private ExtendedEditText mSearchInput;
     private ImageView mSearchIcon;
     private HeaderElevationController mElevationController;
+    private int mSearchContainerOffsetTop;
 
     private SpannableStringBuilder mSearchQueryBuilder = null;
 
@@ -312,6 +312,8 @@
         mSearchContainer = findViewById(R.id.search_container);
         mSearchInput = (ExtendedEditText) findViewById(R.id.search_box_input);
         mSearchIcon = (ImageView) findViewById(R.id.search_icon);
+        mSearchContainerOffsetTop = getResources().getDimensionPixelSize(
+                R.dimen.all_apps_search_bar_margin_top);
 
         final LinearLayout.LayoutParams searchParams =
                 (LinearLayout.LayoutParams) mSearchInput.getLayoutParams();
@@ -335,12 +337,8 @@
         final OnClickListener searchFocusListener = new OnClickListener() {
             @Override
             public void onClick(View view) {
-                if (!mSearchInput.isFocused()) {
-                    mSearchInput.requestFocus();
-                    final InputMethodManager imm =
-                            (InputMethodManager)getContext().getSystemService(
-                                    Context.INPUT_METHOD_SERVICE);
-                    imm.showSoftInput(mSearchInput, 0);
+                if (!mSearchBarController.isSearchFieldFocused()) {
+                    mSearchBarController.focusSearchField();
                 }
             }
         };
@@ -419,13 +417,12 @@
                 mAdapter.setNumAppsPerRow(mNumAppsPerRow);
                 mApps.setNumAppsPerRow(mNumAppsPerRow, mNumPredictedAppsPerRow, new FullMergeAlgorithm());
                 if (mNumAppsPerRow > 0) {
-                    int iconSize = availableWidth / mNumAppsPerRow;
-                    int iconSpacing = (iconSize - grid.allAppsIconSizePx) / 2;
+                    int rvPadding = mAppsRecyclerView.getPaddingStart(); // Assumes symmetry
                     final int thumbMaxWidth =
                             getResources().getDimensionPixelSize(
                                     R.dimen.container_fastscroll_thumb_max_width);
-                    mSearchContainer.setPaddingRelative(
-                            iconSpacing + thumbMaxWidth, 0, iconSpacing + thumbMaxWidth, 0);
+                    mSearchContainer.setPaddingRelative(rvPadding + thumbMaxWidth, 0, rvPadding +
+                            thumbMaxWidth, 0);
                 }
             }
             super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -525,7 +522,7 @@
 
                 LinearLayout.LayoutParams llp =
                         (LinearLayout.LayoutParams) mSearchInput.getLayoutParams();
-                llp.topMargin = insets.top;
+                llp.topMargin = insets.top + mSearchContainerOffsetTop;
                 mSearchInput.setLayoutParams(llp);
                 mSearchIcon.setLayoutParams(llp);
 
diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
index 6540a23..d0b8abc 100644
--- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
+++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java
@@ -203,7 +203,6 @@
                             continue;
                         }
 
-
                         // Find the section name bounds
                         PointF sectionBounds = getAndCacheSectionBounds(sectionName);
 
diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
index 0babc1a..b42b762 100644
--- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java
+++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java
@@ -65,6 +65,8 @@
     private float mShiftCurrent;    // [0, mShiftRange]
     private float mShiftRange;      // changes depending on the orientation
 
+    private static final float DEFAULT_SHIFT_RANGE = 10;
+
 
     private static final float RECATCH_REJECTION_FRACTION = .0875f;
 
@@ -81,6 +83,7 @@
         mLauncher = launcher;
         mDetector = new VerticalPullDetector(launcher);
         mDetector.setListener(this);
+        mShiftCurrent = mShiftRange = DEFAULT_SHIFT_RANGE;
         mBezelSwipeUpHeight = launcher.getResources().getDimensionPixelSize(
                 R.dimen.all_apps_bezel_swipe_height);
     }
@@ -436,14 +439,12 @@
     @Override
     public void onLayoutChange(View v, int left, int top, int right, int bottom,
             int oldLeft, int oldTop, int oldRight, int oldBottom) {
+        float prevShiftRatio = mShiftCurrent / mShiftRange;
         if (!mLauncher.getDeviceProfile().isVerticalBarLayout()) {
             mShiftRange = top;
         } else {
             mShiftRange = bottom;
         }
-        if (!mLauncher.isAllAppsVisible()) {
-            setProgress(mShiftRange);
-        }
-        mHotseat.removeOnLayoutChangeListener(this);
+        setProgress(mShiftRange * prevShiftRatio);
     }
 }
diff --git a/src/com/android/launcher3/model/GridSizeMigrationTask.java b/src/com/android/launcher3/model/GridSizeMigrationTask.java
index cb1acaa..7287ced 100644
--- a/src/com/android/launcher3/model/GridSizeMigrationTask.java
+++ b/src/com/android/launcher3/model/GridSizeMigrationTask.java
@@ -24,7 +24,6 @@
 import com.android.launcher3.LauncherSettings.Favorites;
 import com.android.launcher3.Utilities;
 import com.android.launcher3.Workspace;
-import com.android.launcher3.backup.nano.BackupProtos;
 import com.android.launcher3.compat.AppWidgetManagerCompat;
 import com.android.launcher3.compat.PackageInstallerCompat;
 import com.android.launcher3.config.FeatureFlags;
@@ -51,10 +50,6 @@
     private static final String KEY_MIGRATION_SRC_WORKSPACE_SIZE = "migration_src_workspace_size";
     private static final String KEY_MIGRATION_SRC_HOTSEAT_COUNT = "migration_src_hotseat_count";
 
-    // Set of entries indicating minimum size a widget can be resized to. This is used during
-    // restore in case the widget has not been installed yet.
-    private static final String KEY_MIGRATION_WIDGET_MINSIZE = "migration_widget_min_size";
-
     // These are carefully selected weights for various item types (Math.random?), to allow for
     // the least absurd migration experience.
     private static final float WT_SHORTCUT = 1;
@@ -81,11 +76,9 @@
     private final int mDestHotseatSize;
 
     protected GridSizeMigrationTask(Context context, InvariantDeviceProfile idp,
-            HashSet<String> validPackages, HashMap<String, Point> widgetMinSize,
-            Point sourceSize, Point targetSize) {
+            HashSet<String> validPackages, Point sourceSize, Point targetSize) {
         mContext = context;
         mValidPackages = validPackages;
-        mWidgetMinSize.putAll(widgetMinSize);
         mIdp = idp;
 
         mSrcX = sourceSize.x;
@@ -886,16 +879,6 @@
         return String.format(Locale.ENGLISH, "%d,%d", x, y);
     }
 
-    public static void markForMigration(
-            Context context, HashSet<String> widgets, BackupProtos.DeviceProfieData srcProfile) {
-        Utilities.getPrefs(context).edit()
-                .putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE,
-                        getPointString((int) srcProfile.desktopCols, (int) srcProfile.desktopRows))
-                .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, (int) srcProfile.hotseatCount)
-                .putStringSet(KEY_MIGRATION_WIDGET_MINSIZE, widgets)
-                .apply();
-    }
-
     /**
      * Migrates the workspace and hotseat in case their sizes changed.
      * @return false if the migration failed.
@@ -957,14 +940,6 @@
                             + " to " + targetSize);
                 }
 
-                // Min widget sizes
-                HashMap<String, Point> widgetMinSize = new HashMap<>();
-                for (String s : Utilities.getPrefs(context).getStringSet(KEY_MIGRATION_WIDGET_MINSIZE,
-                        Collections.<String>emptySet())) {
-                    String[] parts = s.split("#");
-                    widgetMinSize.put(parts[0], parsePoint(parts[1]));
-                }
-
                 // Migrate the workspace grid, step by step.
                 while (targetSizeIndex < sourceSizeIndex ) {
                     // We only need to migrate the grid if source size is greater
@@ -974,8 +949,7 @@
 
                     if (new GridSizeMigrationTask(context,
                             LauncherAppState.getInstance().getInvariantDeviceProfile(),
-                            validPackages, widgetMinSize,
-                            stepSourceSize, stepTargetSize).migrateWorkspace()) {
+                            validPackages, stepSourceSize, stepTargetSize).migrateWorkspace()) {
                         dbChanged = true;
                     }
                     sourceSizeIndex--;
@@ -1006,7 +980,6 @@
             prefs.edit()
                     .putString(KEY_MIGRATION_SRC_WORKSPACE_SIZE, gridSizeString)
                     .putInt(KEY_MIGRATION_SRC_HOTSEAT_COUNT, idp.numHotseatIcons)
-                    .remove(KEY_MIGRATION_WIDGET_MINSIZE)
                     .apply();
         }
     }
diff --git a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
index bb6ed0d..4addbfa 100644
--- a/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
+++ b/src/com/android/launcher3/provider/LossyScreenMigrationTask.java
@@ -47,8 +47,9 @@
     protected LossyScreenMigrationTask(
             Context context, InvariantDeviceProfile idp, SQLiteDatabase db) {
         // Decrease the rows count by 1
-        super(context, idp, getValidPackages(context), new HashMap<String, Point>(),
-                new Point(idp.numColumns, idp.numRows + 1), new Point(idp.numColumns, idp.numRows));
+        super(context, idp, getValidPackages(context),
+                new Point(idp.numColumns, idp.numRows + 1),
+                new Point(idp.numColumns, idp.numRows));
 
         mDb = db;
         mOriginalItems = new LongArrayMap<>();
diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
index c250cb2..4dae42f 100644
--- a/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
+++ b/tests/src/com/android/launcher3/model/GridSizeMigrationTaskTest.java
@@ -15,7 +15,6 @@
 import com.android.launcher3.util.TestLauncherProvider;
 
 import java.util.ArrayList;
-import java.util.HashMap;
 import java.util.HashSet;
 
 /**
@@ -130,7 +129,7 @@
                 {  5,  2, -1,  6},
         }});
 
-        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Column 2 and row 2 got removed.
@@ -149,7 +148,7 @@
                 {  5,  2, -1,  6},
         }});
 
-        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Items in the second column get moved to new screen
@@ -173,7 +172,7 @@
                 {  3,  1, -1,  4},
         }});
 
-        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Items in the second column of the first screen should get placed on the 3rd
@@ -204,7 +203,7 @@
                 {  5,  2, -1,  6},
         }});
 
-        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Items in the second column of the first screen should get placed on a new screen.
@@ -231,7 +230,7 @@
                 {  5,  2,  7, -1},
         }}, 0);
 
-        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages,
                 new Point(4, 4), new Point(3, 4)).migrateWorkspace();
 
         // Items in the second column of the first screen should get placed on a new screen.
@@ -254,7 +253,7 @@
                 {  5,  6,  7, -1},
         }}, 0);
 
-        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages, new HashMap<String, Point>(),
+        new GridSizeMigrationTask(getMockContext(), mIdp, mValidPackages,
                 new Point(4, 4), new Point(3, 3)).migrateWorkspace();
 
         // Items in the second column of the first screen should get placed on a new screen.
