Correctly preserve state on orientation changes

Bug: 3049975
diff --git a/src/com/android/launcher2/CellLayout.java b/src/com/android/launcher2/CellLayout.java
index 98aad14..8631e2c 100644
--- a/src/com/android/launcher2/CellLayout.java
+++ b/src/com/android/launcher2/CellLayout.java
@@ -1374,24 +1374,6 @@
         return false;
     }
 
-    /**
-     * Update the array of occupied cells (mOccupied), and return a flattened copy of the array.
-     */
-    boolean[] getOccupiedCellsFlattened() {
-        final int xCount = mCountX;
-        final int yCount = mCountY;
-        final boolean[][] occupied = mOccupied;
-
-        final boolean[] flat = new boolean[xCount * yCount];
-        for (int y = 0; y < yCount; y++) {
-            for (int x = 0; x < xCount; x++) {
-                flat[y * xCount + x] = occupied[x][y];
-            }
-        }
-
-        return flat;
-    }
-
     private void clearOccupiedCells() {
         for (int x = 0; x < mCountX; x++) {
             for (int y = 0; y < mCountY; y++) {
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 471cb3e..9e66191 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -150,8 +150,8 @@
 
     // Type: int
     private static final String RUNTIME_STATE_CURRENT_SCREEN = "launcher.current_screen";
-    // Type: boolean
-    private static final String RUNTIME_STATE_ALL_APPS_FOLDER = "launcher.all_apps_folder";
+    // Type: int
+    private static final String RUNTIME_STATE = "launcher.state";
     // Type: long
     private static final String RUNTIME_STATE_USER_FOLDERS = "launcher.user_folder";
     // Type: int
@@ -802,6 +802,22 @@
     }
 
     /**
+     * Given the integer (ordinal) value of a State enum instance, convert it to a variable of type
+     * State
+     */
+    private static State intToState(int stateOrdinal) {
+        State state = State.WORKSPACE;
+        final State[] stateValues = State.values();
+        for (int i = 0; i < stateValues.length; i++) {
+            if (stateValues[i].ordinal() == stateOrdinal) {
+                state = stateValues[i];
+                break;
+            }
+        }
+        return state;
+    }
+
+    /**
      * Restores the previous state, if it exists.
      *
      * @param savedState The previous state.
@@ -811,9 +827,12 @@
             return;
         }
 
-        final boolean allApps = savedState.getBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, false);
-        if (allApps) {
+        State state = intToState(savedState.getInt(RUNTIME_STATE, State.WORKSPACE.ordinal()));
+
+        if (state == State.ALL_APPS) {
             showAllApps(false);
+        } else if (state == State.CUSTOMIZE) {
+            showCustomizationDrawer(false);
         }
 
         final int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
@@ -1232,10 +1251,7 @@
             super.onSaveInstanceState(outState);
         }
 
-        // TODO should not do this if the drawer is currently closing.
-        if (mState == State.ALL_APPS) {
-            outState.putBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, true);
-        }
+        outState.putInt(RUNTIME_STATE, mState.ordinal());
 
         if (mAddScreen > -1 && mWaitingForResult) {
             outState.putInt(RUNTIME_STATE_PENDING_ADD_SCREEN, mAddScreen);
@@ -2550,8 +2566,9 @@
     }
 
     void showAllApps(boolean animated) {
-        if (mState == State.ALL_APPS)
+        if (mState == State.ALL_APPS) {
             return;
+        }
 
         if (LauncherApplication.isScreenXLarge()) {
             if (mState == State.CUSTOMIZE) {
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index 56e78c3..7399a9e 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -88,8 +88,6 @@
 
     private int mDefaultPage;
 
-    private boolean mWaitingToShrinkToBottom = false;
-
     private boolean mPageMoving = false;
 
     /**
@@ -136,6 +134,8 @@
     private enum ShrinkPosition {
         SHRINK_TO_TOP, SHRINK_TO_MIDDLE, SHRINK_TO_BOTTOM_HIDDEN, SHRINK_TO_BOTTOM_VISIBLE };
     private ShrinkPosition mShrunkenState;
+    private boolean mWaitingToShrink = false;
+    private ShrinkPosition mWaitingToShrinkPosition;
 
     private boolean mInScrollArea = false;
 
@@ -542,9 +542,9 @@
 
         // if shrinkToBottom() is called on initialization, it has to be deferred
         // until after the first call to onLayout so that it has the correct width
-        if (mWaitingToShrinkToBottom) {
-            shrinkToBottom(false);
-            mWaitingToShrinkToBottom = false;
+        if (mWaitingToShrink) {
+            shrink(mWaitingToShrinkPosition, false);
+            mWaitingToShrink = false;
         }
 
         if (LauncherApplication.isInPlaceRotationEnabled()) {
@@ -665,15 +665,7 @@
     }
 
     void shrinkToBottom(boolean animated) {
-        if (mFirstLayout) {
-            // (mFirstLayout == "first layout has not happened yet")
-            // if we get a call to shrink() as part of our initialization (for example, if
-            // Launcher is started in All Apps mode) then we need to wait for a layout call
-            // to get our width so we can layout the mini-screen views correctly
-            mWaitingToShrinkToBottom = true;
-        } else {
-            shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, animated);
-        }
+        shrink(ShrinkPosition.SHRINK_TO_BOTTOM_HIDDEN, animated);
     }
 
     private float getYScaleForScreen(int screen) {
@@ -690,6 +682,15 @@
 
     // we use this to shrink the workspace for the all apps view and the customize view
     private void shrink(ShrinkPosition shrinkPosition, boolean animated) {
+        if (mFirstLayout) {
+            // (mFirstLayout == "first layout has not happened yet")
+            // if we get a call to shrink() as part of our initialization (for example, if
+            // Launcher is started in All Apps mode) then we need to wait for a layout call
+            // to get our width so we can layout the mini-screen views correctly
+            mWaitingToShrink = true;
+            mWaitingToShrinkPosition = shrinkPosition;
+            return;
+        }
         mIsSmall = true;
         mShrunkenState = shrinkPosition;
 
@@ -774,9 +775,9 @@
             } else {
                 cl.setX((int)newX);
                 cl.setY((int)newY);
-                cl.setScaleX(SHRINK_FACTOR * rotationScaleX);
-                cl.setScaleY(SHRINK_FACTOR * rotationScaleY);
-                cl.setBackgroundAlpha(1.0f);
+                cl.setScaleX(SHRINK_FACTOR * rotationScaleX * extraShrinkFactor);
+                cl.setScaleY(SHRINK_FACTOR * rotationScaleY * extraShrinkFactor);
+                cl.setBackgroundAlpha(finalAlpha);
                 cl.setAlpha(finalAlpha);
                 cl.setRotationY(rotation);
             }