Skip to content

Commit 946d05b

Browse files
committed
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 132a742. Revert "Fix adjustViewBounds handling for ImageView" This reverts commit d5edc77.
1 parent 749a997 commit 946d05b

File tree

3 files changed

+6
-31
lines changed

3 files changed

+6
-31
lines changed

core/java/android/view/View.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17234,7 +17234,7 @@ public static class MeasureSpec {
1723417234
* @return the measure specification based on size and mode
1723517235
*/
1723617236
public static int makeMeasureSpec(int size, int mode) {
17237-
return (size & ~MODE_MASK) | (mode & MODE_MASK);
17237+
return size + mode;
1723817238
}
1723917239

1724017240
/**

core/java/android/widget/ImageView.java

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -789,12 +789,6 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
789789
if (resizeWidth) {
790790
int newWidth = (int)(desiredAspect * (heightSize - ptop - pbottom)) +
791791
pleft + pright;
792-
793-
// Allow the width to outgrow its original estimate if height is fixed.
794-
if (!resizeHeight) {
795-
widthSize = resolveAdjustedSize(newWidth, mMaxWidth, widthMeasureSpec);
796-
}
797-
798792
if (newWidth <= widthSize) {
799793
widthSize = newWidth;
800794
done = true;
@@ -805,13 +799,6 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
805799
if (!done && resizeHeight) {
806800
int newHeight = (int)((widthSize - pleft - pright) / desiredAspect) +
807801
ptop + pbottom;
808-
809-
// Allow the height to outgrow its original estimate if width is fixed.
810-
if (!resizeWidth) {
811-
heightSize = resolveAdjustedSize(newHeight, mMaxHeight,
812-
heightMeasureSpec);
813-
}
814-
815802
if (newHeight <= heightSize) {
816803
heightSize = newHeight;
817804
}

core/java/android/widget/RelativeLayout.java

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -369,10 +369,10 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
369369
int width = 0;
370370
int height = 0;
371371

372-
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
373-
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
374-
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
375-
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
372+
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
373+
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
374+
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
375+
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
376376

377377
// Record our dimensions if they are known;
378378
if (widthMode != MeasureSpec.UNSPECIFIED) {
@@ -637,12 +637,7 @@ private void measureChildHorizontal(View child, LayoutParams params, int myWidth
637637
mPaddingLeft, mPaddingRight,
638638
myWidth);
639639
int childHeightMeasureSpec;
640-
if (myHeight < 0) {
641-
// Negative values in a mySize/myWidth/myWidth value in RelativeLayout measurement
642-
// is code for, "we got an unspecified mode in the RelativeLayout's measurespec."
643-
// Carry it forward.
644-
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
645-
} else if (params.width == LayoutParams.MATCH_PARENT) {
640+
if (params.width == LayoutParams.MATCH_PARENT) {
646641
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(myHeight, MeasureSpec.EXACTLY);
647642
} else {
648643
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(myHeight, MeasureSpec.AT_MOST);
@@ -669,13 +664,6 @@ private void measureChildHorizontal(View child, LayoutParams params, int myWidth
669664
private int getChildMeasureSpec(int childStart, int childEnd,
670665
int childSize, int startMargin, int endMargin, int startPadding,
671666
int endPadding, int mySize) {
672-
if (mySize < 0) {
673-
// Negative values in a mySize/myWidth/myWidth value in RelativeLayout measurement
674-
// is code for, "we got an unspecified mode in the RelativeLayout's measurespec."
675-
// Carry it forward.
676-
return MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
677-
}
678-
679667
int childSpecMode = 0;
680668
int childSpecSize = 0;
681669

0 commit comments

Comments
 (0)