Saving/restoring current page in AppsCustomize. (5050168)

Change-Id: Ib868033a2b71383abc4569082675f391d3e4cc76
diff --git a/src/com/android/launcher2/AppsCustomizePagedView.java b/src/com/android/launcher2/AppsCustomizePagedView.java
index 9d03995..76be116 100644
--- a/src/com/android/launcher2/AppsCustomizePagedView.java
+++ b/src/com/android/launcher2/AppsCustomizePagedView.java
@@ -164,6 +164,10 @@
     private final LayoutInflater mLayoutInflater;
     private final PackageManager mPackageManager;
 
+    // Save and Restore
+    private int mSaveInstanceStateItemIndex = -1;
+    private int mRestorePage = -1;
+
     // Content
     private ContentType mContentType;
     private ArrayList<ApplicationInfo> mApps;
@@ -252,6 +256,58 @@
         }
     }
 
+    /** Returns the item index of the center item on this page so that we can restore to this
+     *  item index when we rotate. */
+    private int getMiddleComponentIndexOnCurrentPage() {
+        int i = -1;
+        if (getPageCount() > 0) {
+            int currentPage = getCurrentPage();
+            switch (mContentType) {
+            case Applications: {
+                PagedViewCellLayout layout = (PagedViewCellLayout) getChildAt(currentPage);
+                PagedViewCellLayoutChildren childrenLayout = layout.getChildrenLayout();
+                int numItemsPerPage = mCellCountX * mCellCountY;
+                int childCount = childrenLayout.getChildCount();
+                if (childCount > 0) {
+                    i = (currentPage * numItemsPerPage) + (childCount / 2);
+                }}
+                break;
+            case Widgets: {
+                PagedViewGridLayout layout = (PagedViewGridLayout) getChildAt(currentPage);
+                int numItemsPerPage = mWidgetCountX * mWidgetCountY;
+                int childCount = layout.getChildCount();
+                if (childCount > 0) {
+                    i = (currentPage * numItemsPerPage) + (childCount / 2);
+                }}
+                break;
+            }
+        }
+        return i;
+    }
+
+    /** Get the index of the item to restore to if we need to restore the current page. */
+    int getSaveInstanceStateIndex() {
+        if (mSaveInstanceStateItemIndex == -1) {
+            mSaveInstanceStateItemIndex = getMiddleComponentIndexOnCurrentPage();
+        }
+        return mSaveInstanceStateItemIndex;
+    }
+
+    /** Returns the page in the current orientation which is expected to contain the specified
+     *  item index. */
+    int getPageForComponent(int index) {
+        switch (mContentType) {
+        case Applications: {
+            int numItemsPerPage = mCellCountX * mCellCountY;
+            return (index / numItemsPerPage);
+        }
+        case Widgets: {
+            int numItemsPerPage = mWidgetCountX * mWidgetCountY;
+            return (index / numItemsPerPage);
+        }}
+        return -1;
+    }
+
     /**
      * This differs from isDataReady as this is the test done if isDataReady is not set.
      */
@@ -261,6 +317,20 @@
         return !mApps.isEmpty();
     }
 
+    /** Restores the page for an item at the specified index */
+    void restorePageForIndex(int index) {
+        if (index < 0) return;
+
+        int page = getPageForComponent(index);
+        if (page > -1) {
+            if (getChildCount() > 0) {
+                invalidatePageData(page);
+            } else {
+                mRestorePage = page;
+            }
+        }
+    }
+
     protected void onDataReady(int width, int height) {
         // Note that we transpose the counts in portrait so that we get a similar layout
         boolean isLandscape = getResources().getConfiguration().orientation ==
@@ -288,7 +358,8 @@
         int heightSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(), MeasureSpec.AT_MOST);
         mWidgetSpacingLayout.measure(widthSpec, heightSpec);
         mContentWidth = mWidgetSpacingLayout.getContentWidth();
-        invalidatePageData();
+        invalidatePageData(Math.max(0, mRestorePage));
+        mRestorePage = -1;
     }
 
     @Override
@@ -1036,6 +1107,10 @@
         setChildrenDrawnWithCacheEnabled(false);
         */
         super.onPageEndMoving();
+
+        // We reset the save index when we change pages so that it will be recalculated on next
+        // rotation
+        mSaveInstanceStateItemIndex = -1;
     }
 
     /*
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 7ab41bc..216ce40 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -672,8 +672,8 @@
                 mAppsCustomizeTabHost.setCurrentTabByTag(curTab);
             }
 
-            // Note: currently we do not restore the page for the AppsCustomize pane because the
-            // change in layout can drastically affect the saved page index
+            int currentIndex = savedState.getInt("apps_customize_currentIndex");
+            mAppsCustomizeContent.restorePageForIndex(currentIndex);
         }
     }
 
@@ -1132,6 +1132,8 @@
             if (currentTabTag != null) {
                 outState.putString("apps_customize_currentTab", currentTabTag);
             }
+            int currentIndex = mAppsCustomizeContent.getSaveInstanceStateIndex();
+            outState.putInt("apps_customize_currentIndex", currentIndex);
         }
     }
 
diff --git a/src/com/android/launcher2/PagedView.java b/src/com/android/launcher2/PagedView.java
index d2d734c..c1d92cf 100644
--- a/src/com/android/launcher2/PagedView.java
+++ b/src/com/android/launcher2/PagedView.java
@@ -1640,7 +1640,7 @@
 
             // Set a new page as the current page if necessary
             if (currentPage > -1) {
-                setCurrentPage(currentPage);
+                setCurrentPage(Math.min(getPageCount() - 1, currentPage));
             }
 
             // Mark each of the pages as dirty
diff --git a/src/com/android/launcher2/PagedViewCellLayout.java b/src/com/android/launcher2/PagedViewCellLayout.java
index 63cf9e8..803e700 100644
--- a/src/com/android/launcher2/PagedViewCellLayout.java
+++ b/src/com/android/launcher2/PagedViewCellLayout.java
@@ -192,6 +192,10 @@
         return mChildren.getChildCount();
     }
 
+    public PagedViewCellLayoutChildren getChildrenLayout() {
+        return mChildren;
+    }
+
     @Override
     public View getChildOnPageAt(int i) {
         return mChildren.getChildAt(i);