Add some gesture logging to track down quickscrub launch issue

- Keep rudimentary log of the last few gestures for dumping with the BR
- Also renaming updateInteractionType since we only use it to change
  to the quickscrub starting interaction type now, which is less
  confusing

Bug: 112783625

Change-Id: Ic024684caf2841cd7c09df9481163ea0c0ae03bd
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index f39a007..206c8be 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -91,7 +91,7 @@
      * Updates the UI to indicate quick interaction.
      */
     void onQuickInteractionStart(T activity, @Nullable RunningTaskInfo taskInfo,
-            boolean activityVisible);
+            boolean activityVisible, TouchInteractionLog touchInteractionLog);
 
     float getTranslationYForQuickScrub(TransformedRect targetRect, DeviceProfile dp,
             Context context);
@@ -153,13 +153,14 @@
 
         @Override
         public void onQuickInteractionStart(Launcher activity, RunningTaskInfo taskInfo,
-                boolean activityVisible) {
+                boolean activityVisible, TouchInteractionLog touchInteractionLog) {
             LauncherState fromState = activity.getStateManager().getState();
             activity.getStateManager().goToState(FAST_OVERVIEW, activityVisible);
 
             QuickScrubController controller = activity.<RecentsView>getOverviewPanel()
                     .getQuickScrubController();
-            controller.onQuickScrubStart(activityVisible && !fromState.overviewUi, this);
+            controller.onQuickScrubStart(activityVisible && !fromState.overviewUi, this,
+                    touchInteractionLog);
 
             if (!activityVisible) {
                 // For the duration of the gesture, lock the screen orientation to ensure that we
@@ -425,14 +426,14 @@
 
         @Override
         public void onQuickInteractionStart(RecentsActivity activity, RunningTaskInfo taskInfo,
-                boolean activityVisible) {
+                boolean activityVisible, TouchInteractionLog touchInteractionLog) {
             QuickScrubController controller = activity.<RecentsView>getOverviewPanel()
                     .getQuickScrubController();
 
             // TODO: match user is as well
             boolean startingFromHome = !activityVisible &&
                     (taskInfo == null || Objects.equals(taskInfo.topActivity, mHomeComponent));
-            controller.onQuickScrubStart(startingFromHome, this);
+            controller.onQuickScrubStart(startingFromHome, this, touchInteractionLog);
             if (activityVisible) {
                 mUiHandler.postDelayed(controller::onFinishedTransitionToQuickScrub,
                         OVERVIEW_TRANSITION_MS);
diff --git a/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java b/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
index 8e83bd0..5996df7 100644
--- a/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
@@ -49,8 +49,8 @@
     }
 
     @Override
-    public void updateTouchTracking(int interactionType) {
-        mTarget.updateTouchTracking(interactionType);
+    public void onQuickScrubStart() {
+        mTarget.onQuickScrubStart();
     }
 
     @Override
diff --git a/quickstep/src/com/android/quickstep/MotionEventQueue.java b/quickstep/src/com/android/quickstep/MotionEventQueue.java
index f73be6c..8a598a3 100644
--- a/quickstep/src/com/android/quickstep/MotionEventQueue.java
+++ b/quickstep/src/com/android/quickstep/MotionEventQueue.java
@@ -146,7 +146,7 @@
                 if (event.getActionMasked() == ACTION_VIRTUAL) {
                     switch (event.getAction()) {
                         case ACTION_QUICK_SCRUB_START:
-                            mConsumer.updateTouchTracking(INTERACTION_QUICK_SCRUB);
+                            mConsumer.onQuickScrubStart();
                             break;
                         case ACTION_QUICK_SCRUB_PROGRESS:
                             mConsumer.onQuickScrubProgress(event.getX());
@@ -162,7 +162,7 @@
                             break;
                         case ACTION_SHOW_OVERVIEW_FROM_ALT_TAB:
                             mConsumer.onShowOverviewFromAltTab();
-                            mConsumer.updateTouchTracking(INTERACTION_QUICK_SCRUB);
+                            mConsumer.onQuickScrubStart();
                             break;
                         case ACTION_QUICK_STEP:
                             mConsumer.onQuickStep(event);
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 0e811f7..4417a3d 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -79,6 +79,7 @@
     private final Choreographer mBackgroundThreadChoreographer;
     private final OverviewCallbacks mOverviewCallbacks;
     private final TaskOverlayFactory mTaskOverlayFactory;
+    private final TouchInteractionLog mTouchInteractionLog;
 
     private final boolean mIsDeferredDownTarget;
     private final PointF mDownPos = new PointF();
@@ -100,7 +101,8 @@
             RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
             MainThreadExecutor mainThreadExecutor, Choreographer backgroundThreadChoreographer,
             @HitTarget int downHitTarget, OverviewCallbacks overviewCallbacks,
-            TaskOverlayFactory taskOverlayFactory, VelocityTracker velocityTracker) {
+            TaskOverlayFactory taskOverlayFactory, VelocityTracker velocityTracker,
+            TouchInteractionLog touchInteractionLog) {
         super(base);
 
         mRunningTask = runningTaskInfo;
@@ -113,6 +115,8 @@
         mIsDeferredDownTarget = activityControl.deferStartingActivity(downHitTarget);
         mOverviewCallbacks = overviewCallbacks;
         mTaskOverlayFactory = taskOverlayFactory;
+        mTouchInteractionLog = touchInteractionLog;
+        mTouchInteractionLog.setTouchConsumer(this);
     }
 
     @Override
@@ -125,6 +129,7 @@
         if (mVelocityTracker == null) {
             return;
         }
+        mTouchInteractionLog.addMotionEvent(ev);
         switch (ev.getActionMasked()) {
             case ACTION_DOWN: {
                 TraceHelper.beginSection("TouchInt");
@@ -215,10 +220,13 @@
     }
 
     private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
+        mTouchInteractionLog.startRecentsAnimation();
+
         // Create the shared handler
         RecentsAnimationState animationState = new RecentsAnimationState();
         final WindowTransformSwipeHandler handler = new WindowTransformSwipeHandler(
-                animationState.id, mRunningTask, this, touchTimeMs, mActivityControlHelper);
+                animationState.id, mRunningTask, this, touchTimeMs, mActivityControlHelper,
+                mTouchInteractionLog);
 
         // Preload the plan
         mRecentsModel.loadTasks(mRunningTask.id, null);
@@ -315,7 +323,13 @@
     }
 
     @Override
-    public void updateTouchTracking(int interactionType) {
+    public Choreographer getIntrimChoreographer(MotionEventQueue queue) {
+        mEventQueue = queue;
+        return mBackgroundThreadChoreographer;
+    }
+
+    @Override
+    public void onQuickScrubStart() {
         if (!mPassedInitialSlop && mIsDeferredDownTarget && mInteractionHandler == null) {
             // If we deferred starting the window animation on touch down, then
             // start tracking now
@@ -323,20 +337,16 @@
             mPassedInitialSlop = true;
         }
 
+        mTouchInteractionLog.startQuickScrub();
         if (mInteractionHandler != null) {
-            mInteractionHandler.updateInteractionType(interactionType);
+            mInteractionHandler.onQuickScrubStart();
         }
         notifyGestureStarted();
     }
 
     @Override
-    public Choreographer getIntrimChoreographer(MotionEventQueue queue) {
-        mEventQueue = queue;
-        return mBackgroundThreadChoreographer;
-    }
-
-    @Override
     public void onQuickScrubEnd() {
+        mTouchInteractionLog.endQuickScrub("onQuickScrubEnd");
         if (mInteractionHandler != null) {
             mInteractionHandler.onQuickScrubEnd();
         }
@@ -344,6 +354,7 @@
 
     @Override
     public void onQuickScrubProgress(float progress) {
+        mTouchInteractionLog.setQuickScrubProgress(progress);
         if (mInteractionHandler != null) {
             mInteractionHandler.onQuickScrubProgress(progress);
         }
@@ -351,6 +362,7 @@
 
     @Override
     public void onQuickStep(MotionEvent ev) {
+        mTouchInteractionLog.startQuickStep();
         if (mIsDeferredDownTarget) {
             // Deferred gesture, start the animation and gesture tracking once we pass the actual
             // touch slop
diff --git a/quickstep/src/com/android/quickstep/QuickScrubController.java b/quickstep/src/com/android/quickstep/QuickScrubController.java
index cbc7a67..9432256 100644
--- a/quickstep/src/com/android/quickstep/QuickScrubController.java
+++ b/quickstep/src/com/android/quickstep/QuickScrubController.java
@@ -69,6 +69,7 @@
     private boolean mFinishedTransitionToQuickScrub;
     private Runnable mOnFinishedTransitionToQuickScrubRunnable;
     private ActivityControlHelper mActivityControlHelper;
+    private TouchInteractionLog mTouchInteractionLog;
 
     public QuickScrubController(BaseActivity activity, RecentsView recentsView) {
         mActivity = activity;
@@ -79,13 +80,15 @@
         }
     }
 
-    public void onQuickScrubStart(boolean startingFromHome, ActivityControlHelper controlHelper) {
+    public void onQuickScrubStart(boolean startingFromHome, ActivityControlHelper controlHelper,
+            TouchInteractionLog touchInteractionLog) {
         prepareQuickScrub(TAG);
         mInQuickScrub = true;
         mStartedFromHome = startingFromHome;
         mQuickScrubSection = 0;
         mFinishedTransitionToQuickScrub = false;
         mActivityControlHelper = controlHelper;
+        mTouchInteractionLog = touchInteractionLog;
 
         snapToNextTaskIfAvailable();
         mActivity.getUserEventDispatcher().resetActionDurationMillis();
@@ -101,7 +104,9 @@
             TaskView taskView = mRecentsView.getTaskViewAt(page);
             if (taskView != null) {
                 mWaitingForTaskLaunch = true;
+                mTouchInteractionLog.launchTaskStart();
                 taskView.launchTask(true, (result) -> {
+                    mTouchInteractionLog.launchTaskEnd(result);
                     if (!result) {
                         taskView.notifyTaskLaunchFailed(TAG);
                         breakOutOfQuickScrub();
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
index 646fc57..225d29b 100644
--- a/quickstep/src/com/android/quickstep/TouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -43,7 +43,7 @@
 
     default void reset() { }
 
-    default void updateTouchTracking(@InteractionType int interactionType) { }
+    default void onQuickScrubStart() { }
 
     default void onQuickScrubEnd() { }
 
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionLog.java b/quickstep/src/com/android/quickstep/TouchInteractionLog.java
new file mode 100644
index 0000000..053efbb
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/TouchInteractionLog.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.quickstep;
+
+import android.view.MotionEvent;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.LinkedList;
+
+/**
+ * Keeps track of debugging logs for a particular quickstep/scrub gesture.
+ */
+public class TouchInteractionLog {
+
+    // The number of gestures to log
+    private static final int MAX_NUM_LOG_GESTURES = 5;
+
+    private final Calendar mCalendar = Calendar.getInstance();
+    private final SimpleDateFormat mDateFormat = new SimpleDateFormat("MMM dd - kk:mm:ss:SSS");
+    private final LinkedList<ArrayList<String>> mGestureLogs = new LinkedList<>();
+
+    public void prepareForNewGesture() {
+        mGestureLogs.add(new ArrayList<>());
+        while (mGestureLogs.size() > MAX_NUM_LOG_GESTURES) {
+            mGestureLogs.pop();
+        }
+        getCurrentLog().add("[" + mDateFormat.format(mCalendar.getTime()) + "]");
+    }
+
+    public void setTouchConsumer(TouchConsumer consumer) {
+        getCurrentLog().add("tc=" + consumer.getClass().getSimpleName());
+    }
+
+    public void addMotionEvent(MotionEvent event) {
+        getCurrentLog().add("ev=" + event.getActionMasked());
+    }
+
+    public void startQuickStep() {
+        getCurrentLog().add("qstStart");
+    }
+
+    public void startQuickScrub() {
+        getCurrentLog().add("qsStart");
+    }
+
+    public void setQuickScrubProgress(float progress) {
+        getCurrentLog().add("qsP=" + progress);
+    }
+
+    public void endQuickScrub(String reason) {
+        getCurrentLog().add("qsEnd=" + reason);
+    }
+
+    public void startRecentsAnimation() {
+        getCurrentLog().add("raStart");
+    }
+
+    public void startRecentsAnimationCallback(int numTargets) {
+        getCurrentLog().add("raStartCb=" + numTargets);
+    }
+
+    public void cancelRecentsAnimation() {
+        getCurrentLog().add("raCancel");
+    }
+
+    public void finishRecentsAnimation(boolean toHome) {
+        getCurrentLog().add("raFinish=" + toHome);
+    }
+
+    public void launchTaskStart() {
+        getCurrentLog().add("launchStart");
+    }
+
+    public void launchTaskEnd(boolean result) {
+        getCurrentLog().add("launchEnd=" + result);
+    }
+
+    public void dump(PrintWriter pw) {
+        pw.println("TouchInteractionLog {");
+        for (ArrayList<String> gesture : mGestureLogs) {
+            pw.print("    ");
+            for (String log : gesture) {
+                pw.print(log + " ");
+            }
+            pw.println();
+        }
+        pw.println("}");
+    }
+
+    private ArrayList<String> getCurrentLog() {
+        return mGestureLogs.getLast();
+    }
+}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index bd79301..b9f95cc 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -52,6 +52,8 @@
 import com.android.systemui.shared.system.ActivityManagerWrapper;
 import com.android.systemui.shared.system.ChoreographerCompat;
 import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
 
 /**
  * Service connected by system-UI for handling touch interaction.
@@ -81,6 +83,8 @@
 
         @Override
         public void onPreMotionEvent(@HitTarget int downHitTarget) {
+            mTouchInteractionLog.prepareForNewGesture();
+
             TraceHelper.beginSection("SysUiBinder");
             setupTouchConsumer(downHitTarget);
             TraceHelper.partitionSection("SysUiBinder", "Down target " + downHitTarget);
@@ -179,6 +183,7 @@
     private OverviewInteractionState mOverviewInteractionState;
     private OverviewCallbacks mOverviewCallbacks;
     private TaskOverlayFactory mTaskOverlayFactory;
+    private TouchInteractionLog mTouchInteractionLog;
 
     private Choreographer mMainThreadChoreographer;
     private Choreographer mBackgroundThreadChoreographer;
@@ -196,6 +201,7 @@
         mOverviewInteractionState = OverviewInteractionState.INSTANCE.get(this);
         mOverviewCallbacks = OverviewCallbacks.get(this);
         mTaskOverlayFactory = TaskOverlayFactory.get(this);
+        mTouchInteractionLog = new TouchInteractionLog();
 
         sConnected = true;
 
@@ -240,7 +246,7 @@
         } else if (forceToLauncher ||
                 runningTaskInfo.topActivity.equals(mOverviewCommandHelper.overviewComponent)) {
             return OverviewTouchConsumer.newInstance(
-                    mOverviewCommandHelper.getActivityControlHelper(), false);
+                    mOverviewCommandHelper.getActivityControlHelper(), false, mTouchInteractionLog);
         } else {
             if (tracker == null) {
                 tracker = VelocityTracker.obtain();
@@ -249,7 +255,7 @@
                             mOverviewCommandHelper.overviewIntent,
                             mOverviewCommandHelper.getActivityControlHelper(), mMainThreadExecutor,
                             mBackgroundThreadChoreographer, downHitTarget, mOverviewCallbacks,
-                            mTaskOverlayFactory, tracker);
+                            mTaskOverlayFactory, tracker, mTouchInteractionLog);
         }
     }
 
@@ -262,6 +268,11 @@
                 mBackgroundThreadChoreographer = ChoreographerCompat.getSfInstance());
     }
 
+    @Override
+    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        mTouchInteractionLog.dump(pw);
+    }
+
     public static class OverviewTouchConsumer<T extends BaseDraggingActivity>
             implements TouchConsumer {
 
@@ -272,6 +283,7 @@
         private final PointF mDownPos = new PointF();
         private final int mTouchSlop;
         private final QuickScrubController mQuickScrubController;
+        private final TouchInteractionLog mTouchInteractionLog;
 
         private final boolean mStartingInActivityBounds;
 
@@ -283,7 +295,7 @@
         private boolean mEndPending = false;
 
         OverviewTouchConsumer(ActivityControlHelper<T> activityHelper, T activity,
-                boolean startingInActivityBounds) {
+                boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog) {
             mActivityHelper = activityHelper;
             mActivity = activity;
             mTarget = activity.getDragLayer();
@@ -292,6 +304,8 @@
 
             mQuickScrubController = mActivity.<RecentsView>getOverviewPanel()
                     .getQuickScrubController();
+            mTouchInteractionLog = touchInteractionLog;
+            mTouchInteractionLog.setTouchConsumer(this);
         }
 
         @Override
@@ -299,6 +313,7 @@
             if (mInvalidated) {
                 return;
             }
+            mTouchInteractionLog.addMotionEvent(ev);
             int action = ev.getActionMasked();
             if (action == ACTION_DOWN) {
                 if (mStartingInActivityBounds) {
@@ -372,44 +387,48 @@
             OverviewCallbacks.get(mActivity).closeAllWindows();
             ActivityManagerWrapper.getInstance()
                     .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+            mTouchInteractionLog.startQuickStep();
         }
 
         @Override
-        public void updateTouchTracking(int interactionType) {
+        public void onQuickScrubStart() {
             if (mInvalidated) {
                 return;
             }
-            if (interactionType == INTERACTION_QUICK_SCRUB) {
+            mTouchInteractionLog.startQuickScrub();
+            if (!mQuickScrubController.prepareQuickScrub(TAG)) {
+                mInvalidated = true;
+                mTouchInteractionLog.endQuickScrub("onQuickScrubStart");
+                return;
+            }
+            OverviewCallbacks.get(mActivity).closeAllWindows();
+            ActivityManagerWrapper.getInstance()
+                    .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+
+            mStartPending = true;
+            Runnable action = () -> {
                 if (!mQuickScrubController.prepareQuickScrub(TAG)) {
                     mInvalidated = true;
+                    mTouchInteractionLog.endQuickScrub("onQuickScrubStart");
                     return;
                 }
-                OverviewCallbacks.get(mActivity).closeAllWindows();
-                ActivityManagerWrapper.getInstance()
-                        .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
+                mActivityHelper.onQuickInteractionStart(mActivity, null, true,
+                        mTouchInteractionLog);
+                mQuickScrubController.onQuickScrubProgress(mLastProgress);
+                mStartPending = false;
 
-                mStartPending = true;
-                Runnable action = () -> {
-                    if (!mQuickScrubController.prepareQuickScrub(TAG)) {
-                        mInvalidated = true;
-                        return;
-                    }
-                    mActivityHelper.onQuickInteractionStart(mActivity, null, true);
-                    mQuickScrubController.onQuickScrubProgress(mLastProgress);
-                    mStartPending = false;
+                if (mEndPending) {
+                    mQuickScrubController.onQuickScrubEnd();
+                    mEndPending = false;
+                }
+            };
 
-                    if (mEndPending) {
-                        mQuickScrubController.onQuickScrubEnd();
-                        mEndPending = false;
-                    }
-                };
-
-                mActivityHelper.executeOnWindowAvailable(mActivity, action);
-            }
+            mActivityHelper.executeOnWindowAvailable(mActivity, action);
         }
 
         @Override
         public void onQuickScrubEnd() {
+            mTouchInteractionLog.endQuickScrub("onQuickScrubEnd");
             if (mInvalidated) {
                 return;
             }
@@ -422,6 +441,7 @@
 
         @Override
         public void onQuickScrubProgress(float progress) {
+            mTouchInteractionLog.setQuickScrubProgress(progress);
             mLastProgress = progress;
             if (mInvalidated || mStartPending) {
                 return;
@@ -429,13 +449,14 @@
             mQuickScrubController.onQuickScrubProgress(progress);
         }
 
-        public static TouchConsumer newInstance(
-                ActivityControlHelper activityHelper, boolean startingInActivityBounds) {
+        public static TouchConsumer newInstance(ActivityControlHelper activityHelper,
+                boolean startingInActivityBounds, TouchInteractionLog touchInteractionLog) {
             BaseDraggingActivity activity = activityHelper.getCreatedActivity();
             if (activity == null) {
                 return TouchConsumer.NO_OP;
             }
-            return new OverviewTouchConsumer(activityHelper, activity, startingInActivityBounds);
+            return new OverviewTouchConsumer(activityHelper, activity, startingInActivityBounds,
+                    touchInteractionLog);
         }
     }
 }
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index a2e9af8..9991552 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -198,6 +198,7 @@
     private final Context mContext;
     private final ActivityControlHelper<T> mActivityControlHelper;
     private final ActivityInitListener mActivityInitListener;
+    private final TouchInteractionLog mTouchInteractionLog;
 
     private final int mRunningTaskId;
     private final RunningTaskInfo mRunningTaskInfo;
@@ -239,7 +240,8 @@
     private Bundle mAssistData;
 
     WindowTransformSwipeHandler(int id, RunningTaskInfo runningTaskInfo, Context context,
-            long touchTimeMs, ActivityControlHelper<T> controller) {
+            long touchTimeMs, ActivityControlHelper<T> controller,
+            TouchInteractionLog touchInteractionLog) {
         this.id = id;
         mContext = context;
         mRunningTaskInfo = runningTaskInfo;
@@ -248,6 +250,7 @@
         mActivityControlHelper = controller;
         mActivityInitListener = mActivityControlHelper
                 .createActivityInitListener(this::onActivityInit);
+        mTouchInteractionLog = touchInteractionLog;
 
         initStateCallbacks();
     }
@@ -319,7 +322,7 @@
                 this::notifyTransitionCancelled);
 
         mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
-                        | STATE_APP_CONTROLLER_RECEIVED, this::onQuickScrubStart);
+                        | STATE_APP_CONTROLLER_RECEIVED, this::onQuickScrubStartUi);
         mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_QUICK_SCRUB_START
                 | STATE_SCALED_CONTROLLER_RECENTS, this::onFinishedTransitionToQuickScrub);
         mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_CURRENT_TASK_FINISHED
@@ -503,25 +506,6 @@
                 .getHighResThumbnailLoader().setVisible(true);
     }
 
-    public void updateInteractionType(@InteractionType int interactionType) {
-        if (mInteractionType != INTERACTION_NORMAL) {
-            throw new IllegalArgumentException(
-                    "Can't change interaction type from " + mInteractionType);
-        }
-        if (interactionType != INTERACTION_QUICK_SCRUB) {
-            throw new IllegalArgumentException(
-                    "Can't change interaction type to " + interactionType);
-        }
-        mInteractionType = interactionType;
-        mRecentsAnimationWrapper.runOnInit(this::shiftAnimationDestinationForQuickscrub);
-
-        setStateOnUiThread(STATE_QUICK_SCRUB_START | STATE_GESTURE_COMPLETED);
-
-        // Start the window animation without waiting for launcher.
-        animateToProgress(mCurrentShift.value, 1f, QUICK_SCRUB_FROM_APP_START_DURATION, LINEAR,
-                true /* goingToHome */);
-    }
-
     private void shiftAnimationDestinationForQuickscrub() {
         TransformedRect tempRect = new TransformedRect();
         mActivityControlHelper
@@ -669,6 +653,7 @@
         initTransitionEndpoints(dp);
 
         mRecentsAnimationWrapper.setController(controller, targets);
+        mTouchInteractionLog.startRecentsAnimationCallback(targets.apps.length);
         setStateOnUiThread(STATE_APP_CONTROLLER_RECEIVED);
 
         mPassedOverviewThreshold = false;
@@ -678,6 +663,7 @@
         mRecentsAnimationWrapper.setController(null, null);
         mActivityInitListener.unregister();
         setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED);
+        mTouchInteractionLog.cancelRecentsAnimation();
     }
 
     public void onGestureStarted() {
@@ -729,7 +715,8 @@
         // Hide the task view, if not already hidden
         setTargetAlphaProvider(WindowTransformSwipeHandler::getHiddenTargetAlpha);
 
-        return OverviewTouchConsumer.newInstance(mActivityControlHelper, true);
+        return OverviewTouchConsumer.newInstance(mActivityControlHelper, true,
+                mTouchInteractionLog);
     }
 
     private void handleNormalGestureEnd(float endVelocity, boolean isFling) {
@@ -854,6 +841,7 @@
     @UiThread
     private void resumeLastTask() {
         mRecentsAnimationWrapper.finish(false /* toHome */, null);
+        mTouchInteractionLog.finishRecentsAnimation(false);
     }
 
     public void reset() {
@@ -950,6 +938,7 @@
             mRecentsAnimationWrapper.finish(true /* toHome */,
                     () -> setStateOnUiThread(STATE_CURRENT_TASK_FINISHED));
         }
+        mTouchInteractionLog.finishRecentsAnimation(true);
     }
 
     private void setupLauncherUiAfterSwipeUpAnimation() {
@@ -969,7 +958,22 @@
         reset();
     }
 
-    private void onQuickScrubStart() {
+    public void onQuickScrubStart() {
+        if (mInteractionType != INTERACTION_NORMAL) {
+            throw new IllegalArgumentException(
+                    "Can't change interaction type from " + mInteractionType);
+        }
+        mInteractionType = INTERACTION_QUICK_SCRUB;
+        mRecentsAnimationWrapper.runOnInit(this::shiftAnimationDestinationForQuickscrub);
+
+        setStateOnUiThread(STATE_QUICK_SCRUB_START | STATE_GESTURE_COMPLETED);
+
+        // Start the window animation without waiting for launcher.
+        animateToProgress(mCurrentShift.value, 1f, QUICK_SCRUB_FROM_APP_START_DURATION, LINEAR,
+                true /* goingToHome */);
+    }
+
+    private void onQuickScrubStartUi() {
         if (!mQuickScrubController.prepareQuickScrub(TAG)) {
             mQuickScrubBlocked = true;
             setStateOnUiThread(STATE_RESUME_LAST_TASK | STATE_HANDLER_INVALIDATED);
@@ -980,7 +984,8 @@
             mLauncherTransitionController = null;
         }
 
-        mActivityControlHelper.onQuickInteractionStart(mActivity, mRunningTaskInfo, false);
+        mActivityControlHelper.onQuickInteractionStart(mActivity, mRunningTaskInfo, false,
+                mTouchInteractionLog);
 
         // Inform the last progress in case we skipped before.
         mQuickScrubController.onQuickScrubProgress(mCurrentQuickScrubProgress);