summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorAdam Powell <adamp@google.com>2014-03-06 17:55:16 -0800
committerAdam Powell <adamp@google.com>2014-03-10 14:09:18 -0700
commitfd6b99750bfab7f930ee375a79009874a3196165 (patch)
treeb122d36116e37ca411dd5bdef134c70d3c685f53 /core/java
parentc6f0b54d695b49966a13bb196800a985ac6ce212 (diff)
Prevent overflow from MeasureSpec.adjust; measure cache fix
Extract the size from the MeasureSpec value before adding the delta. The opposite order could result in a negative delta causing overflow into size from the EXACTLY mode, creating a very large size value in the resulting MeasureSpec. Don't reapply optical bounds insets after pulling a value from the measurement cache. (The insets will have already been applied before insertion into the cache.) Change-Id: Ib0154f4d6c3a7c31e7fee24fd7d5d10cc5dc71a1
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/view/View.java31
1 files changed, 29 insertions, 2 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index b0bae463112d..9b47cbe24b81 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16499,7 +16499,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
} else {
long value = mMeasureCache.valueAt(cacheIndex);
// Casting a long to int drops the high 32 bits, no mask needed
- setMeasuredDimension((int) (value >> 32), (int) value);
+ setMeasuredDimensionRaw((int) (value >> 32), (int) value);
mPrivateFlags3 |= PFLAG3_MEASURE_NEEDED_BEFORE_LAYOUT;
}
@@ -16594,6 +16594,22 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
measuredWidth += optical ? opticalWidth : -opticalWidth;
measuredHeight += optical ? opticalHeight : -opticalHeight;
}
+ setMeasuredDimensionRaw(measuredWidth, measuredHeight);
+ }
+
+ /**
+ * Sets the measured dimension without extra processing for things like optical bounds.
+ * Useful for reapplying consistent values that have already been cooked with adjustments
+ * for optical bounds, etc. such as those from the measurement cache.
+ *
+ * @param measuredWidth The measured width of this view. May be a complex
+ * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
+ * {@link #MEASURED_STATE_TOO_SMALL}.
+ * @param measuredHeight The measured height of this view. May be a complex
+ * bit mask as defined by {@link #MEASURED_SIZE_MASK} and
+ * {@link #MEASURED_STATE_TOO_SMALL}.
+ */
+ private void setMeasuredDimensionRaw(int measuredWidth, int measuredHeight) {
mMeasuredWidth = measuredWidth;
mMeasuredHeight = measuredHeight;
@@ -18361,7 +18377,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
static int adjust(int measureSpec, int delta) {
- return makeMeasureSpec(getSize(measureSpec + delta), getMode(measureSpec));
+ final int mode = getMode(measureSpec);
+ if (mode == UNSPECIFIED) {
+ // No need to adjust size for UNSPECIFIED mode.
+ return makeMeasureSpec(0, UNSPECIFIED);
+ }
+ int size = getSize(measureSpec) + delta;
+ if (size < 0) {
+ Log.e(VIEW_LOG_TAG, "MeasureSpec.adjust: new size would be negative! (" + size +
+ ") spec: " + toString(measureSpec) + " delta: " + delta);
+ size = 0;
+ }
+ return makeMeasureSpec(size, mode);
}
/**