Fixed a measuring bug with the notification children container

The notification children didn't respect the given dimensions
when measuring and was simply measuring itself as high as desired.
This lead to a bug where the parent could crash when a layer was
set on it.
We are now measuring the container at most with the height of
the given size and let children draw over our view bounds.
In oder to still allow touch in those regions we also
override the touch rect.
This also simplifies the rest of the touch handling.

Bug: 26159274
Change-Id: I728553a6386455e6632e2511be8a3e7cb447e89b
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 2d7ea2e..537f887 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -12482,8 +12482,7 @@
      * Determines whether the given point, in local coordinates is inside the view.
      */
     /*package*/ final boolean pointInView(float localX, float localY) {
-        return localX >= 0 && localX < (mRight - mLeft)
-                && localY >= 0 && localY < (mBottom - mTop);
+        return pointInView(localX, localY, 0);
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 874b76a..1e73811 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -518,11 +518,6 @@
     }
 
     @Override
-    protected boolean filterMotionEvent(MotionEvent event) {
-        return mIsHeadsUp || super.filterMotionEvent(event);
-    }
-
-    @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
         mPublicLayout = (NotificationContentView) findViewById(R.id.expandedPublic);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
index 59cbd40..bc7bd5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java
@@ -45,7 +45,6 @@
     private static Rect mClipRect = new Rect();
     private boolean mWillBeGone;
     private int mMinClipTopAmount = 0;
-    private boolean mMeasuredTooHigh;
 
     public ExpandableView(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -59,9 +58,7 @@
         final int givenSize = MeasureSpec.getSize(heightMeasureSpec);
         int ownMaxHeight = limitViewHeight ? mMaxViewHeight : Integer.MAX_VALUE;
         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
-        boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
-        if (hasFixedHeight) {
-            // We have a height set in our layout, so we want to be at most as big as given
+        if (heightMode != MeasureSpec.UNSPECIFIED && givenSize != 0) {
             ownMaxHeight = Math.min(givenSize, ownMaxHeight);
         }
         int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
@@ -77,7 +74,7 @@
             if (layoutParams.height != ViewGroup.LayoutParams.MATCH_PARENT) {
                 if (layoutParams.height >= 0) {
                     // An actual height is set
-                    childHeightSpec = layoutParams.height > ownMaxHeight && limitViewHeight
+                    childHeightSpec = layoutParams.height > ownMaxHeight
                         ? MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.EXACTLY)
                         : MeasureSpec.makeMeasureSpec(layoutParams.height, MeasureSpec.EXACTLY);
                 }
@@ -90,7 +87,8 @@
                 mMatchParentViews.add(child);
             }
         }
-        int ownHeight = hasFixedHeight ? ownMaxHeight : Math.min(ownMaxHeight, maxChildHeight);
+        int ownHeight = heightMode == MeasureSpec.EXACTLY
+                ? givenSize : Math.min(ownMaxHeight, maxChildHeight);
         newHeightSpec = MeasureSpec.makeMeasureSpec(ownHeight, MeasureSpec.EXACTLY);
         for (View child : mMatchParentViews) {
             child.measure(getChildMeasureSpec(
@@ -100,7 +98,6 @@
         mMatchParentViews.clear();
         int width = MeasureSpec.getSize(widthMeasureSpec);
         setMeasuredDimension(width, ownHeight);
-        mMeasuredTooHigh = heightMode != MeasureSpec.UNSPECIFIED && ownHeight > givenSize;
     }
 
     protected boolean shouldLimitViewHeight() {
@@ -133,26 +130,11 @@
     }
 
     @Override
-    public boolean dispatchGenericMotionEvent(MotionEvent ev) {
-        if (filterMotionEvent(ev)) {
-            return super.dispatchGenericMotionEvent(ev);
-        }
-        return false;
-    }
-
-    @Override
-    public boolean dispatchTouchEvent(MotionEvent ev) {
-        if (filterMotionEvent(ev)) {
-            return super.dispatchTouchEvent(ev);
-        }
-        return false;
-    }
-
-    protected boolean filterMotionEvent(MotionEvent event) {
-        return event.getActionMasked() != MotionEvent.ACTION_DOWN
-                && event.getActionMasked() != MotionEvent.ACTION_HOVER_ENTER
-                && event.getActionMasked() != MotionEvent.ACTION_HOVER_MOVE
-                || event.getY() > mClipTopAmount && event.getY() < mActualHeight;
+    public boolean pointInView(float localX, float localY, float slop) {
+        float top = mClipTopAmount;
+        float bottom = mActualHeight;
+        return localX >= -slop && localY >= top - slop && localX < ((mRight - mLeft) + slop) &&
+                localY < (bottom + slop);
     }
 
     /**
@@ -397,7 +379,8 @@
 
     @Override
     public boolean hasOverlappingRendering() {
-        return super.hasOverlappingRendering() && !mMeasuredTooHigh;
+        // Otherwise it will be clipped
+        return super.hasOverlappingRendering() && getActualHeight() <= getHeight();
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 5cfd174..b38c3fe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -378,23 +378,22 @@
             return;
         }
         if (mHasPinnedNotification) {
-            int minX = Integer.MAX_VALUE;
+            int minX = 0;
             int maxX = 0;
-            int minY = Integer.MAX_VALUE;
             int maxY = 0;
             for (HeadsUpEntry entry : mSortedEntries) {
                 ExpandableNotificationRow row = entry.entry.row;
                 if (row.isPinned()) {
                     row.getLocationOnScreen(mTmpTwoArray);
-                    minX = Math.min(minX, mTmpTwoArray[0]);
-                    minY = Math.min(minY, 0);
-                    maxX = Math.max(maxX, mTmpTwoArray[0] + row.getWidth());
-                    maxY = Math.max(maxY, row.getHeadsUpHeight());
+                    minX = mTmpTwoArray[0];
+                    maxX = mTmpTwoArray[0] + row.getWidth();
+                    maxY = row.getHeadsUpHeight();
+                    break;
                 }
             }
 
             info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
-            info.touchableRegion.set(minX, minY, maxX, maxY + mNotificationsTopPadding);
+            info.touchableRegion.set(minX, 0, maxX, maxY + mNotificationsTopPadding);
         } else if (mHeadsUpGoingAway || mWaitingOnCollapseWhenGoingAway) {
             info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
             info.touchableRegion.set(0, 0, mStatusBarWindowView.getWidth(), mStatusBarHeight);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
index beaa3ad..321bcbc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java
@@ -56,6 +56,7 @@
     private ExpandableNotificationRow mNotificationParent;
     private HybridNotificationView mGroupOverflowContainer;
     private ViewState mGroupOverFlowState;
+    private int mRealHeight;
 
     public NotificationChildrenContainer(Context context) {
         this(context, null);
@@ -111,8 +112,8 @@
         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
         boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
         boolean isHeightLimited = heightMode == MeasureSpec.AT_MOST;
+        int size = MeasureSpec.getSize(heightMeasureSpec);
         if (hasFixedHeight || isHeightLimited) {
-            int size = MeasureSpec.getSize(heightMeasureSpec);
             ownMaxHeight = Math.min(ownMaxHeight, size);
         }
         int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
@@ -133,9 +134,19 @@
         if (mGroupOverflowContainer != null) {
             mGroupOverflowContainer.measure(widthMeasureSpec, newHeightSpec);
         }
+        mRealHeight = height;
+        if (heightMode != MeasureSpec.UNSPECIFIED) {
+            height = Math.min(height, size);
+        }
         setMeasuredDimension(width, height);
     }
 
+    @Override
+    public boolean pointInView(float localX, float localY, float slop) {
+        return localX >= -slop && localY >= -slop && localX < ((mRight - mLeft) + slop) &&
+                localY < (mRealHeight + slop);
+    }
+
     /**
      * Add a child notification to this view.
      *