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

Commit b3124b19 authored by Adam Powell's avatar Adam Powell Committed by The Android Automerger
Browse files

DO NOT MERGE - Revert fixes for ImageView/MeasureSpec/RelativeLayout

MeasureSpec.makeMeasureSpec has a bug where a negative or very large
size parameter will cause the resulting MeasureSpec value to
overflow. RelativeLayout partially relies on this when measuring
children with mode UNSPECIFIED; a default value of -1 in a local
variable ends up being passed to makeMeasureSpec, overflowing a mode
value to create a measurespec that is very large in size, with AT_MOST
as the mode. The correct behavior is for RelativeLayout to propagate
the UNSPECIFIED mode.

Unfortunately a number of custom view implementations in apps rely on
the buggy behavior as they do not implement their own onMeasure
method. This makes them fall back to View's default onMeasure
implementation, which accepts the spec's size unconditionally for
AT_MOST or EXACTLY modes, but falls back on
getSuggestedMinimum[Width|Height] for UNSPECIFIED. If the view had no
background drawable with dimensions and no minWidth field set, this
fix for RelativeLayout causes some views to measure with a size of 0
rather than a size of the 30-bit version of 0xFF...

Revert these fixes in the interests of compatibility. The next version
will conditionally use the new behavior if targetSdk > JB-MR1.

This also required reverting a fix for ImageView's adjustViewBounds
functionality, as it cannot be implemented reliably if this
RelativeLayout fix is not also in place.

Revert "Fix UNSPECIFIED measurement in RelativeLayout"

This reverts commit 132a742b.

Revert "Fix adjustViewBounds handling for ImageView"

This reverts commit d5edc772.
parent f7c80fe1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -17234,7 +17234,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
         * @return the measure specification based on size and mode
         */
        public static int makeMeasureSpec(int size, int mode) {
            return (size & ~MODE_MASK) | (mode & MODE_MASK);
            return size + mode;
        }
        /**
+0 −13
Original line number Diff line number Diff line
@@ -789,12 +789,6 @@ public class ImageView extends View {
                    if (resizeWidth) {
                        int newWidth = (int)(desiredAspect * (heightSize - ptop - pbottom)) +
                                pleft + pright;

                        // Allow the width to outgrow its original estimate if height is fixed.
                        if (!resizeHeight) {
                            widthSize = resolveAdjustedSize(newWidth, mMaxWidth, widthMeasureSpec);
                        }

                        if (newWidth <= widthSize) {
                            widthSize = newWidth;
                            done = true;
@@ -805,13 +799,6 @@ public class ImageView extends View {
                    if (!done && resizeHeight) {
                        int newHeight = (int)((widthSize - pleft - pright) / desiredAspect) +
                                ptop + pbottom;

                        // Allow the height to outgrow its original estimate if width is fixed.
                        if (!resizeWidth) {
                            heightSize = resolveAdjustedSize(newHeight, mMaxHeight,
                                    heightMeasureSpec);
                        }

                        if (newHeight <= heightSize) {
                            heightSize = newHeight;
                        }
+5 −17
Original line number Diff line number Diff line
@@ -369,10 +369,10 @@ public class RelativeLayout extends ViewGroup {
        int width = 0;
        int height = 0;

        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);

        // Record our dimensions if they are known;
        if (widthMode != MeasureSpec.UNSPECIFIED) {
@@ -637,12 +637,7 @@ public class RelativeLayout extends ViewGroup {
                mPaddingLeft, mPaddingRight,
                myWidth);
        int childHeightMeasureSpec;
        if (myHeight < 0) {
            // Negative values in a mySize/myWidth/myWidth value in RelativeLayout measurement
            // is code for, "we got an unspecified mode in the RelativeLayout's measurespec."
            // Carry it forward.
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        } else if (params.width == LayoutParams.MATCH_PARENT) {
        if (params.width == LayoutParams.MATCH_PARENT) {
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(myHeight, MeasureSpec.EXACTLY);
        } else {
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(myHeight, MeasureSpec.AT_MOST);
@@ -669,13 +664,6 @@ public class RelativeLayout extends ViewGroup {
    private int getChildMeasureSpec(int childStart, int childEnd,
            int childSize, int startMargin, int endMargin, int startPadding,
            int endPadding, int mySize) {
        if (mySize < 0) {
            // Negative values in a mySize/myWidth/myWidth value in RelativeLayout measurement
            // is code for, "we got an unspecified mode in the RelativeLayout's measurespec."
            // Carry it forward.
            return MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }

        int childSpecMode = 0;
        int childSpecSize = 0;