Fix bug 2250457 - Open folder on home screen changes changes the behaviour of the home button

Now, home always goes to the center worksapce screen and back from an
app goes to all apps if it was open.

Getting that animations smooth took a little bit of work.
diff --git a/res/raw/rollo3.c b/res/raw/rollo3.c
index cbcdb22..b2b6cf1 100644
--- a/res/raw/rollo3.c
+++ b/res/raw/rollo3.c
@@ -126,6 +126,12 @@
 	// debugF("======= moveTo", state->targetPos);
 }
 
+void setZoom() {
+    g_Zoom = state->zoomTarget;
+    g_DrawLastFrame = 1;
+    updateReadback();
+}
+
 void fling() {
     g_LastTouchDown = 0;
     g_PosVelocity = -state->flingVelocity * 4;
diff --git a/src/com/android/launcher2/AllAppsView.java b/src/com/android/launcher2/AllAppsView.java
index 722213d..a7a1e64 100644
--- a/src/com/android/launcher2/AllAppsView.java
+++ b/src/com/android/launcher2/AllAppsView.java
@@ -112,6 +112,9 @@
 
     private boolean mShouldGainFocus;
 
+    private boolean mZoomDirty = false;
+    private float mNextZoom;
+    private boolean mNextAnimate;
 
     static class Defines {
         public static final int ALLOC_PARAMS = 0;
@@ -185,7 +188,6 @@
         super.surfaceChanged(holder, format, w, h);
 
         if (mRS == null) {
-
             mRS = createRenderScript(true);
             mRollo = new RolloRS();
             mRollo.mHasSurface = true;
@@ -198,6 +200,7 @@
                 gainFocus();
                 mShouldGainFocus = false;
             }
+            mRollo.dirtyCheck();
         } else {
             mRollo.mHasSurface = true;
             mRollo.dirtyCheck();
@@ -572,32 +575,44 @@
     }
 
     /**
-     * Zoom to the specifed amount.
+     * Zoom to the specifed level.
      *
-     * @param amount [0..1] 0 is hidden, 1 is open
+     * @param zoom [0..1] 0 is hidden, 1 is open
      */
-    public void zoom(float amount) {
-        if (mRollo == null) {
-            return;
-        }
-
+    public void zoom(float zoom, boolean animate) {
         cancelLongPress();
-        mRollo.clearSelectedIcon();
-        mRollo.setHomeSelected(SELECTED_NONE);
-        if (amount > 0.001f) {
-            // set in readback, so we're correct even before the next frame
-            mRollo.mState.zoomTarget = amount;
+        if (mRollo == null || !mRollo.mHasSurface) {
+            mZoomDirty = true;
+            mNextZoom = zoom;
+            mNextAnimate = animate;
+            return;
         } else {
-            mRollo.mState.zoomTarget = 0;
+            mRollo.setZoom(zoom, animate);
         }
-        mRollo.mState.save();
     }
 
     public boolean isVisible() {
-        if (mRollo == null) {
-            return false;
+        if (mZoomDirty) {
+            return mNextZoom > 0.001f;
+        } else {
+            if (mRollo == null) {
+                return false;
+            } else {
+                return mRollo.mMessageProc.mZoom > 0.001f;
+            }
         }
-        return mRollo.mMessageProc.mZoom > 0.001f;
+    }
+
+    public boolean isOpaque() {
+        if (mZoomDirty) {
+            return mNextZoom > 0.999f;
+        } else {
+            if (mRollo == null) {
+                return false;
+            } else {
+                return mRollo.mMessageProc.mZoom > 0.999f;
+            }
+        }
     }
 
     /*
@@ -729,7 +744,7 @@
         private Script.Invokable mInvokeMoveTo;
         private Script.Invokable mInvokeFling;
         private Script.Invokable mInvokeResetWAR;
-
+        private Script.Invokable mInvokeSetZoom;
 
         private ProgramStore mPSIcons;
         private ProgramStore mPSText;
@@ -1003,6 +1018,7 @@
             mInvokeFling = sb.addInvokable("fling");
             mInvokeMoveTo = sb.addInvokable("moveTo");
             mInvokeResetWAR = sb.addInvokable("resetHWWar");
+            mInvokeSetZoom = sb.addInvokable("setZoom");
             mScript = sb.create();
             mScript.setClearColor(0.0f, 0.0f, 0.0f, 0.0f);
             mScript.bindAllocation(mParams.mAlloc, Defines.ALLOC_PARAMS);
@@ -1022,10 +1038,16 @@
         }
 
         void dirtyCheck() {
-            if (mAppsDirty && mHasSurface) {
-                uploadApps(mAllAppsList);
-                saveAppsList();
-                mAppsDirty = false;
+            if (mHasSurface) {
+                if (mAppsDirty) {
+                    uploadApps(mAllAppsList);
+                    saveAppsList();
+                    mAppsDirty = false;
+                }
+                if (mZoomDirty) {
+                    setZoom(mNextZoom, mNextAnimate);
+                    mZoomDirty = false;
+                }
             }
         }
 
@@ -1053,6 +1075,20 @@
             saveAppsList();
         }
 
+        private void setZoom(float zoom, boolean animate) {
+            mRollo.clearSelectedIcon();
+            mRollo.setHomeSelected(SELECTED_NONE);
+            if (zoom > 0.001f) {
+                mRollo.mState.zoomTarget = zoom;
+            } else {
+                mRollo.mState.zoomTarget = 0;
+            }
+            mRollo.mState.save();
+            if (!animate) {
+                mRollo.mInvokeSetZoom.execute();
+            }
+        }
+
         private void frameBitmapAllocMips(Allocation alloc, int w, int h) {
             int black[] = new int[w > h ? w : h];
             Allocation.Adapter2D a = alloc.createAdapter2D();
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 6a0978b..ce3d5a7 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -192,7 +192,6 @@
 
     private boolean mRestoring;
     private boolean mWaitingForResult;
-    private boolean mExitingBecauseOfLaunch;
 
     private Bundle mSavedInstanceState;
 
@@ -446,10 +445,6 @@
     @Override
     protected void onPause() {
         super.onPause();
-        if (mExitingBecauseOfLaunch) {
-            mExitingBecauseOfLaunch = false;
-            closeAllApps(false);
-        }
         dismissPreview(mPreviousView);
         dismissPreview(mNextView);
     }
@@ -511,6 +506,11 @@
             return;
         }
 
+        final boolean allApps = savedState.getBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, false);
+        if (allApps) {
+            showAllApps(false);
+        }
+
         final int currentScreen = savedState.getInt(RUNTIME_STATE_CURRENT_SCREEN, -1);
         if (currentScreen > -1) {
             mWorkspace.setCurrentScreen(currentScreen);
@@ -856,23 +856,17 @@
             // for example onResume being called when the user pressed the 'back' button.
             mIsNewIntent = true;
 
-            if ((intent.getFlags() & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) !=
-                    Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) {
+            if (!mWorkspace.isDefaultScreenShowing()) {
+                mWorkspace.moveToDefaultScreen();
+            }
 
-                if (!mWorkspace.isDefaultScreenShowing()) {
-                    mWorkspace.moveToDefaultScreen();
-                }
+            closeAllApps(false);
 
-                closeAllApps(true);
-
-                final View v = getWindow().peekDecorView();
-                if (v != null && v.getWindowToken() != null) {
-                    InputMethodManager imm = (InputMethodManager)getSystemService(
-                            INPUT_METHOD_SERVICE);
-                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
-                }
-            } else {
-                closeAllApps(false);
+            final View v = getWindow().peekDecorView();
+            if (v != null && v.getWindowToken() != null) {
+                InputMethodManager imm = (InputMethodManager)getSystemService(
+                        INPUT_METHOD_SERVICE);
+                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
             }
         }
     }
@@ -902,10 +896,8 @@
 
         final boolean isConfigurationChange = getChangingConfigurations() != 0;
 
-        // When the drawer is opened and we are saving the state because of a
-        // configuration change
         // TODO should not do this if the drawer is currently closing.
-        if (isAllAppsVisible() && isConfigurationChange) {
+        if (isAllAppsVisible()) {
             outState.putBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, true);
         }
 
@@ -1408,7 +1400,6 @@
             // Open shortcut
             final Intent intent = ((ApplicationInfo) tag).intent;
             startActivitySafely(intent);
-            mExitingBecauseOfLaunch = true;
         } else if (tag instanceof FolderInfo) {
             handleFolderClick((FolderInfo) tag);
         } else if (v == mHandleView) {
@@ -1416,7 +1407,7 @@
             if (isAllAppsVisible()) {
                 closeAllApps(true);
             } else {
-                showAllApps();
+                showAllApps(true);
             }
         }
     }
@@ -1819,10 +1810,16 @@
         return mAllAppsGrid.isVisible();
     }
 
-    void showAllApps() {
-        mAllAppsGrid.zoom(1.0f);
+    boolean isAllAppsOpaque() {
+        return mAllAppsGrid.isOpaque();
+    }
+
+    void showAllApps(boolean animated) {
+        mAllAppsGrid.zoom(1.0f, animated);
         //mWorkspace.hide();
 
+        mWorkspace.startFading(false);
+
         mAllAppsGrid.setFocusable(true);
         mAllAppsGrid.requestFocus();
         
@@ -1833,10 +1830,10 @@
 
     void closeAllApps(boolean animated) {
         if (mAllAppsGrid.isVisible()) {
-            mAllAppsGrid.zoom(0.0f);
+            mAllAppsGrid.zoom(0.0f, animated);
             mAllAppsGrid.setFocusable(false);
             mWorkspace.getChildAt(mWorkspace.getCurrentScreen()).requestFocus();
-
+            mWorkspace.startFading(true);
 
             // TODO: fade these two too
             /*
@@ -2138,11 +2135,6 @@
                 }
             }
 
-            final boolean allApps = mSavedState.getBoolean(RUNTIME_STATE_ALL_APPS_FOLDER, false);
-            if (allApps) {
-                showAllApps();
-            }
-
             mSavedState = null;
         }
 
diff --git a/src/com/android/launcher2/Workspace.java b/src/com/android/launcher2/Workspace.java
index aa11e93..3b038cb 100644
--- a/src/com/android/launcher2/Workspace.java
+++ b/src/com/android/launcher2/Workspace.java
@@ -48,7 +48,7 @@
  * A workspace is meant to be used with a fixed width only.
  */
 public class Workspace extends ViewGroup implements DropTarget, DragSource, DragScroller {
-    //private static final String TAG = "Launcher.Workspace";
+    private static final String TAG = "Launcher.Workspace";
     private static final int INVALID_SCREEN = -1;
     
     /**
@@ -111,6 +111,8 @@
     private Drawable mPreviousIndicator;
     private Drawable mNextIndicator;
 
+    private boolean mFading = true;
+
     /**
      * Used to inflate the Workspace from XML.
      *
@@ -474,8 +476,25 @@
         }
     }
 
+    public void startFading(boolean dest) {
+        mFading = dest;
+        invalidate();
+    }
+
     @Override
     protected void dispatchDraw(Canvas canvas) {
+        final boolean allAppsOpaque = mLauncher.isAllAppsOpaque();
+        if (mFading == allAppsOpaque) {
+            invalidate();
+        } else {
+            mFading = !allAppsOpaque;
+        }
+        if (allAppsOpaque) {
+            // If the launcher is up, draw black.
+            canvas.drawARGB(0xff, 0, 0, 0);
+            return;
+        }
+
         if (Launcher.lastStartTime != 0) {
             int itemCount = 0;
             for (int i=0; i<getChildCount(); i++) {
@@ -790,6 +809,34 @@
         return mTouchState != TOUCH_STATE_REST;
     }
 
+    /**
+     * If one of our descendant views decides that it could be focused now, only
+     * pass that along if it's on the current screen.
+     *
+     * This happens when live folders requery, and if they're off screen, they
+     * end up calling requestFocus, which pulls it on screen.
+     */
+    @Override
+    public void focusableViewAvailable(View focused) {
+        View current = getChildAt(mCurrentScreen);
+        View v = focused;
+        while (true) {
+            if (v == current) {
+                super.focusableViewAvailable(focused);
+                return;
+            }
+            if (v == this) {
+                return;
+            }
+            ViewParent parent = v.getParent();
+            if (parent instanceof View) {
+                v = (View)v.getParent();
+            } else {
+                return;
+            }
+        }
+    }
+
     void enableChildrenCache(int fromScreen, int toScreen) {
         if (fromScreen > toScreen) {
             fromScreen = toScreen;