Using the new Touch dispatcher

Change-Id: Ib3cf82f6e0360e6e9609a8a3930125883e6ea997
diff --git a/quickstep/libs/sysui_shared.jar b/quickstep/libs/sysui_shared.jar
index 9ccd477..16d2b67 100644
--- a/quickstep/libs/sysui_shared.jar
+++ b/quickstep/libs/sysui_shared.jar
Binary files differ
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
index af25355..a3c942e 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java
@@ -39,6 +39,8 @@
 import android.content.Context;
 import android.graphics.Rect;
 import android.graphics.RectF;
+import android.graphics.Region;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.animation.Interpolator;
 
@@ -411,6 +413,11 @@
     }
 
     @Override
+    public boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
+        return activeNavBarRegion.contains((int) ev.getX(), (int) ev.getY());
+    }
+
+    @Override
     public Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTargetCompat target) {
         return homeBounds;
     }
diff --git a/quickstep/src/com/android/quickstep/ActivityControlHelper.java b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
index 0bdb578..fd60cb8 100644
--- a/quickstep/src/com/android/quickstep/ActivityControlHelper.java
+++ b/quickstep/src/com/android/quickstep/ActivityControlHelper.java
@@ -22,8 +22,10 @@
 import android.content.Intent;
 import android.graphics.Rect;
 import android.graphics.RectF;
+import android.graphics.Region;
 import android.os.Build;
 import android.os.Handler;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.animation.Interpolator;
 
@@ -103,6 +105,10 @@
      */
     boolean deferStartingActivity(int downHitTarget);
 
+    default boolean deferStartingActivity(Region activeNavBarRegion, MotionEvent ev) {
+        return true;
+    }
+
     boolean supportsLongSwipe(T activity);
 
     AlphaProperty getAlphaProperty(T activity);
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 3a82da1..63349ed 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -43,9 +43,6 @@
 import android.view.ViewConfiguration;
 import android.view.WindowManager;
 
-import androidx.annotation.Nullable;
-import androidx.annotation.UiThread;
-
 import com.android.launcher3.config.FeatureFlags;
 import com.android.launcher3.util.Preconditions;
 import com.android.launcher3.util.RaceConditionTracker;
@@ -58,9 +55,13 @@
 import com.android.systemui.shared.system.BackgroundExecutor;
 import com.android.systemui.shared.system.InputConsumerController;
 import com.android.systemui.shared.system.NavigationBarCompat;
-import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
 import com.android.systemui.shared.system.WindowManagerWrapper;
 
+import java.util.function.Consumer;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.UiThread;
+
 /**
  * Touch consumer for handling events originating from an activity other than Launcher
  */
@@ -83,7 +84,7 @@
     private final int mDisplayRotation;
     private final Rect mStableInsets = new Rect();
 
-    private final MotionEventQueue mEventQueue;
+    private final Consumer<OtherActivityTouchConsumer> mOnCompleteCallback;
     private final MotionPauseDetector mMotionPauseDetector;
     private VelocityTracker mVelocityTracker;
 
@@ -107,9 +108,10 @@
 
     public OtherActivityTouchConsumer(Context base, RunningTaskInfo runningTaskInfo,
             RecentsModel recentsModel, Intent homeIntent, ActivityControlHelper activityControl,
-            @HitTarget int downHitTarget, OverviewCallbacks overviewCallbacks,
+            boolean isDeferredDownTarget, OverviewCallbacks overviewCallbacks,
             TaskOverlayFactory taskOverlayFactory, InputConsumerController inputConsumer,
-            TouchInteractionLog touchInteractionLog, MotionEventQueue eventQueue,
+            TouchInteractionLog touchInteractionLog,
+            Consumer<OtherActivityTouchConsumer> onCompleteCallback,
             SwipeSharedState swipeSharedState) {
         super(base);
 
@@ -118,11 +120,11 @@
         mHomeIntent = homeIntent;
 
         mMotionPauseDetector = new MotionPauseDetector(base);
-        mEventQueue = eventQueue;
+        mOnCompleteCallback = onCompleteCallback;
         mVelocityTracker = VelocityTracker.obtain();
 
         mActivityControlHelper = activityControl;
-        mIsDeferredDownTarget = activityControl.deferStartingActivity(downHitTarget);
+        mIsDeferredDownTarget = isDeferredDownTarget;
         mOverviewCallbacks = overviewCallbacks;
         mTaskOverlayFactory = taskOverlayFactory;
         mTouchInteractionLog = touchInteractionLog;
@@ -381,7 +383,7 @@
         Preconditions.assertUIThread();
         removeListener();
         mInteractionHandler = null;
-        mEventQueue.onConsumerInactive(this);
+        mOnCompleteCallback.accept(this);
     }
 
     private void removeListener() {
diff --git a/quickstep/src/com/android/quickstep/OverviewInteractionState.java b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
index eaa3ad4..411e593 100644
--- a/quickstep/src/com/android/quickstep/OverviewInteractionState.java
+++ b/quickstep/src/com/android/quickstep/OverviewInteractionState.java
@@ -152,7 +152,7 @@
             return;
         }
 
-        int flags = 0;
+        int flags = FLAG_DISABLE_QUICK_SCRUB;
         if (!mSwipeUpEnabled) {
             flags = FLAG_DISABLE_SWIPE_UP | FLAG_DISABLE_QUICK_SCRUB | FLAG_SHOW_OVERVIEW_BUTTON;
         }
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 276ba05..6bbcd65 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -21,6 +21,8 @@
 
 import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
 import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
+import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_CHANNEL;
+import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
 
 import android.annotation.TargetApi;
 import android.app.ActivityManager.RunningTaskInfo;
@@ -34,6 +36,7 @@
 import android.util.Log;
 import android.util.SparseArray;
 import android.view.Choreographer;
+import android.view.InputEvent;
 import android.view.MotionEvent;
 
 import com.android.launcher3.MainThreadExecutor;
@@ -41,6 +44,8 @@
 import com.android.systemui.shared.recents.IOverviewProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.ActivityManagerWrapper;
+import com.android.systemui.shared.system.InputChannelCompat;
+import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver;
 import com.android.systemui.shared.system.InputConsumerController;
 import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
 
@@ -70,11 +75,29 @@
 
     private final IBinder mMyBinder = new IOverviewProxy.Stub() {
 
-        public void onActiveNavBarRegionChanges(Region region) { }
+        public void onActiveNavBarRegionChanges(Region region) {
+            mActiveNavBarRegion = region;
+        }
 
-        public void onInitialize(Bundle params) { }
+        public void onInitialize(Bundle bundle) {
+            mISystemUiProxy = ISystemUiProxy.Stub
+                    .asInterface(bundle.getBinder(KEY_EXTRA_SYSUI_PROXY));
+            mRecentsModel.setSystemUiProxy(mISystemUiProxy);
+            mOverviewInteractionState.setSystemUiProxy(mISystemUiProxy);
+
+            if (mInputEventReceiver != null) {
+                mInputEventReceiver.dispose();
+            }
+            mInputEventReceiver = InputChannelCompat.fromBundle(bundle, KEY_EXTRA_INPUT_CHANNEL,
+                    Looper.getMainLooper(), mMainChoreographer,
+                    TouchInteractionService.this::onInputEvent);
+        }
 
         public void onPreMotionEvent(@HitTarget int downHitTarget) {
+            // If ev are using the new dispatching system, skip the old logic
+            if (mInputEventReceiver != null) {
+                return;
+            }
             mTouchInteractionLog.prepareForNewGesture();
 
             TraceHelper.beginSection("SysUiBinder");
@@ -83,6 +106,11 @@
         }
 
         public void onMotionEvent(MotionEvent ev) {
+            // If ev are using the new dispatching system, skip the old logic
+            if (mInputEventReceiver != null) {
+                ev.recycle();
+                return;
+            }
             mEventQueue.queue(ev);
 
             int action = ev.getActionMasked();
@@ -99,15 +127,27 @@
         }
 
         public void onQuickScrubStart() {
+            // If ev are using the new dispatching system, skip the old logic
+            if (mInputEventReceiver != null) {
+                return;
+            }
             mEventQueue.onQuickScrubStart();
             TraceHelper.partitionSection("SysUiBinder", "onQuickScrubStart");
         }
 
         public void onQuickScrubProgress(float progress) {
+            // If ev are using the new dispatching system, skip the old logic
+            if (mInputEventReceiver != null) {
+                return;
+            }
             mEventQueue.onQuickScrubProgress(progress);
         }
 
         public void onQuickScrubEnd() {
+            // If ev are using the new dispatching system, skip the old logic
+            if (mInputEventReceiver != null) {
+                return;
+            }
             mEventQueue.onQuickScrubEnd();
             TraceHelper.endSection("SysUiBinder", "onQuickScrubEnd");
         }
@@ -119,6 +159,11 @@
 
         @Override
         public void onOverviewShown(boolean triggeredFromAltTab) {
+            // If ev are using the new dispatching system, skip the old logic
+            if (mInputEventReceiver != null) {
+                mOverviewCommandHelper.onOverviewShown();
+                return;
+            }
             if (triggeredFromAltTab) {
                 mEventQueue.onNewGesture(HIT_TARGET_NONE);
                 mEventQueue.onOverviewShownFromAltTab();
@@ -129,6 +174,10 @@
 
         @Override
         public void onOverviewHidden(boolean triggeredFromAltTab, boolean triggeredFromHomeKey) {
+            // If ev are using the new dispatching system, skip the old logic
+            if (mInputEventReceiver != null) {
+                return;
+            }
             if (triggeredFromAltTab && !triggeredFromHomeKey) {
                 // onOverviewShownFromAltTab initiates quick scrub. Ending it here.
                 mEventQueue.onQuickScrubEnd();
@@ -162,12 +211,19 @@
     private InputConsumerController mInputConsumer;
     private SwipeSharedState mSwipeSharedState;
 
+    private TouchConsumer mConsumer = TouchConsumer.NO_OP;
+    private Choreographer mMainChoreographer;
+    private InputEventReceiver mInputEventReceiver;
+    private Region mActiveNavBarRegion = new Region();
+
     @Override
     public void onCreate() {
         super.onCreate();
         mAM = ActivityManagerWrapper.getInstance();
         mRecentsModel = RecentsModel.INSTANCE.get(this);
         mOverviewComponentObserver = new OverviewComponentObserver(this);
+        mMainChoreographer = Choreographer.getInstance();
+
         mOverviewCommandHelper = new OverviewCommandHelper(this, mOverviewComponentObserver);
         mEventQueue = new MotionEventQueue(Looper.myLooper(), Choreographer.getInstance(),
                 this::newConsumer);
@@ -190,6 +246,9 @@
         mInputConsumer.unregisterInputConsumer();
         mOverviewComponentObserver.onDestroy();
         mEventQueue.dispose();
+        if (mInputEventReceiver != null) {
+            mInputEventReceiver.dispose();
+        }
         sConnected = false;
         super.onDestroy();
     }
@@ -200,6 +259,22 @@
         return mMyBinder;
     }
 
+    private void onInputEvent(InputEvent ev) {
+        if (!(ev instanceof MotionEvent)) {
+            Log.e(TAG, "Unknown event " + ev);
+            return;
+        }
+        MotionEvent event = (MotionEvent) ev;
+        if (event.getAction() == ACTION_DOWN) {
+            mTouchInteractionLog.prepareForNewGesture();
+            boolean useSharedState = mConsumer.isActive();
+            mConsumer.onConsumerAboutToBeSwitched();
+            mConsumer = newConsumer(useSharedState, event);
+        }
+
+        mConsumer.accept(event);
+    }
+
     private TouchConsumer newConsumer(@HitTarget int downHitTarget, boolean useSharedState) {
         RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
         if (!useSharedState) {
@@ -219,12 +294,54 @@
                     mOverviewComponentObserver.getActivityControlHelper(), false,
                     mTouchInteractionLog, false /* waitForWindowAvailable */);
         } else {
+            ActivityControlHelper activityControl =
+                    mOverviewComponentObserver.getActivityControlHelper();
             return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
                     mOverviewComponentObserver.getOverviewIntent(),
                     mOverviewComponentObserver.getActivityControlHelper(),
-                    downHitTarget, mOverviewCallbacks,
-                    mTaskOverlayFactory, mInputConsumer, mTouchInteractionLog, mEventQueue,
-                    mSwipeSharedState);
+                    activityControl.deferStartingActivity(downHitTarget), mOverviewCallbacks,
+                    mTaskOverlayFactory, mInputConsumer, mTouchInteractionLog,
+                    mEventQueue::onConsumerInactive, mSwipeSharedState);
+        }
+    }
+
+    private TouchConsumer newConsumer(boolean useSharedState, MotionEvent event) {
+        RunningTaskInfo runningTaskInfo = mAM.getRunningTask(0);
+        if (!useSharedState) {
+            mSwipeSharedState.clearAllState();
+        }
+
+        if (runningTaskInfo == null && !mSwipeSharedState.goingToLauncher) {
+            return TouchConsumer.NO_OP;
+        } else if (mSwipeSharedState.goingToLauncher ||
+                mOverviewComponentObserver.getActivityControlHelper().isResumed()) {
+            return OverviewTouchConsumer.newInstance(
+                    mOverviewComponentObserver.getActivityControlHelper(), false,
+                    mTouchInteractionLog);
+        } else if (ENABLE_QUICKSTEP_LIVE_TILE.get() &&
+                mOverviewComponentObserver.getActivityControlHelper().isInLiveTileMode()) {
+            return OverviewTouchConsumer.newInstance(
+                    mOverviewComponentObserver.getActivityControlHelper(), false,
+                    mTouchInteractionLog, false /* waitForWindowAvailable */);
+        } else {
+            ActivityControlHelper activityControl =
+                    mOverviewComponentObserver.getActivityControlHelper();
+            boolean shouldDefer = activityControl.deferStartingActivity(mActiveNavBarRegion, event);
+            return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
+                    mOverviewComponentObserver.getOverviewIntent(),
+                    mOverviewComponentObserver.getActivityControlHelper(),
+                    shouldDefer, mOverviewCallbacks,
+                    mTaskOverlayFactory, mInputConsumer, mTouchInteractionLog,
+                    this::onConsumerInactive, mSwipeSharedState);
+        }
+    }
+
+    /**
+     * To be called by the consumer when it's no longer active.
+     */
+    private void onConsumerInactive(TouchConsumer caller) {
+        if (mConsumer == caller) {
+            mConsumer = TouchConsumer.NO_OP;
         }
     }