Removing custom dispatchDraw logic and letting the system handle
selecting appropriate children for drawing.

> System already skips children which are outside the bounds. Originally
this logic was added because workspace layout is larger than the screen, and
we need to selectivly skip more children. But over time we have added many
special conditions and at present workspace actually draws more children than
needed at any given time.
> Fixing bug, where onBeginPageMoving was getting called during folder open

Bug: 12116740
Change-Id: Idee18ee9cd9d348ebc4dfd82f4ff6df14e0d22d2
diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java
index ce6ce68..0abac36 100644
--- a/src/com/android/launcher3/PagedView.java
+++ b/src/com/android/launcher3/PagedView.java
@@ -28,7 +28,6 @@
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.Rect;
-import android.graphics.RectF;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Parcel;
@@ -118,7 +117,6 @@
     private float mLastMotionXRemainder;
     private float mLastMotionY;
     private float mTotalMotionX;
-    private int mLastScreenCenter = -1;
 
     private boolean mCancelTap;
 
@@ -131,7 +129,6 @@
     protected final static int TOUCH_STATE_REORDERING = 4;
 
     protected int mTouchState = TOUCH_STATE_REST;
-    private boolean mForceScreenScrolled = false;
 
     protected OnLongClickListener mLongClickListener;
 
@@ -144,7 +141,7 @@
 
     protected int mActivePointerId = INVALID_POINTER;
 
-    protected boolean mIsPageMoving = false;
+    protected boolean mIsPageInTransition = false;
 
     protected boolean mWasInOverscroll = false;
 
@@ -183,7 +180,6 @@
     private static final float[] sTmpPoint = new float[2];
     private static final int[] sTmpIntPoint = new int[2];
     private static final Rect sTmpRect = new Rect();
-    private static final RectF sTmpRectF = new RectF();
 
     protected final Rect mInsets = new Rect();
     protected final boolean mIsRtl;
@@ -409,7 +405,6 @@
         if (getChildCount() == 0) {
             return;
         }
-        mForceScreenScrolled = true;
         mCurrentPage = validateNewPage(currentPage);
         updateCurrentPageScroll();
         notifyPageSwitchListener();
@@ -433,30 +428,36 @@
             }
         }
     }
-    protected void pageBeginMoving() {
-        if (!mIsPageMoving) {
-            mIsPageMoving = true;
-            onPageBeginMoving();
+    protected void pageBeginTransition() {
+        if (!mIsPageInTransition) {
+            mIsPageInTransition = true;
+            onPageBeginTransition();
         }
     }
 
-    protected void pageEndMoving() {
-        if (mIsPageMoving) {
-            mIsPageMoving = false;
-            onPageEndMoving();
+    protected void pageEndTransition() {
+        if (mIsPageInTransition) {
+            mIsPageInTransition = false;
+            onPageEndTransition();
         }
     }
 
-    protected boolean isPageMoving() {
-        return mIsPageMoving;
+    protected boolean isPageInTransition() {
+        return mIsPageInTransition;
     }
 
-    // a method that subclasses can override to add behavior
-    protected void onPageBeginMoving() {
+    /**
+     * Called when the page starts moving as part of the scroll. Subclasses can override this
+     * to provide custom behavior during animation.
+     */
+    protected void onPageBeginTransition() {
     }
 
-    // a method that subclasses can override to add behavior
-    protected void onPageEndMoving() {
+    /**
+     * Called when the page ends moving as part of the scroll. Subclasses can override this
+     * to provide custom behavior during animation.
+     */
+    protected void onPageEndTransition() {
         mWasInOverscroll = false;
     }
 
@@ -584,7 +585,7 @@
             // We don't want to trigger a page end moving unless the page has settled
             // and the user has stopped scrolling
             if (mTouchState == TOUCH_STATE_REST) {
-                pageEndMoving();
+                pageEndTransition();
             }
 
             onPostReorderingAnimationCompleted();
@@ -899,11 +900,6 @@
         requestLayout();
     }
 
-    /**
-     * Called when the center screen changes during scrolling.
-     */
-    protected void screenScrolled(int screenCenter) { }
-
     @Override
     public void onChildViewAdded(View parent, View child) {
         // Update the page indicator, we don't update the page indicator as we
@@ -914,14 +910,12 @@
 
         // This ensures that when children are added, they get the correct transforms / alphas
         // in accordance with any scroll effects.
-        mForceScreenScrolled = true;
         updateFreescrollBounds();
         invalidate();
     }
 
     @Override
     public void onChildViewRemoved(View parent, View child) {
-        mForceScreenScrolled = true;
         updateFreescrollBounds();
         invalidate();
     }
@@ -979,99 +973,6 @@
         range[1] = Math.max(0, getChildCount() - 1);
     }
 
-    protected void getVisiblePages(int[] range) {
-        final int count = getChildCount();
-        range[0] = -1;
-        range[1] = -1;
-
-        if (count > 0) {
-            final int visibleLeft = -getLeft();
-            final int visibleRight = visibleLeft + getViewportWidth();
-            final Matrix pageShiftMatrix = getPageShiftMatrix();
-            int curScreen = 0;
-
-            for (int i = 0; i < count; i++) {
-                View currPage = getPageAt(i);
-
-                // Verify if the page bounds are within the visible range.
-                sTmpRectF.left = 0;
-                sTmpRectF.right = currPage.getMeasuredWidth();
-                currPage.getMatrix().mapRect(sTmpRectF);
-                sTmpRectF.offset(currPage.getLeft() - getScrollX(), 0);
-                pageShiftMatrix.mapRect(sTmpRectF);
-
-                if (sTmpRectF.left > visibleRight || sTmpRectF.right < visibleLeft) {
-                    if (range[0] == -1) {
-                        continue;
-                    } else {
-                        break;
-                    }
-                }
-                curScreen = i;
-                if (range[0] < 0) {
-                    range[0] = curScreen;
-                }
-            }
-
-            range[1] = curScreen;
-        } else {
-            range[0] = -1;
-            range[1] = -1;
-        }
-    }
-
-    protected Matrix getPageShiftMatrix() {
-        return getMatrix();
-    }
-
-    protected boolean shouldDrawChild(View child) {
-        return child.getVisibility() == VISIBLE;
-    }
-
-    @Override
-    protected void dispatchDraw(Canvas canvas) {
-        // Find out which screens are visible; as an optimization we only call draw on them
-        final int pageCount = getChildCount();
-        if (pageCount > 0) {
-            int halfScreenSize = getViewportWidth() / 2;
-            int screenCenter = getScrollX() + halfScreenSize;
-
-            if (screenCenter != mLastScreenCenter || mForceScreenScrolled) {
-                // set mForceScreenScrolled before calling screenScrolled so that screenScrolled can
-                // set it for the next frame
-                mForceScreenScrolled = false;
-                screenScrolled(screenCenter);
-                mLastScreenCenter = screenCenter;
-            }
-
-            getVisiblePages(mTempVisiblePagesRange);
-            final int leftScreen = mTempVisiblePagesRange[0];
-            final int rightScreen = mTempVisiblePagesRange[1];
-            if (leftScreen != -1 && rightScreen != -1) {
-                final long drawingTime = getDrawingTime();
-                // Clip to the bounds
-                canvas.save();
-                canvas.clipRect(getScrollX(), getScrollY(), getScrollX() + getRight() - getLeft(),
-                        getScrollY() + getBottom() - getTop());
-
-                // Draw all the children, leaving the drag view for last
-                for (int i = pageCount - 1; i >= 0; i--) {
-                    final View v = getPageAt(i);
-                    if (v == mDragView) continue;
-                    if (leftScreen <= i && i <= rightScreen && shouldDrawChild(v)) {
-                        drawChild(canvas, v, drawingTime);
-                    }
-                }
-                // Draw the drag view on top (if there is one)
-                if (mDragView != null) {
-                    drawChild(canvas, mDragView, drawingTime);
-                }
-
-                canvas.restore();
-            }
-        }
-    }
-
     @Override
     public void draw(Canvas canvas) {
         super.draw(canvas);
@@ -1321,7 +1222,7 @@
                     mTouchState = TOUCH_STATE_REST;
                     if (!mScroller.isFinished() && !mFreeScroll) {
                         setCurrentPage(getNextPage());
-                        pageEndMoving();
+                        pageEndTransition();
                     }
                 } else {
                     if (isTouchPointInViewportWithBuffer((int) mDownMotionX, (int) mDownMotionY)) {
@@ -1382,7 +1283,7 @@
             mLastMotionX = x;
             mLastMotionXRemainder = 0;
             onScrollInteractionBegin();
-            pageBeginMoving();
+            pageBeginTransition();
             // Stop listening for things like pinches.
             requestDisallowInterceptTouchEvent(true);
         }
@@ -1564,7 +1465,7 @@
 
             if (mTouchState == TOUCH_STATE_SCROLLING) {
                 onScrollInteractionBegin();
-                pageBeginMoving();
+                pageBeginTransition();
             }
             break;
 
@@ -2010,7 +1911,6 @@
 
         mNextPage = whichPage;
 
-        pageBeginMoving();
         awakenScrollBars(duration);
         if (immediate) {
             duration = 0;
@@ -2018,6 +1918,10 @@
             duration = Math.abs(delta);
         }
 
+        if (duration != 0) {
+            pageBeginTransition();
+        }
+
         if (!mScroller.isFinished()) {
             abortScrollerAnimation(false);
         }
@@ -2037,7 +1941,6 @@
             computeScroll();
         }
 
-        mForceScreenScrolled = true;
         invalidate();
     }
 
diff --git a/src/com/android/launcher3/PinchAnimationManager.java b/src/com/android/launcher3/PinchAnimationManager.java
index 84ef12e..3cc0f7d 100644
--- a/src/com/android/launcher3/PinchAnimationManager.java
+++ b/src/com/android/launcher3/PinchAnimationManager.java
@@ -60,7 +60,6 @@
 
     private final Animator[] mAnimators = new Animator[4];
 
-    private final int[] mVisiblePageRange = new int[2];
     private Launcher mLauncher;
     private Workspace mWorkspace;
 
@@ -181,17 +180,13 @@
     }
 
     private void setOverviewPanelsAlpha(float alpha, int duration) {
-        mWorkspace.getVisiblePages(mVisiblePageRange);
-        for (int i = mVisiblePageRange[0]; i <= mVisiblePageRange[1]; i++) {
-            View page = mWorkspace.getPageAt(i);
-            if (!mWorkspace.shouldDrawChild(page)) {
-                continue;
-            }
+        int childCount = mWorkspace.getChildCount();
+        for (int i = 0; i < childCount; i++) {
+            final CellLayout cl = (CellLayout) mWorkspace.getChildAt(i);
             if (duration == 0) {
-                ((CellLayout) page).setBackgroundAlpha(alpha);
+                cl.setBackgroundAlpha(alpha);
             } else {
-                ObjectAnimator.ofFloat(page, "backgroundAlpha", alpha)
-                        .setDuration(duration).start();
+                ObjectAnimator.ofFloat(cl, "backgroundAlpha", alpha).setDuration(duration).start();
             }
         }
     }
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index f9bda75..3b9d690 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -32,7 +32,6 @@
 import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
-import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
@@ -171,11 +170,10 @@
     // These are temporary variables to prevent having to allocate a new object just to
     // return an (x, y) value from helper functions. Do NOT use them to maintain other state.
     private static final Rect sTempRect = new Rect();
+
     private final int[] mTempXY = new int[2];
     @Thunk float[] mDragViewVisualCenter = new float[2];
     private float[] mTempCellLayoutCenterCoordinates = new float[2];
-    private int[] mTempVisiblePagesRange = new int[2];
-    private Matrix mTempMatrix = new Matrix();
 
     private SpringLoadedDragController mSpringLoadedDragController;
     private float mOverviewModeShrinkFactor;
@@ -552,14 +550,6 @@
         super.onChildViewAdded(parent, child);
     }
 
-    protected boolean shouldDrawChild(View child) {
-        final CellLayout cl = (CellLayout) child;
-        return super.shouldDrawChild(child) &&
-            (mIsSwitchingState ||
-             cl.getShortcutsAndWidgets().getAlpha() > 0 ||
-             cl.getBackgroundAlpha() > 0);
-    }
-
     boolean isTouchActive() {
         return mTouchState != TOUCH_STATE_REST;
     }
@@ -993,7 +983,7 @@
             return;
         }
 
-        if (isPageMoving()) {
+        if (isPageInTransition()) {
             mStripScreensOnPageStopMoving = true;
             return;
         }
@@ -1309,13 +1299,13 @@
         }
     }
 
-    protected void onPageBeginMoving() {
-        super.onPageBeginMoving();
+    protected void onPageBeginTransition() {
+        super.onPageBeginTransition();
         updateChildrenLayersEnabled(false);
     }
 
-    protected void onPageEndMoving() {
-        super.onPageEndMoving();
+    protected void onPageEndTransition() {
+        super.onPageEndTransition();
         updateChildrenLayersEnabled(false);
 
         if (mDragController.isDragging()) {
@@ -1418,6 +1408,10 @@
         if (!isTransitioning) {
             showPageIndicatorAtCurrentScroll();
         }
+
+        updatePageAlphaValues();
+        updateStateForCustomContent();
+        enableHwLayersOnVisiblePages();
     }
 
     private void showPageIndicatorAtCurrentScroll() {
@@ -1576,18 +1570,6 @@
     }
 
     @Override
-    protected Matrix getPageShiftMatrix() {
-        if (Float.compare(mOverlayTranslation, 0) != 0) {
-            // The pages are translated by mOverlayTranslation. incorporate that in the
-            // visible page calculation by shifting everything back by that same amount.
-            mTempMatrix.set(getMatrix());
-            mTempMatrix.postTranslate(-mOverlayTranslation, 0);
-            return mTempMatrix;
-        }
-        return super.getPageShiftMatrix();
-    }
-
-    @Override
     protected void getEdgeVerticalPosition(int[] pos) {
         View child = getChildAt(getPageCount() - 1);
         pos[0] = child.getTop();
@@ -1687,15 +1669,16 @@
     }
 
     public void showOutlinesTemporarily() {
-        if (!mIsPageMoving && !isTouchActive()) {
+        if (!mIsPageInTransition && !isTouchActive()) {
             snapToPage(mCurrentPage);
         }
     }
 
-    private void updatePageAlphaValues(int screenCenter) {
+    private void updatePageAlphaValues() {
         if (mWorkspaceFadeInAdjacentScreens &&
                 !workspaceInModalState() &&
                 !mIsSwitchingState) {
+            int screenCenter = getScrollX() + getViewportOffsetX() + getViewportWidth() / 2;
             for (int i = numCustomPages(); i < getChildCount(); i++) {
                 CellLayout child = (CellLayout) getChildAt(i);
                 if (child != null) {
@@ -1723,7 +1706,7 @@
         return hasCustomContent() && getNextPage() == 0;
     }
 
-    private void updateStateForCustomContent(int screenCenter) {
+    private void updateStateForCustomContent() {
         float translationX = 0;
         float progress = 0;
         if (hasCustomContent()) {
@@ -1771,13 +1754,6 @@
         }
     }
 
-    @Override
-    protected void screenScrolled(int screenCenter) {
-        updatePageAlphaValues(screenCenter);
-        updateStateForCustomContent(screenCenter);
-        enableHwLayersOnVisiblePages();
-    }
-
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         IBinder windowToken = getWindowToken();
@@ -1856,7 +1832,7 @@
 
     @Thunk void updateChildrenLayersEnabled(boolean force) {
         boolean small = mState == State.OVERVIEW || mIsSwitchingState;
-        boolean enableChildrenLayers = force || small || mAnimatingViewIntoPlace || isPageMoving();
+        boolean enableChildrenLayers = force || small || mAnimatingViewIntoPlace || isPageInTransition();
 
         if (enableChildrenLayers != mChildrenLayersEnabled) {
             mChildrenLayersEnabled = enableChildrenLayers;
@@ -1874,9 +1850,37 @@
     private void enableHwLayersOnVisiblePages() {
         if (mChildrenLayersEnabled) {
             final int screenCount = getChildCount();
-            getVisiblePages(mTempVisiblePagesRange);
-            int leftScreen = mTempVisiblePagesRange[0];
-            int rightScreen = mTempVisiblePagesRange[1];
+
+            float visibleLeft = getViewportOffsetX();
+            float visibleRight = visibleLeft + getViewportWidth();
+            float scaleX = getScaleX();
+            if (scaleX < 1 && scaleX > 0) {
+                float mid = getMeasuredWidth() / 2;
+                visibleLeft = mid - ((mid - visibleLeft) / scaleX);
+                visibleRight = mid + ((visibleRight - mid) / scaleX);
+            }
+
+            int leftScreen = -1;
+            int rightScreen = -1;
+            for (int i = numCustomPages(); i < screenCount; i++) {
+                final View child = getPageAt(i);
+
+                float left = child.getLeft() + child.getTranslationX() - getScrollX();
+                if (left <= visibleRight && (left + child.getMeasuredWidth()) >= visibleLeft) {
+                    if (leftScreen == -1) {
+                        leftScreen = i;
+                    }
+                    rightScreen = i;
+                }
+            }
+            if (mForceDrawAdjacentPages) {
+                // In overview mode, make sure that the two side pages are visible.
+                leftScreen = Utilities.boundToRange(getCurrentPage() - 1,
+                    numCustomPages(), rightScreen);
+                rightScreen = Utilities.boundToRange(getCurrentPage() + 1,
+                    leftScreen, getPageCount() - 1);
+            }
+
             if (leftScreen == rightScreen) {
                 // make sure we're caching at least two pages always
                 if (rightScreen < screenCount - 1) {
@@ -1886,14 +1890,10 @@
                 }
             }
 
-            final CellLayout customScreen = mWorkspaceScreens.get(CUSTOM_CONTENT_SCREEN_ID);
-            for (int i = 0; i < screenCount; i++) {
+            for (int i = numCustomPages(); i < screenCount; i++) {
                 final CellLayout layout = (CellLayout) getPageAt(i);
-
-                // enable layers between left and right screen inclusive, except for the
-                // customScreen, which may animate its content during transitions.
-                boolean enableLayer = layout != customScreen &&
-                        leftScreen <= i && i <= rightScreen && shouldDrawChild(layout);
+                // enable layers between left and right screen inclusive.
+                boolean enableLayer = leftScreen <= i && i <= rightScreen;
                 layout.enableHardwareLayer(enableLayer);
             }
         }
@@ -1912,16 +1912,6 @@
         updateChildrenLayersEnabled(false);
     }
 
-    @Override
-    protected void getVisiblePages(int[] range) {
-        super.getVisiblePages(range);
-        if (mForceDrawAdjacentPages) {
-            // In overview mode, make sure that the two side pages are visible.
-            range[0] = Utilities.boundToRange(getCurrentPage() - 1, numCustomPages(), range[1]);
-            range[1] = Utilities.boundToRange(getCurrentPage() + 1, range[0], getPageCount() - 1);
-        }
-    }
-
     protected void onWallpaperTap(MotionEvent ev) {
         final int[] position = mTempXY;
         getLocationOnScreen(position);
@@ -2637,7 +2627,7 @@
                                 && !d.accessibleDrag) {
                             mDelayedResizeRunnable = new Runnable() {
                                 public void run() {
-                                    if (!isPageMoving() && !mIsSwitchingState) {
+                                    if (!isPageInTransition() && !mIsSwitchingState) {
                                         DragLayer dragLayer = mLauncher.getDragLayer();
                                         dragLayer.addResizeFrame(hostView, cellLayout);
                                     }
@@ -2764,7 +2754,7 @@
         // Here we store the final page that will be dropped to, if the workspace in fact
         // receives the drop
         if (mInScrollArea) {
-            if (isPageMoving()) {
+            if (isPageInTransition()) {
                 // If the user drops while the page is scrolling, we should use that page as the
                 // destination instead of the page that is being hovered over.
                 mDropToLayout = (CellLayout) getPageAt(getNextPage());
diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java
index dcd3ec4..31ec709 100644
--- a/src/com/android/launcher3/folder/FolderPagedView.java
+++ b/src/com/android/launcher3/folder/FolderPagedView.java
@@ -524,12 +524,11 @@
     }
 
     @Override
-    protected void onPageBeginMoving() {
-        super.onPageBeginMoving();
-        getVisiblePages(sTempPosArray);
-        for (int i = sTempPosArray[0]; i <= sTempPosArray[1]; i++) {
-            verifyVisibleHighResIcons(i);
-        }
+    protected void onPageBeginTransition() {
+        super.onPageBeginTransition();
+        // Ensure that adjacent pages have high resolution icons
+        verifyVisibleHighResIcons(getCurrentPage() - 1);
+        verifyVisibleHighResIcons(getCurrentPage() + 1);
     }
 
     /**