From 4e7a1208eaa81f684485ee23ba681dab6419973f Mon Sep 17 00:00:00 2001 From: Abodunrinwa Toki Date: Tue, 3 May 2016 18:23:12 +0100 Subject: [PATCH] Implement alternative ViewGroup.getChildVisibleRect. This CL allows getChildVisibleRect to optionally always call the view's parent. The previous version attempted to optimize the call by not calling further up the view heirarchy when the rect isn't visible in the current view. The call is hidden and the previous behaviour is preserved to limit the bits of code that this change affects. Bug: 28514727 Change-Id: I49550ed4082bcbdcfe4643b962b50f3308092525 --- core/java/android/view/ViewGroup.java | 16 +++++++++++++--- .../internal/view/FloatingActionMode.java | 3 ++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 3f7bbdf24e97e..6cf8cd16f1876 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -5473,6 +5473,14 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @Override public boolean getChildVisibleRect(View child, Rect r, android.graphics.Point offset) { + return getChildVisibleRect(child, r, offset, false); + } + + /** + * @hide + */ + public boolean getChildVisibleRect( + View child, Rect r, android.graphics.Point offset, boolean forceParentCheck) { // It doesn't make a whole lot of sense to call this on a view that isn't attached, // but for some simple tests it can be useful. If we don't have attach info this // will allocate memory. @@ -5512,20 +5520,22 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager rectIsVisible = rect.intersect(0, 0, width, height); } - if (rectIsVisible && (mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { + if ((forceParentCheck || rectIsVisible) + && (mGroupFlags & CLIP_TO_PADDING_MASK) == CLIP_TO_PADDING_MASK) { // Clip to padding. rectIsVisible = rect.intersect(mPaddingLeft, mPaddingTop, width - mPaddingRight, height - mPaddingBottom); } - if (rectIsVisible && mClipBounds != null) { + if ((forceParentCheck || rectIsVisible) && mClipBounds != null) { // Clip to clipBounds. rectIsVisible = rect.intersect(mClipBounds.left, mClipBounds.top, mClipBounds.right, mClipBounds.bottom); } r.set((int) Math.floor(rect.left), (int) Math.floor(rect.top), (int) Math.ceil(rect.right), (int) Math.ceil(rect.bottom)); - if (rectIsVisible && mParent != null) { + + if ((forceParentCheck || rectIsVisible) && mParent != null) { rectIsVisible = mParent.getChildVisibleRect(this, r, offset); } return rectIsVisible; diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java index ccdb024820c8f..31ab26fe4eaf1 100644 --- a/core/java/com/android/internal/view/FloatingActionMode.java +++ b/core/java/com/android/internal/view/FloatingActionMode.java @@ -173,7 +173,8 @@ public class FloatingActionMode extends ActionMode { final ViewParent parent = mOriginatingView.getParent(); if (parent instanceof ViewGroup) { ((ViewGroup) parent).getChildVisibleRect( - mOriginatingView, mContentRectOnScreen, null /* offset */); + mOriginatingView, mContentRectOnScreen, + null /* offset */, true /* forceParentCheck */); mContentRectOnScreen.offset(mRootViewPositionOnScreen[0], mRootViewPositionOnScreen[1]); } else { mContentRectOnScreen.offset(mViewPositionOnScreen[0], mViewPositionOnScreen[1]);