Passing all events to RecentsView instead of passing the calculated velocity

Velocity tracker is able to calculate the velocity using cached copy of motionEvent
as long as the event as correct timeStamp

Change-Id: I2b0f612e010fdfcf144d5bed928c5a96b36f3ac7
This commit is contained in:
Sunny Goyal 2019-02-19 16:37:38 -08:00
parent 7b4215d633
commit 4bb8b06ef3
6 changed files with 94 additions and 60 deletions

Binary file not shown.

View File

@ -24,6 +24,7 @@ import static android.view.MotionEvent.INVALID_POINTER_ID;
import static com.android.launcher3.util.RaceConditionTracker.ENTER;
import static com.android.launcher3.util.RaceConditionTracker.EXIT;
import static com.android.quickstep.TouchInteractionService.EDGE_NAV_BAR;
import static com.android.quickstep.TouchInteractionService.TOUCH_INTERACTION_LOG;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
@ -35,7 +36,6 @@ import android.content.Intent;
import android.graphics.PointF;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.view.Display;
import android.view.MotionEvent;
import android.view.Surface;
@ -43,7 +43,6 @@ import android.view.VelocityTracker;
import android.view.ViewConfiguration;
import android.view.WindowManager;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import com.android.launcher3.config.FeatureFlags;
@ -51,10 +50,10 @@ import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.RaceConditionTracker;
import com.android.launcher3.util.TraceHelper;
import com.android.quickstep.WindowTransformSwipeHandler.GestureEndTarget;
import com.android.quickstep.util.CachedEventDispatcher;
import com.android.quickstep.util.MotionPauseDetector;
import com.android.quickstep.util.RecentsAnimationListenerSet;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.AssistDataReceiver;
import com.android.systemui.shared.system.BackgroundExecutor;
import com.android.systemui.shared.system.InputConsumerController;
import com.android.systemui.shared.system.NavigationBarCompat;
@ -71,6 +70,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
public static final String DOWN_EVT = "OtherActivityTouchConsumer.DOWN";
private static final String UP_EVT = "OtherActivityTouchConsumer.UP";
private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher();
private final RunningTaskInfo mRunningTask;
private final RecentsModel mRecentsModel;
private final Intent mHomeIntent;
@ -143,6 +143,19 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
if (mVelocityTracker == null) {
return;
}
// Proxy events to recents view
if (!isNavBarOnLeft() && !isNavBarOnRight()) {
if (mPassedDragSlop && mInteractionHandler != null
&& !mRecentsViewDispatcher.hasConsumer()) {
mRecentsViewDispatcher.setConsumer(mInteractionHandler.getRecentsViewDispatcher());
}
int edgeFlags = ev.getEdgeFlags();
ev.setEdgeFlags(edgeFlags | EDGE_NAV_BAR);
mRecentsViewDispatcher.dispatchEvent(ev);
ev.setEdgeFlags(edgeFlags);
}
mVelocityTracker.addMovement(ev);
if (ev.getActionMasked() == ACTION_POINTER_UP) {
mVelocityTracker.clear();
@ -177,7 +190,6 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
mLastPos.set(ev.getX(newPointerIdx), ev.getY(newPointerIdx));
mActivePointerId = ev.getPointerId(newPointerIdx);
}
dispatchMotion(ev, null, null);
break;
}
case ACTION_MOVE: {
@ -220,7 +232,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
if (mPassedDragSlop && mInteractionHandler != null) {
// Move
dispatchMotion(ev, displacement - mStartDisplacement, null);
mInteractionHandler.updateDisplacement(displacement - mStartDisplacement);
if (FeatureFlags.SWIPE_HOME.get()) {
boolean isLandscape = isNavBarOnLeft() || isNavBarOnRight();
@ -245,17 +257,6 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
}
}
private void dispatchMotion(MotionEvent ev, @Nullable Float displacement,
@Nullable Float velocityX) {
if (displacement != null) {
mInteractionHandler.updateDisplacement(displacement);
}
boolean isLandscape = isNavBarOnLeft() || isNavBarOnRight();
if (!isLandscape) {
mInteractionHandler.dispatchMotionEventToRecentsView(ev, velocityX);
}
}
private void notifyGestureStarted() {
if (mInteractionHandler == null) {
return;
@ -319,8 +320,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
: isNavBarOnLeft() ? -velocityX
: mVelocityTracker.getYVelocity(mActivePointerId);
dispatchMotion(ev, getDisplacement(ev) - mStartDisplacement, velocityX);
mInteractionHandler.updateDisplacement(getDisplacement(ev) - mStartDisplacement);
mInteractionHandler.onGestureEnded(velocity, velocityX);
} else {
// Since we start touch tracking on DOWN, we may reach this state without actually

View File

@ -56,6 +56,7 @@ import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.os.SystemClock;
import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
@ -103,9 +104,9 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat;
import com.android.systemui.shared.system.WindowCallbacksCompat;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
@TargetApi(Build.VERSION_CODES.O)
@ -522,24 +523,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
return TaskView.getCurveScaleForInterpolation(interpolation);
}
@UiThread
public void dispatchMotionEventToRecentsView(MotionEvent event, @Nullable Float velocityX) {
if (mRecentsView == null) {
return;
}
// Pass the motion events to RecentsView to allow scrolling during swipe up.
if (!mDispatchedDownEvent) {
// The first event we dispatch should be ACTION_DOWN.
mDispatchedDownEvent = true;
MotionEvent downEvent = MotionEvent.obtain(event);
downEvent.setAction(MotionEvent.ACTION_DOWN);
int flags = downEvent.getEdgeFlags();
downEvent.setEdgeFlags(flags | TouchInteractionService.EDGE_NAV_BAR);
mRecentsView.simulateTouchEvent(downEvent, velocityX);
downEvent.recycle();
}
mRecentsView.simulateTouchEvent(event, velocityX);
public Consumer<MotionEvent> getRecentsViewDispatcher() {
return mRecentsView != null ? mRecentsView::dispatchTouchEvent : null;
}
@UiThread

View File

@ -0,0 +1,69 @@
/*
* Copyright (C) 2019 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.util;
import static com.android.systemui.shared.system.InputChannelCompat.mergeMotionEvent;
import android.view.MotionEvent;
import java.util.ArrayList;
import java.util.function.Consumer;
/**
* Utility class to dispatch touch events to a different class. It stores the events locally
* until a valid dispatcher is available.
*/
public class CachedEventDispatcher {
private Consumer<MotionEvent> mConsumer;
private ArrayList<MotionEvent> mCache;
private MotionEvent mLastEvent;
public void dispatchEvent(MotionEvent event) {
if (mConsumer != null) {
mConsumer.accept(event);
} else {
if (mLastEvent == null || !mergeMotionEvent(event, mLastEvent)) {
// Queue event.
if (mCache == null) {
mCache = new ArrayList<>();
}
mLastEvent = MotionEvent.obtain(event);
mCache.add(mLastEvent);
}
}
}
public void setConsumer(Consumer<MotionEvent> consumer) {
if (consumer == null) {
return;
}
mConsumer = consumer;
int cacheCount = mCache == null ? 0 : mCache.size();
for (int i = 0; i < cacheCount; i++) {
MotionEvent ev = mCache.get(i);
mConsumer.accept(ev);
ev.recycle();
}
mCache = null;
mLastEvent = null;
}
public boolean hasConsumer() {
return mConsumer != null;
}
}

View File

@ -166,8 +166,6 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
private final ViewPool<TaskView> mTaskViewPool;
@Nullable Float mSimulatedVelocityX = null;
/**
* TODO: Call reloadIdNeeded in onTaskStackChanged.
*/
@ -1626,18 +1624,4 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
}
}
}
public void simulateTouchEvent(MotionEvent event, @Nullable Float velocityX) {
mSimulatedVelocityX = velocityX;
dispatchTouchEvent(event);
mSimulatedVelocityX = null;
}
@Override
protected int computeXVelocity() {
if (mSimulatedVelocityX != null) {
return mSimulatedVelocityX.intValue();
}
return super.computeXVelocity();
}
}

View File

@ -1134,7 +1134,9 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
final int activePointerId = mActivePointerId;
final int pointerIndex = ev.findPointerIndex(activePointerId);
final float x = ev.getX(pointerIndex);
int velocityX = computeXVelocity();
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
int velocityX = (int) velocityTracker.getXVelocity(mActivePointerId);
final int deltaX = (int) (x - mDownMotionX);
final int pageWidth = getPageAt(mCurrentPage).getMeasuredWidth();
boolean isSignificantMove = Math.abs(deltaX) > pageWidth *
@ -1238,12 +1240,6 @@ public abstract class PagedView<T extends View & PageIndicator> extends ViewGrou
return true;
}
protected int computeXVelocity() {
final VelocityTracker velocityTracker = mVelocityTracker;
velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
return (int) velocityTracker.getXVelocity(mActivePointerId);
}
protected boolean shouldFlingForVelocity(int velocityX) {
return Math.abs(velocityX) > mFlingThresholdVelocity;
}