diff options
| author | Tiger Huang <tigerhuang@google.com> | 2019-03-18 21:21:26 +0800 |
|---|---|---|
| committer | Tiger Huang <tigerhuang@google.com> | 2019-03-28 16:53:20 +0800 |
| commit | 2b210c234c32b1ea3d760f018274576d05b24ad6 (patch) | |
| tree | 0707025cd3583c20c2ce0170849ffb9b29b0a9f6 /core/java/android/view/ViewGroup.java | |
| parent | a50d69cccce55a9de0bdb8e10400e760b3fd1edc (diff) | |
Reduce the window tap exclude region for child above it
For letting touches directly go to the embedded display, we've opened a
tap exclude region for the ActivityView. However, if there is a view on
top of the region, the view cannot be touched within the region.
In this CL, we reduce the tap exclude region if there is a can-receive-
pointer-event view on top of the region.
Bug: 128517544
Test: atest CtsActivityManagerDeviceTestCases:ActivityViewTest
Test: atest FrameworksCoreTests:ViewGroupTest
Test: Menual test with ActivityViewTest and Bubbles
Change-Id: I68e2a9fe9d0891801b533ab8d25074f64bef5a79
Diffstat (limited to 'core/java/android/view/ViewGroup.java')
| -rw-r--r-- | core/java/android/view/ViewGroup.java | 59 |
1 files changed, 45 insertions, 14 deletions
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 4851476e3d70..937bd1b34e61 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -2011,7 +2011,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = childrenCount - 1; i >= 0; i--) { final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex); - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { continue; } @@ -2094,7 +2094,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView( preorderedList, children, childIndex); - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { continue; } @@ -2314,7 +2314,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager getAndVerifyPreorderedIndex(childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex); - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { continue; } @@ -2500,7 +2500,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager for (int i = childrenCount - 1; i >= 0; i--) { final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder); final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex); - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { continue; } @@ -2680,7 +2680,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager i = childrenCount - 1; } - if (!canViewReceivePointerEvents(child) + if (!child.canReceivePointerEvents() || !isTransformedTouchPointInView(x, y, child, null)) { ev.setTargetAccessibilityFocus(false); continue; @@ -2970,15 +2970,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } - /** - * Returns true if a child view can receive pointer events. - * @hide - */ - private static boolean canViewReceivePointerEvents(@NonNull View child) { - return (child.mViewFlags & VISIBILITY_MASK) == VISIBLE - || child.getAnimation() != null; - } - private float[] getTempPoint() { if (mTempPoint == null) { mTempPoint = new float[2]; @@ -7199,6 +7190,46 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } } + /** + * @hide + */ + @Override + public void subtractObscuredTouchableRegion(Region touchableRegion, View view) { + final int childrenCount = mChildrenCount; + final ArrayList<View> preorderedList = buildTouchDispatchChildList(); + final boolean customOrder = preorderedList == null && isChildrenDrawingOrderEnabled(); + final View[] children = mChildren; + for (int i = childrenCount - 1; i >= 0; i--) { + final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder); + final View child = getAndVerifyPreorderedView(preorderedList, children, childIndex); + if (child == view) { + // We've reached the target view. + break; + } + if (!child.canReceivePointerEvents()) { + // This child cannot be touched. Skip it. + continue; + } + applyOpToRegionByBounds(touchableRegion, child, Region.Op.DIFFERENCE); + } + + // The touchable region should not exceed the bounds of its container. + applyOpToRegionByBounds(touchableRegion, this, Region.Op.INTERSECT); + + final ViewParent parent = getParent(); + if (parent != null) { + parent.subtractObscuredTouchableRegion(touchableRegion, this); + } + } + + private static void applyOpToRegionByBounds(Region region, View view, Region.Op op) { + final int[] locationInWindow = new int[2]; + view.getLocationInWindow(locationInWindow); + final int x = locationInWindow[0]; + final int y = locationInWindow[1]; + region.op(x, y, x + view.getWidth(), y + view.getHeight(), op); + } + @Override public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) { insets = super.dispatchApplyWindowInsets(insets); |
