Fixing TouchInteractionService referring destroyed activity

Bug: 139137636
Change-Id: I2d36bcd9478e070e21cb6c8e2cde617807af8dd1
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index 25a3078..eb5c7f9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -15,7 +15,9 @@
  */
 package com.android.quickstep;
 
+import static android.view.MotionEvent.ACTION_CANCEL;
 import static android.view.MotionEvent.ACTION_DOWN;
+import static android.view.MotionEvent.ACTION_UP;
 
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
@@ -435,7 +437,8 @@
                 TraceHelper.FLAG_ALLOW_BINDER_TRACKING);
         mDeviceState.setOrientationTransformIfNeeded(event);
 
-        if (event.getAction() == ACTION_DOWN) {
+        final int action = event.getAction();
+        if (action == ACTION_DOWN) {
             GestureState newGestureState = new GestureState(mOverviewComponentObserver,
                     ActiveGestureLog.INSTANCE.generateAndSetLogId());
             newGestureState.updateRunningTask(TraceHelper.whitelistIpcs("getRunningTask.0",
@@ -468,6 +471,13 @@
 
         ActiveGestureLog.INSTANCE.addLog("onMotionEvent", event.getActionMasked());
         mUncheckedConsumer.onMotionEvent(event);
+
+        if (action == ACTION_UP || action == ACTION_CANCEL) {
+            if (mConsumer != null && !mConsumer.isConsumerDetachedFromGesture()) {
+                onConsumerInactive(mConsumer);
+            }
+        }
+
         TraceHelper.INSTANCE.endFlagsOverride(traceToken);
     }
 
@@ -661,8 +671,8 @@
      */
     private void onConsumerInactive(InputConsumer caller) {
         if (mConsumer == caller) {
-            mConsumer = mResetGestureInputConsumer;
-            mUncheckedConsumer = mConsumer;
+            mConsumer = mUncheckedConsumer = mResetGestureInputConsumer;
+            mGestureState = new GestureState();
         }
     }
 
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
index 05c206f..a87e7eb 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/DelegateInputConsumer.java
@@ -25,6 +25,11 @@
     }
 
     @Override
+    public boolean isConsumerDetachedFromGesture() {
+        return mDelegate.isConsumerDetachedFromGesture();
+    }
+
+    @Override
     public boolean allowInterceptByParent() {
         return mDelegate.allowInterceptByParent() && mState != STATE_ACTIVE;
     }
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index 893868b..416d7a1 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -160,6 +160,11 @@
         return TYPE_OTHER_ACTIVITY;
     }
 
+    @Override
+    public boolean isConsumerDetachedFromGesture() {
+        return true;
+    }
+
     private void forceCancelGesture(MotionEvent ev) {
         int action = ev.getAction();
         ev.setAction(ACTION_CANCEL);
diff --git a/quickstep/src/com/android/quickstep/InputConsumer.java b/quickstep/src/com/android/quickstep/InputConsumer.java
index 3e84e7d..8efaeb9 100644
--- a/quickstep/src/com/android/quickstep/InputConsumer.java
+++ b/quickstep/src/com/android/quickstep/InputConsumer.java
@@ -60,6 +60,16 @@
     }
 
     /**
+     * Returns true if the lifecycle of this input consumer is detached from the normal gesture
+     * down/up flow. If so, it is the responsibility of the input consumer to call back to
+     * {@link TouchInteractionService#onConsumerInactive(InputConsumer)} after the consumer is
+     * finished.
+     */
+    default boolean isConsumerDetachedFromGesture() {
+        return false;
+    }
+
+    /**
      * Called by the event queue when the consumer is about to be switched to a new consumer.
      * Consumers should update the state accordingly here before the state is passed to the new
      * consumer.