Merge "Fixing regression in transition after returning to home from another app. (Bug 6629707)" into jb-dev
diff --git a/src/com/android/launcher2/Folder.java b/src/com/android/launcher2/Folder.java
index db65a31..1163f9e 100644
--- a/src/com/android/launcher2/Folder.java
+++ b/src/com/android/launcher2/Folder.java
@@ -100,6 +100,8 @@
     private boolean mSuppressFolderDeletion = false;
     private boolean mItemAddedBackToSelfViaIcon = false;
     FolderEditText mFolderName;
+    private float mFolderIconPivotX;
+    private float mFolderIconPivotY;
 
     private boolean mIsEditingName = false;
     private InputMethodManager mInputMethodManager;
@@ -839,20 +841,24 @@
         int folderPivotY = height / 2 + (centeredTop - top);
         setPivotX(folderPivotX);
         setPivotY(folderPivotY);
-        int folderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() *
+        mFolderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() *
                 (1.0f * folderPivotX / width));
-        int folderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() *
+        mFolderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() *
                 (1.0f * folderPivotY / height));
 
-        mFolderIcon.setPivotX(folderIconPivotX);
-        mFolderIcon.setPivotY(folderIconPivotY);
-
         lp.width = width;
         lp.height = height;
         lp.x = left;
         lp.y = top;
     }
 
+    float getPivotXForIconAnimation() {
+        return mFolderIconPivotX;
+    }
+    float getPivotYForIconAnimation() {
+        return mFolderIconPivotY;
+    }
+
     private void setupContentForNumItems(int count) {
         setupContentDimensions(count);
 
diff --git a/src/com/android/launcher2/FolderIcon.java b/src/com/android/launcher2/FolderIcon.java
index d643084..4919b57 100644
--- a/src/com/android/launcher2/FolderIcon.java
+++ b/src/com/android/launcher2/FolderIcon.java
@@ -321,12 +321,7 @@
         // This will animate the first item from it's position as an icon into its
         // position as the first item in the preview
         animateFirstItem(animateDrawable, INITIAL_ITEM_ANIMATION_DURATION);
-
-        postDelayed(new Runnable() {
-            public void run() {
-                addItem(destInfo);
-            }
-        }, INITIAL_ITEM_ANIMATION_DURATION);
+        addItem(destInfo);
     }
 
     public void onDragExit(Object dragInfo) {
diff --git a/src/com/android/launcher2/HolographicLinearLayout.java b/src/com/android/launcher2/HolographicLinearLayout.java
index a40c727..0f997d5 100644
--- a/src/com/android/launcher2/HolographicLinearLayout.java
+++ b/src/com/android/launcher2/HolographicLinearLayout.java
@@ -68,6 +68,7 @@
 
     void invalidatePressedFocusedStates() {
         mHolographicHelper.invalidatePressedFocusedStates(mImageView);
+        invalidate();
     }
 
     @Override
diff --git a/src/com/android/launcher2/Launcher.java b/src/com/android/launcher2/Launcher.java
index 3e471bf..28dfd65 100644
--- a/src/com/android/launcher2/Launcher.java
+++ b/src/com/android/launcher2/Launcher.java
@@ -48,6 +48,9 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.ContentObserver;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
@@ -278,6 +281,10 @@
     // when we scroll to that page on resume.
     private int mNewShortcutAnimatePage = -1;
     private ArrayList<View> mNewShortcutAnimateViews = new ArrayList<View>();
+    private ImageView mFolderIconImageView;
+    private Bitmap mFolderIconBitmap;
+    private Canvas mFolderIconCanvas;
+    private Rect mRectForFolderAnimation = new Rect();
 
     private BubbleTextView mWaitingForResume;
 
@@ -1869,8 +1876,7 @@
                     (SearchManager) getSystemService(Context.SEARCH_SERVICE);
             ComponentName activityName = searchManager.getGlobalSearchActivity();
             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             if (activityName != null) {
                 intent.setPackage(activityName.getPackageName());
             }
@@ -1878,8 +1884,7 @@
             overridePendingTransition(R.anim.fade_in_fast, R.anim.fade_out_fast);
         } catch (ActivityNotFoundException e) {
             Intent intent = new Intent(RecognizerIntent.ACTION_WEB_SEARCH);
-            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
-                    | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
             startActivitySafely(null, intent, "onClickVoiceButton");
         }
     }
@@ -2017,6 +2022,56 @@
         }
     }
 
+    /**
+     * This method draws the FolderIcon to an ImageView and then adds and positions that ImageView
+     * in the DragLayer in the exact absolute location of the original FolderIcon.
+     */
+    private void copyFolderIconToImage(FolderIcon fi) {
+        final int width = fi.getMeasuredWidth();
+        final int height = fi.getMeasuredHeight();
+
+        // Lazy load ImageView, Bitmap and Canvas
+        if (mFolderIconImageView == null) {
+            mFolderIconImageView = new ImageView(this);
+        }
+        if (mFolderIconBitmap == null || mFolderIconBitmap.getWidth() != width ||
+                mFolderIconBitmap.getHeight() != height) {
+            mFolderIconBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+            mFolderIconCanvas = new Canvas(mFolderIconBitmap);
+        }
+
+        DragLayer.LayoutParams lp;
+        if (mFolderIconImageView.getLayoutParams() instanceof DragLayer.LayoutParams) {
+            lp = (DragLayer.LayoutParams) mFolderIconImageView.getLayoutParams();
+        } else {
+            lp = new DragLayer.LayoutParams(width, height);
+        }
+
+        mDragLayer.getViewRectRelativeToSelf(fi, mRectForFolderAnimation);
+        lp.customPosition = true;
+        lp.x = mRectForFolderAnimation.left;
+        lp.y = mRectForFolderAnimation.top;
+        lp.width = width;
+        lp.height = height;
+
+        mFolderIconCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
+        fi.draw(mFolderIconCanvas);
+        mFolderIconImageView.setImageBitmap(mFolderIconBitmap);
+        if (fi.mFolder != null) {
+            mFolderIconImageView.setPivotX(fi.mFolder.getPivotXForIconAnimation());
+            mFolderIconImageView.setPivotY(fi.mFolder.getPivotYForIconAnimation());
+        }
+        // Just in case this image view is still in the drag layer from a previous animation,
+        // we remove it and re-add it.
+        if (mDragLayer.indexOfChild(mFolderIconImageView) != -1) {
+            mDragLayer.removeView(mFolderIconImageView);
+        }
+        mDragLayer.addView(mFolderIconImageView, lp);
+        if (fi.mFolder != null) {
+            fi.mFolder.bringToFront();
+        }
+    }
+
     private void growAndFadeOutFolderIcon(FolderIcon fi) {
         if (fi == null) return;
         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 0);
@@ -2030,31 +2085,38 @@
             cl.setFolderLeaveBehindCell(lp.cellX, lp.cellY);
         }
 
-        ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(fi, alpha, scaleX, scaleY);
+        // Push an ImageView copy of the FolderIcon into the DragLayer and hide the original
+        copyFolderIconToImage(fi);
+        fi.setVisibility(View.INVISIBLE);
+
+        ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(mFolderIconImageView, alpha,
+                scaleX, scaleY);
         oa.setDuration(getResources().getInteger(R.integer.config_folderAnimDuration));
         oa.start();
     }
 
-    private void shrinkAndFadeInFolderIcon(FolderIcon fi) {
+    private void shrinkAndFadeInFolderIcon(final FolderIcon fi) {
         if (fi == null) return;
         PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1.0f);
         PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
         PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
 
-        FolderInfo info = (FolderInfo) fi.getTag();
-        CellLayout cl = null;
-        if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) {
-            cl = (CellLayout) fi.getParent().getParent();
-        }
+        final CellLayout cl = (CellLayout) fi.getParent().getParent();
 
-        final CellLayout layout = cl;
-        ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(fi, alpha, scaleX, scaleY);
+        // We remove and re-draw the FolderIcon in-case it has changed
+        mDragLayer.removeView(mFolderIconImageView);
+        copyFolderIconToImage(fi);
+        ObjectAnimator oa = ObjectAnimator.ofPropertyValuesHolder(mFolderIconImageView, alpha,
+                scaleX, scaleY);
         oa.setDuration(getResources().getInteger(R.integer.config_folderAnimDuration));
         oa.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator animation) {
-                if (layout != null) {
-                    layout.clearFolderLeaveBehind();
+                if (cl != null) {
+                    cl.clearFolderLeaveBehind();
+                    // Remove the ImageView copy of the FolderIcon and make the original visible.
+                    mDragLayer.removeView(mFolderIconImageView);
+                    fi.setVisibility(View.VISIBLE);
                 }
             }
         });
@@ -2072,7 +2134,6 @@
         Folder folder = folderIcon.mFolder;
         FolderInfo info = folder.mInfo;
 
-        growAndFadeOutFolderIcon(folderIcon);
         info.opened = true;
 
         // Just verify that the folder hasn't already been added to the DragLayer.
@@ -2085,6 +2146,7 @@
                     folder.getParent() + ").");
         }
         folder.animateOpen();
+        growAndFadeOutFolderIcon(folderIcon);
     }
 
     public void closeFolder() {