Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a69f2a64 authored by Selim Cinek's avatar Selim Cinek
Browse files

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
parent 496126aa
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -12482,8 +12482,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     * 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);
    }
    /**
+0 −5
Original line number Diff line number Diff line
@@ -517,11 +517,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView {
        requestLayout();
    }

    @Override
    protected boolean filterMotionEvent(MotionEvent event) {
        return mIsHeadsUp || super.filterMotionEvent(event);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
+11 −28
Original line number Diff line number Diff line
@@ -45,7 +45,6 @@ public abstract class ExpandableView extends FrameLayout {
    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 @@ public abstract class ExpandableView extends FrameLayout {
        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 @@ public abstract class ExpandableView extends FrameLayout {
            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 @@ public abstract class ExpandableView extends FrameLayout {
                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 @@ public abstract class ExpandableView extends FrameLayout {
        mMatchParentViews.clear();
        int width = MeasureSpec.getSize(widthMeasureSpec);
        setMeasuredDimension(width, ownHeight);
        mMeasuredTooHigh = heightMode != MeasureSpec.UNSPECIFIED && ownHeight > givenSize;
    }

    protected boolean shouldLimitViewHeight() {
@@ -133,26 +130,11 @@ public abstract class ExpandableView extends FrameLayout {
    }

    @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 @@ public abstract class ExpandableView extends FrameLayout {

    @Override
    public boolean hasOverlappingRendering() {
        return super.hasOverlappingRendering() && !mMeasuredTooHigh;
        // Otherwise it will be clipped
        return super.hasOverlappingRendering() && getActualHeight() <= getHeight();
    }

    /**
+6 −7
Original line number Diff line number Diff line
@@ -378,23 +378,22 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
            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);
+12 −1
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ public class NotificationChildrenContainer extends ViewGroup {
    private ExpandableNotificationRow mNotificationParent;
    private HybridNotificationView mGroupOverflowContainer;
    private ViewState mGroupOverFlowState;
    private int mRealHeight;

    public NotificationChildrenContainer(Context context) {
        this(context, null);
@@ -111,8 +112,8 @@ public class NotificationChildrenContainer extends ViewGroup {
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        boolean hasFixedHeight = heightMode == MeasureSpec.EXACTLY;
        boolean isHeightLimited = heightMode == MeasureSpec.AT_MOST;
        if (hasFixedHeight || isHeightLimited) {
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if (hasFixedHeight || isHeightLimited) {
            ownMaxHeight = Math.min(ownMaxHeight, size);
        }
        int newHeightSpec = MeasureSpec.makeMeasureSpec(ownMaxHeight, MeasureSpec.AT_MOST);
@@ -133,9 +134,19 @@ public class NotificationChildrenContainer extends ViewGroup {
        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.
     *