Merge "Allowing ability to pick up items / enter overview before full page settle" into jb-ub-now-jolly-elf
diff --git a/src/com/android/launcher3/DynamicGrid.java b/src/com/android/launcher3/DynamicGrid.java
index 42aa20d..ce78553 100644
--- a/src/com/android/launcher3/DynamicGrid.java
+++ b/src/com/android/launcher3/DynamicGrid.java
@@ -74,10 +74,10 @@
         // 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,  6, 6,  72, 14.4f,  7, 60));
+                575, 904,  5, 5,  72, 14.4f,  7, 60));
         // Larger tablet profiles always have system bars on the top & bottom
         deviceProfiles.add(new DeviceProfile("Nexus 10",
-                727, 1207,  5, 8,  80, 14.4f,  9, 64));
+                727, 1207,  5, 5,  80, 14.4f,  7, 64));
         /*
         deviceProfiles.add(new DeviceProfile("Nexus 7",
                 600, 960,  5, 5,  72, 14.4f,  5, 60));
diff --git a/src/com/android/launcher3/FastBitmapDrawable.java b/src/com/android/launcher3/FastBitmapDrawable.java
index 83be143..85e9020 100644
--- a/src/com/android/launcher3/FastBitmapDrawable.java
+++ b/src/com/android/launcher3/FastBitmapDrawable.java
@@ -32,6 +32,7 @@
     FastBitmapDrawable(Bitmap b) {
         mAlpha = 255;
         mBitmap = b;
+        setBounds(0, 0, b.getWidth(), b.getHeight());
     }
 
     @Override
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 89abd9f..7d84a3c 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -459,7 +459,7 @@
             } else {
                 // We only load the page synchronously if the user rotates (or triggers a
                 // configuration change) while launcher is in the foreground
-                mModel.startLoader(true, mWorkspace.getCurrentPage());
+                mModel.startLoader(true, mWorkspace.getRestorePage());
             }
         }
 
@@ -1801,7 +1801,8 @@
     @Override
     protected void onSaveInstanceState(Bundle outState) {
         if (mWorkspace.getChildCount() > 0) {
-            outState.putInt(RUNTIME_STATE_CURRENT_SCREEN, mWorkspace.getRestorePage());
+            outState.putInt(RUNTIME_STATE_CURRENT_SCREEN,
+                    mWorkspace.getCurrentPageOffsetFromCustomContent());
         }
         super.onSaveInstanceState(outState);
 
diff --git a/src/com/android/launcher3/LauncherModel.java b/src/com/android/launcher3/LauncherModel.java
index 5a3b1b8..6a6cb35 100644
--- a/src/com/android/launcher3/LauncherModel.java
+++ b/src/com/android/launcher3/LauncherModel.java
@@ -1636,7 +1636,9 @@
             LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary(0);
 
             // Check if we need to do any upgrade-path logic
+            // (Includes having just imported default favorites)
             boolean loadedOldDb = LauncherAppState.getLauncherProvider().justLoadedOldDb();
+
             // Log to disk
             Launcher.addDumpLog(TAG, "11683562 -   loadedOldDb: " + loadedOldDb, true);
 
@@ -2026,7 +2028,7 @@
 
         /** Filters the set of items who are directly or indirectly (via another container) on the
          * specified screen. */
-        private void filterCurrentWorkspaceItems(int currentScreen,
+        private void filterCurrentWorkspaceItems(long currentScreenId,
                 ArrayList<ItemInfo> allWorkspaceItems,
                 ArrayList<ItemInfo> currentScreenItems,
                 ArrayList<ItemInfo> otherScreenItems) {
@@ -2041,8 +2043,8 @@
 
             // If we aren't filtering on a screen, then the set of items to load is the full set of
             // items given.
-            if (currentScreen < 0) {
-                currentScreenItems.addAll(allWorkspaceItems);
+            if (currentScreenId < 0) {
+                throw new RuntimeException("Unexpected screen id");
             }
 
             // Order the set of items by their containers first, this allows use to walk through the
@@ -2057,7 +2059,7 @@
             });
             for (ItemInfo info : allWorkspaceItems) {
                 if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
-                    if (info.screenId == currentScreen) {
+                    if (info.screenId == currentScreenId) {
                         currentScreenItems.add(info);
                         itemsOnScreen.add(info.id);
                     } else {
@@ -2078,20 +2080,20 @@
         }
 
         /** Filters the set of widgets which are on the specified screen. */
-        private void filterCurrentAppWidgets(int currentScreen,
+        private void filterCurrentAppWidgets(long currentScreenId,
                 ArrayList<LauncherAppWidgetInfo> appWidgets,
                 ArrayList<LauncherAppWidgetInfo> currentScreenWidgets,
                 ArrayList<LauncherAppWidgetInfo> otherScreenWidgets) {
             // If we aren't filtering on a screen, then the set of items to load is the full set of
             // widgets given.
-            if (currentScreen < 0) {
-                currentScreenWidgets.addAll(appWidgets);
+            if (currentScreenId < 0) {
+                throw new RuntimeException("Unexpected screen id");
             }
 
             for (LauncherAppWidgetInfo widget : appWidgets) {
                 if (widget == null) continue;
                 if (widget.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                        widget.screenId == currentScreen) {
+                        widget.screenId == currentScreenId) {
                     currentScreenWidgets.add(widget);
                 } else {
                     otherScreenWidgets.add(widget);
@@ -2100,15 +2102,15 @@
         }
 
         /** Filters the set of folders which are on the specified screen. */
-        private void filterCurrentFolders(int currentScreen,
+        private void filterCurrentFolders(long currentScreenId,
                 HashMap<Long, ItemInfo> itemsIdMap,
                 HashMap<Long, FolderInfo> folders,
                 HashMap<Long, FolderInfo> currentScreenFolders,
                 HashMap<Long, FolderInfo> otherScreenFolders) {
             // If we aren't filtering on a screen, then the set of items to load is the full set of
             // widgets given.
-            if (currentScreen < 0) {
-                currentScreenFolders.putAll(folders);
+            if (currentScreenId < 0) {
+                throw new RuntimeException("Unexpected screen id");
             }
 
             for (long id : folders.keySet()) {
@@ -2116,7 +2118,7 @@
                 FolderInfo folder = folders.get(id);
                 if (info == null || folder == null) continue;
                 if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP &&
-                        info.screenId == currentScreen) {
+                        info.screenId == currentScreenId) {
                     currentScreenFolders.put(id, folder);
                 } else {
                     otherScreenFolders.put(id, folder);
@@ -2243,13 +2245,7 @@
                 return;
             }
 
-            final boolean isLoadingSynchronously = (synchronizeBindPage > -1);
-            final int currentScreen = isLoadingSynchronously ? synchronizeBindPage :
-                oldCallbacks.getCurrentWorkspaceScreen();
-
-            // Load all the items that are on the current page first (and in the process, unbind
-            // all the existing workspace items before we call startBinding() below.
-            unbindWorkspaceItemsOnMainThread();
+            // Save a copy of all the bg-thread collections
             ArrayList<ItemInfo> workspaceItems = new ArrayList<ItemInfo>();
             ArrayList<LauncherAppWidgetInfo> appWidgets =
                     new ArrayList<LauncherAppWidgetInfo>();
@@ -2264,6 +2260,20 @@
                 orderedScreenIds.addAll(sBgWorkspaceScreens);
             }
 
+            final boolean isLoadingSynchronously = (synchronizeBindPage > -1);
+            final int currentScreen = isLoadingSynchronously ? synchronizeBindPage :
+                oldCallbacks.getCurrentWorkspaceScreen();
+            if (currentScreen >= orderedScreenIds.size()) {
+                Log.w(TAG, "Invalid screen id to synchronously load");
+                return;
+            }
+            final long currentScreenId = orderedScreenIds.get(currentScreen);
+
+            // Load all the items that are on the current page first (and in the process, unbind
+            // all the existing workspace items before we call startBinding() below.
+            unbindWorkspaceItemsOnMainThread();
+
+            // Separate the items that are on the current screen, and all the other remaining items
             ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<ItemInfo>();
             ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<ItemInfo>();
             ArrayList<LauncherAppWidgetInfo> currentAppWidgets =
@@ -2273,12 +2283,11 @@
             HashMap<Long, FolderInfo> currentFolders = new HashMap<Long, FolderInfo>();
             HashMap<Long, FolderInfo> otherFolders = new HashMap<Long, FolderInfo>();
 
-            // Separate the items that are on the current screen, and all the other remaining items
-            filterCurrentWorkspaceItems(currentScreen, workspaceItems, currentWorkspaceItems,
+            filterCurrentWorkspaceItems(currentScreenId, workspaceItems, currentWorkspaceItems,
                     otherWorkspaceItems);
-            filterCurrentAppWidgets(currentScreen, appWidgets, currentAppWidgets,
+            filterCurrentAppWidgets(currentScreenId, appWidgets, currentAppWidgets,
                     otherAppWidgets);
-            filterCurrentFolders(currentScreen, itemsIdMap, folders, currentFolders,
+            filterCurrentFolders(currentScreenId, itemsIdMap, folders, currentFolders,
                     otherFolders);
             sortWorkspaceItemsSpatially(currentWorkspaceItems);
             sortWorkspaceItemsSpatially(otherWorkspaceItems);
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index b5db338..dbc1b1c 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -71,6 +71,9 @@
     static final String OLD_AUTHORITY = "com.android.launcher2.settings";
     static final String AUTHORITY = ProviderConfig.AUTHORITY;
 
+    // Should we attempt to load anything from the com.android.launcher2 provider?
+    static final boolean IMPORT_LAUNCHER2_DATABASE = true;
+
     static final String TABLE_FAVORITES = "favorites";
     static final String TABLE_WORKSPACE_SCREENS = "workspaceScreens";
     static final String PARAMETER_NOTIFY = "notify";
@@ -366,32 +369,38 @@
                 sendAppWidgetResetNotify();
             }
 
-            // Try converting the old database
-            ContentValuesCallback permuteScreensCb = new ContentValuesCallback() {
-                public void onRow(ContentValues values) {
-                    int container = values.getAsInteger(LauncherSettings.Favorites.CONTAINER);
-                    if (container == Favorites.CONTAINER_DESKTOP) {
-                        int screen = values.getAsInteger(LauncherSettings.Favorites.SCREEN);
-                        screen = (int) upgradeLauncherDb_permuteScreens(screen);
-                        values.put(LauncherSettings.Favorites.SCREEN, screen);
+            if (IMPORT_LAUNCHER2_DATABASE) {
+                // Try converting the old database
+                ContentValuesCallback permuteScreensCb = new ContentValuesCallback() {
+                    public void onRow(ContentValues values) {
+                        int container = values.getAsInteger(LauncherSettings.Favorites.CONTAINER);
+                        if (container == Favorites.CONTAINER_DESKTOP) {
+                            int screen = values.getAsInteger(LauncherSettings.Favorites.SCREEN);
+                            screen = (int) upgradeLauncherDb_permuteScreens(screen);
+                            values.put(LauncherSettings.Favorites.SCREEN, screen);
+                        }
+                    }
+                };
+                Uri uri = Uri.parse("content://" + Settings.AUTHORITY +
+                        "/old_favorites?notify=true");
+                if (!convertDatabase(db, uri, permuteScreensCb, true)) {
+                    // Try and upgrade from the Launcher2 db
+                    uri = LauncherSettings.Favorites.OLD_CONTENT_URI;
+                    if (!convertDatabase(db, uri, permuteScreensCb, false)) {
+                        // If we fail, then set a flag to load the default workspace
+                        setFlagEmptyDbCreated();
+                        return;
                     }
                 }
-            };
-            Uri uri = Uri.parse("content://" + Settings.AUTHORITY +
-                    "/old_favorites?notify=true");
-            if (!convertDatabase(db, uri, permuteScreensCb, true)) {
-                // Try and upgrade from the Launcher2 db
-                uri = LauncherSettings.Favorites.OLD_CONTENT_URI;
-                if (!convertDatabase(db, uri, permuteScreensCb, false)) {
-                    // If we fail, then set a flag to load the default workspace
-                    setFlagEmptyDbCreated();
-                    return;
-                }
+                // Right now, in non-default workspace cases, we want to run the final
+                // upgrade code (ie. to fix workspace screen indices -> ids, etc.), so
+                // set that flag too.
+                setFlagJustLoadedOldDb();
+            } else {
+                // Fresh and clean launcher DB.
+                mMaxItemId = initializeMaxItemId(db);
+                setFlagEmptyDbCreated();
             }
-            // Right now, in non-default workspace cases, we want to run the final
-            // upgrade code (ie. to fix workspace screen indices -> ids, etc.), so
-            // set that flag too.
-            setFlagJustLoadedOldDb();
         }
 
         private void addWorkspacesTable(SQLiteDatabase db) {
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index 370c629..2c7114b 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -570,6 +570,9 @@
     void setRestorePage(int restorePage) {
         mRestorePage = restorePage;
     }
+    int getRestorePage() {
+        return mRestorePage;
+    }
 
     protected void notifyPageSwitchListener() {
         if (mPageSwitchListener != null) {
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 4d72852..ba28dcf 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -690,7 +690,8 @@
             mWorkspaceScreens.put(EXTRA_EMPTY_SCREEN_ID, finalScreen);
             mScreenOrder.add(EXTRA_EMPTY_SCREEN_ID);
 
-            // XXX: Do we need to update LM workspace screens here?
+            // Update the model if we have changed any screens
+            mLauncher.getModel().updateWorkspaceScreenOrder(mLauncher, mScreenOrder);
             Launcher.addDumpLog(TAG, "11683562 -   extra empty screen: " + finalScreenId, true);
         }
     }
@@ -3960,7 +3961,7 @@
         return mDragInfo;
     }
 
-    public int getRestorePage() {
+    public int getCurrentPageOffsetFromCustomContent() {
         return getNextPage() - numCustomPages();
     }