From ba6dbff3f5c8d3f45c942eb0fe66aa45797480ad Mon Sep 17 00:00:00 2001 From: shepshapard Date: Wed, 6 Feb 2019 16:14:22 -0800 Subject: [PATCH] Prevent reflection - ScaleGestureDetector#mMinSpan Also makes "minScalingSpan" accessible to developers via ViewConfiguration in case developers were accessing mMinSpan in order to simply read the value of the field, since that was previously the only way to read the value. Fixes: 123768938 Test: android.view.cts.ViewConfigurationTest Change-Id: Ib179aa153f00a55b6913c7497a1e43bd101f41d3 --- api/current.txt | 1 + .../android/view/ScaleGestureDetector.java | 10 +++---- core/java/android/view/ViewConfiguration.java | 30 +++++++++++++++++++ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/api/current.txt b/api/current.txt index d6f0955dbca9b..520bda1dc49b0 100644 --- a/api/current.txt +++ b/api/current.txt @@ -51111,6 +51111,7 @@ package android.view { method public int getScaledHoverSlop(); method public int getScaledMaximumDrawingCacheSize(); method public int getScaledMaximumFlingVelocity(); + method public int getScaledMinScalingSpan(); method public int getScaledMinimumFlingVelocity(); method public int getScaledOverflingDistance(); method public int getScaledOverscrollDistance(); diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index dc11d3ddd1d6d..c24b8b2a5ee3c 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -18,7 +18,6 @@ package android.view; import android.annotation.UnsupportedAppUsage; import android.content.Context; -import android.content.res.Resources; import android.os.Build; import android.os.Handler; @@ -145,7 +144,7 @@ public class ScaleGestureDetector { private boolean mInProgress; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768938) private int mSpanSlop; - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123768938) private int mMinSpan; private final Handler mHandler; @@ -200,10 +199,9 @@ public class ScaleGestureDetector { Handler handler) { mContext = context; mListener = listener; - mSpanSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2; - - final Resources res = context.getResources(); - mMinSpan = res.getDimensionPixelSize(com.android.internal.R.dimen.config_minScalingSpan); + final ViewConfiguration viewConfiguration = ViewConfiguration.get(context); + mSpanSlop = viewConfiguration.getScaledTouchSlop() * 2; + mMinSpan = viewConfiguration.getScaledMinScalingSpan(); mHandler = handler; // Quick scale is enabled by default after JB_MR2 final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion; diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java index 6beae37d6b46c..bb29ed6c5339a 100644 --- a/core/java/android/view/ViewConfiguration.java +++ b/core/java/android/view/ViewConfiguration.java @@ -293,12 +293,14 @@ public class ViewConfiguration { */ private static final float AMBIGUOUS_GESTURE_MULTIPLIER = 2f; + private final boolean mConstructedWithContext; private final int mEdgeSlop; private final int mFadingEdgeLength; private final int mMinimumFlingVelocity; private final int mMaximumFlingVelocity; private final int mScrollbarSize; private final int mTouchSlop; + private final int mMinScalingSpan; private final int mHoverSlop; private final int mMinScrollbarTouchTarget; private final int mDoubleTapTouchSlop; @@ -329,6 +331,7 @@ public class ViewConfiguration { */ @Deprecated public ViewConfiguration() { + mConstructedWithContext = false; mEdgeSlop = EDGE_SLOP; mFadingEdgeLength = FADING_EDGE_LENGTH; mMinimumFlingVelocity = MINIMUM_FLING_VELOCITY; @@ -350,6 +353,10 @@ public class ViewConfiguration { mHorizontalScrollFactor = HORIZONTAL_SCROLL_FACTOR; mVerticalScrollFactor = VERTICAL_SCROLL_FACTOR; mShowMenuShortcutsWhenKeyboardPresent = false; + + // Getter throws if mConstructedWithContext is false so doesn't matter what + // this value is. + mMinScalingSpan = 0; } /** @@ -363,6 +370,7 @@ public class ViewConfiguration { * @see android.util.DisplayMetrics */ private ViewConfiguration(Context context) { + mConstructedWithContext = true; final Resources res = context.getResources(); final DisplayMetrics metrics = res.getDisplayMetrics(); final Configuration config = res.getConfiguration(); @@ -447,6 +455,8 @@ public class ViewConfiguration { mShowMenuShortcutsWhenKeyboardPresent = res.getBoolean( com.android.internal.R.bool.config_showMenuShortcutsWhenKeyboardPresent); + mMinScalingSpan = res.getDimensionPixelSize( + com.android.internal.R.dimen.config_minScalingSpan); } /** @@ -958,6 +968,26 @@ public class ViewConfiguration { return mShowMenuShortcutsWhenKeyboardPresent; } + /** + * Retrieves the distance in pixels between touches that must be reached for a gesture to be + * interpreted as scaling. + * + * In general, scaling shouldn't start until this distance has been met or surpassed, and + * scaling should end when the distance in pixels between touches drops below this distance. + * + * @return The distance in pixels + * @throws IllegalStateException if this method is called on a ViewConfiguration that was + * instantiated using a constructor with no Context parameter. + */ + public int getScaledMinScalingSpan() { + if (!mConstructedWithContext) { + throw new IllegalStateException("Min scaling span cannot be determined when this " + + "method is called on a ViewConfiguration that was instantiated using a " + + "constructor with no Context parameter"); + } + return mMinScalingSpan; + } + /** * @hide * @return Whether or not marquee should use fading edges.