Fix bug where quickly ending folder animation with back swipe caused icons not clipped to folder

1. Fix a race condition that the new animation is reading stale UI state which should have been reset in previous animation.
2. Don't set clipChildren=true on folder page view during open folder animation

Fix: 282158620
Test: open folder and quickly back swipe, verify app icons are still clipped
Change-Id: I5f0877fe4157533563df922ba50a6ad540c9ba6e
diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java
index 05ad57a..2ce6c78 100644
--- a/src/com/android/launcher3/folder/FolderAnimationManager.java
+++ b/src/com/android/launcher3/folder/FolderAnimationManager.java
@@ -265,23 +265,37 @@
         Animator z = getAnimator(mFolder, View.TRANSLATION_Z, -mFolder.getElevation(), 0);
         play(a, z, mIsOpening ? midDuration : 0, midDuration);
 
-        // Store clip variables
-        CellLayout cellLayout = mContent.getCurrentCellLayout();
-        boolean folderClipChildren = mFolder.getClipChildren();
-        boolean folderClipToPadding = mFolder.getClipToPadding();
-        boolean contentClipChildren = mContent.getClipChildren();
-        boolean contentClipToPadding = mContent.getClipToPadding();
-        boolean cellLayoutClipChildren = cellLayout.getClipChildren();
-        boolean cellLayoutClipPadding = cellLayout.getClipToPadding();
-
-        mFolder.setClipChildren(false);
-        mFolder.setClipToPadding(false);
-        mContent.setClipChildren(false);
-        mContent.setClipToPadding(false);
-        cellLayout.setClipChildren(false);
-        cellLayout.setClipToPadding(false);
-
+        // Store clip variables.
+        // Because {@link #onAnimationStart} and {@link #onAnimationEnd} callbacks are sent to
+        // message queue and executed on separate frame, we should save states in
+        // {@link #onAnimationStart} instead of before creating animator, so that cancelling
+        // animation A and restarting animation B allows A to reset states in
+        // {@link #onAnimationEnd} before B reads new UI state from {@link #onAnimationStart}.
         a.addListener(new AnimatorListenerAdapter() {
+            private CellLayout mCellLayout;
+            private boolean mFolderClipToPadding;
+            private boolean mContentClipChildren;
+            private boolean mContentClipToPadding;
+            private boolean mCellLayoutClipChildren;
+            private boolean mCellLayoutClipPadding;
+
+            @Override
+            public void onAnimationStart(Animator animator) {
+                super.onAnimationStart(animator);
+                mCellLayout = mContent.getCurrentCellLayout();
+                mFolderClipToPadding = mFolder.getClipToPadding();
+                mContentClipChildren = mContent.getClipChildren();
+                mContentClipToPadding = mContent.getClipToPadding();
+                mCellLayoutClipChildren = mCellLayout.getClipChildren();
+                mCellLayoutClipPadding = mCellLayout.getClipToPadding();
+
+                mFolder.setClipToPadding(false);
+                mContent.setClipChildren(false);
+                mContent.setClipToPadding(false);
+                mCellLayout.setClipChildren(false);
+                mCellLayout.setClipToPadding(false);
+            }
+
             @Override
             public void onAnimationEnd(Animator animation) {
                 super.onAnimationEnd(animation);
@@ -295,13 +309,11 @@
                 mFolder.mFooter.setTranslationX(0f);
                 mFolder.mFolderName.setAlpha(1f);
 
-                mFolder.setClipChildren(folderClipChildren);
-                mFolder.setClipToPadding(folderClipToPadding);
-                mContent.setClipChildren(contentClipChildren);
-                mContent.setClipToPadding(contentClipToPadding);
-                cellLayout.setClipChildren(cellLayoutClipChildren);
-                cellLayout.setClipToPadding(cellLayoutClipPadding);
-
+                mFolder.setClipToPadding(mFolderClipToPadding);
+                mContent.setClipChildren(mContentClipChildren);
+                mContent.setClipToPadding(mContentClipToPadding);
+                mCellLayout.setClipChildren(mCellLayoutClipChildren);
+                mCellLayout.setClipToPadding(mCellLayoutClipPadding);
             }
         });