diff options
2 files changed, 86 insertions, 1 deletions
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java index aa57e0b84a63..a19fdddea49c 100644 --- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java +++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java @@ -68,11 +68,15 @@ import android.view.ViewConfiguration; import com.android.internal.R; import com.android.internal.accessibility.util.AccessibilityStatsLogUtils; import com.android.internal.annotations.VisibleForTesting; +import com.android.modules.expresslog.Histogram; import com.android.server.accessibility.AccessibilityManagerService; import com.android.server.accessibility.AccessibilityTraceManager; import com.android.server.accessibility.Flags; import com.android.server.accessibility.gestures.GestureUtils; +import java.util.ArrayList; +import java.util.List; + /** * This class handles full screen magnification in response to touch events. * @@ -871,6 +875,15 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH */ class DetectingState implements State, Handler.Callback { + private static final Histogram HISTOGRAM_FIRST_INTERVAL = + new Histogram( + "accessibility.value_full_triple_tap_first_interval", + new Histogram.UniformOptions(25, 0, 250)); + private static final Histogram HISTOGRAM_SECOND_INTERVAL = + new Histogram( + "accessibility.value_full_triple_tap_second_interval", + new Histogram.UniformOptions(25, 0, 250)); + private static final int MESSAGE_ON_TRIPLE_TAP_AND_HOLD = 1; private static final int MESSAGE_TRANSITION_TO_DELEGATING_STATE = 2; private static final int MESSAGE_TRANSITION_TO_PANNINGSCALING_STATE = 3; @@ -1115,6 +1128,12 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH if (multitapTriggered && numTaps > 2) { final boolean enabled = !isActivated(); mMagnificationLogger.logMagnificationTripleTap(enabled); + + List<Long> intervals = intervalsOf(mDelayedEventQueue, ACTION_UP); + if (intervals.size() >= 2) { + HISTOGRAM_FIRST_INTERVAL.logSample(intervals.get(0)); + HISTOGRAM_SECOND_INTERVAL.logSample(intervals.get(1)); + } } return multitapTriggered; } @@ -1144,6 +1163,10 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH return event != null ? event.getEventTime() : Long.MIN_VALUE; } + public List<Long> intervalsOf(MotionEventInfo info, int eventType) { + return MotionEventInfo.intervalsOf(info, eventType); + } + public int tapCount() { return MotionEventInfo.countOf(mDelayedEventQueue, ACTION_UP); } @@ -1649,7 +1672,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH return !(Float.isNaN(pointerDownLocation.x) && Float.isNaN(pointerDownLocation.y)); } - private static final class MotionEventInfo { + public static final class MotionEventInfo { private static final int MAX_POOL_SIZE = 10; private static final Object sLock = new Object(); @@ -1709,6 +1732,14 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH } } + public MotionEventInfo getNext() { + return mNext; + } + + public void setNext(MotionEventInfo info) { + mNext = info; + } + private void clear() { event = recycleAndNullify(event); rawEvent = recycleAndNullify(rawEvent); @@ -1721,6 +1752,23 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH + countOf(info.mNext, eventType); } + static List<Long> intervalsOf(MotionEventInfo info, int eventType) { + List<Long> intervals = new ArrayList<>(); + MotionEventInfo current = info; + MotionEventInfo previous = null; + + while (current != null) { + if (current.event.getAction() == eventType) { + if (previous != null) { + intervals.add(current.event.getDownTime() - previous.event.getDownTime()); + } + previous = current; + } + current = current.mNext; + } + return intervals; + } + public static String toString(MotionEventInfo info) { return info == null ? "" diff --git a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java index 598d3a3a9f8a..b745e6a7d4a5 100644 --- a/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java +++ b/services/tests/servicestests/src/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandlerTest.java @@ -32,6 +32,7 @@ import static com.android.server.testutils.TestUtils.strictMock; import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -64,6 +65,7 @@ import android.graphics.Rect; import android.graphics.Region; import android.os.Handler; import android.os.Message; +import android.os.SystemClock; import android.os.UserHandle; import android.os.VibrationEffect; import android.os.Vibrator; @@ -105,6 +107,7 @@ import org.mockito.MockitoAnnotations; import org.mockito.stubbing.Answer; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.function.IntConsumer; @@ -700,6 +703,15 @@ public class FullScreenMagnificationGestureHandlerTest { } @Test + public void testIntervalsOf_sendMotionEventInfo_returnMatchIntervals() { + FullScreenMagnificationGestureHandler.MotionEventInfo upEventQueue = + createEventQueue(ACTION_UP, 0, 100, 300); + + List<Long> upIntervals = mMgh.mDetectingState.intervalsOf(upEventQueue, ACTION_UP); + assertEquals(Arrays.asList(100L, 200L), upIntervals); + } + + @Test public void testMagnifierDeactivates_shortcutTriggeredState_returnToIdleState() { goFromStateIdleTo(STATE_SHORTCUT_TRIGGERED); @@ -2294,6 +2306,31 @@ public class FullScreenMagnificationGestureHandlerTest { return event; } + private FullScreenMagnificationGestureHandler.MotionEventInfo createEventQueue( + int eventType, long... delays) { + FullScreenMagnificationGestureHandler.MotionEventInfo eventQueue = null; + long currentTime = SystemClock.uptimeMillis(); + + for (int i = 0; i < delays.length; i++) { + MotionEvent event = MotionEvent.obtain(currentTime + delays[i], + currentTime + delays[i], eventType, 0, 0, 0); + + FullScreenMagnificationGestureHandler.MotionEventInfo info = + FullScreenMagnificationGestureHandler.MotionEventInfo + .obtain(event, MotionEvent.obtain(event), 0); + + if (eventQueue == null) { + eventQueue = info; + } else { + FullScreenMagnificationGestureHandler.MotionEventInfo tail = eventQueue; + while (tail.getNext() != null) { + tail = tail.getNext(); + } + tail.setNext(info); + } + } + return eventQueue; + } private String stateDump() { return "\nCurrent state dump:\n" + mMgh + "\n" + mHandler.getPendingMessages(); |