Fix pinch zoom with partial magnification window not very responsive
When two fingers are too close, the android.view.ScaleGestureDetector will end the scale by minSpan value. This is because the size limit of window magnification can easily trigger the end scale, leading to the zoom out having little effect.
Solution is creating a new construct on android.view.ScaleGestureDetector and set the minSpan to zero.In this way, pinch zoom can work completely on the entire magnification window.
Bug: 295327792
Test: manual
Change-Id: I0afb5021221a7bf00cc1a16299a951f76dd62317
diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java
index a0a172d..5a28d5f 100644
--- a/core/java/android/view/ScaleGestureDetector.java
+++ b/core/java/android/view/ScaleGestureDetector.java
@@ -199,12 +199,33 @@
* @throws NullPointerException if {@code listener} is null.
*/
public ScaleGestureDetector(@NonNull Context context, @NonNull OnScaleGestureListener listener,
- @Nullable Handler handler) {
+ @Nullable Handler handler) {
+ this(context, ViewConfiguration.get(context).getScaledTouchSlop() * 2,
+ ViewConfiguration.get(context).getScaledMinimumScalingSpan(), handler, listener);
+ }
+
+ /**
+ * Creates a ScaleGestureDetector with span slop and min span.
+ *
+ * @param context the application's context.
+ * @param spanSlop the threshold for interpreting a touch movement as scaling.
+ * @param minSpan the minimum threshold of scaling span. The span could be
+ * overridden by other usages to specify a different scaling span, for instance,
+ * if you need pinch gestures to continue closer together than the default.
+ * @param listener the listener invoked for all the callbacks, this must not be null.
+ * @param handler the handler to use for running deferred listener events.
+ *
+ * @throws NullPointerException if {@code listener} is null.
+ *
+ * @hide
+ */
+ public ScaleGestureDetector(@NonNull Context context, @NonNull int spanSlop,
+ @NonNull int minSpan, @Nullable Handler handler,
+ @NonNull OnScaleGestureListener listener) {
mContext = context;
mListener = listener;
- final ViewConfiguration viewConfiguration = ViewConfiguration.get(context);
- mSpanSlop = viewConfiguration.getScaledTouchSlop() * 2;
- mMinSpan = viewConfiguration.getScaledMinimumScalingSpan();
+ mSpanSlop = spanSlop;
+ mMinSpan = minSpan;
mHandler = handler;
// Quick scale is enabled by default after JB_MR2
final int targetSdkVersion = context.getApplicationInfo().targetSdkVersion;
diff --git a/services/accessibility/accessibility.aconfig b/services/accessibility/accessibility.aconfig
index 11189cf..6fa9c08 100644
--- a/services/accessibility/accessibility.aconfig
+++ b/services/accessibility/accessibility.aconfig
@@ -34,3 +34,10 @@
description: "Calls WMS.addWindowToken without holding A11yManagerService#mLock"
bug: "297972548"
}
+
+flag {
+ name: "pinch_zoom_zero_min_span"
+ namespace: "accessibility"
+ description: "Whether to set min span of ScaleGestureDetector to zero."
+ bug: "295327792"
+}
\ No newline at end of file
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
index c5495d9..9455628 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
@@ -28,8 +28,10 @@
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
+import android.view.ViewConfiguration;
import com.android.internal.R;
+import com.android.server.accessibility.Flags;
/**
* Handles the behavior while receiving scaling and panning gestures if it's enabled.
@@ -70,7 +72,13 @@
mMaxScale = maxScale;
mMinScale = minScale;
mBlockScroll = blockScroll;
- mScaleGestureDetector = new ScaleGestureDetector(context, this, Handler.getMain());
+ if (Flags.pinchZoomZeroMinSpan()) {
+ mScaleGestureDetector = new ScaleGestureDetector(context,
+ ViewConfiguration.get(context).getScaledTouchSlop() * 2,
+ /* minSpan= */ 0, Handler.getMain(), this);
+ } else {
+ mScaleGestureDetector = new ScaleGestureDetector(context, this, Handler.getMain());
+ }
mScrollGestureDetector = new GestureDetector(context, this, Handler.getMain());
mScaleGestureDetector.setQuickScaleEnabled(false);
mMagnificationDelegate = magnificationDelegate;