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;
}
}