summaryrefslogtreecommitdiffstats
path: root/quickstep/src/com/android
diff options
context:
space:
mode:
authorSunny Goyal <sunnygoyal@google.com>2018-03-12 13:40:58 -0700
committerSunny Goyal <sunnygoyal@google.com>2018-03-12 15:25:17 -0700
commit6586062f711a5194d22d870b66ba7e5a8467576f (patch)
tree624b2195f13f1f18e0941724186ce7eaab8bee04 /quickstep/src/com/android
parentdcdeffdfd5446886759e128d4b59ffa1cb3c2dc1 (diff)
downloadandroid_packages_apps_Trebuchet-6586062f711a5194d22d870b66ba7e5a8467576f.tar.gz
android_packages_apps_Trebuchet-6586062f711a5194d22d870b66ba7e5a8467576f.tar.bz2
android_packages_apps_Trebuchet-6586062f711a5194d22d870b66ba7e5a8467576f.zip
Ensuring that we finish the last transition before starting a new one.
> Finishing the active animation instead of cancelling it. This ansures that the animation callbacks are called properly and RecentsAnimaiton is finished > If a transition is already running, using main thread for next transtion so that this new transition is not started before the last transition is finished. > If the transition is expected to finish at Launcher, directly use the Launcher consumer. RunningTaskInfo is not updated until the screen shot is complete. Bug: 74481901 Change-Id: I2b1128f1f2eff0e6bd94b3adb9cef6ae0578bd0c
Diffstat (limited to 'quickstep/src/com/android')
-rw-r--r--quickstep/src/com/android/quickstep/AnimatedFloat.java6
-rw-r--r--quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java1
-rw-r--r--quickstep/src/com/android/quickstep/DeferredTouchConsumer.java99
-rw-r--r--quickstep/src/com/android/quickstep/MotionEventQueue.java17
-rw-r--r--quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java5
-rw-r--r--quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java21
-rw-r--r--quickstep/src/com/android/quickstep/TouchConsumer.java12
-rw-r--r--quickstep/src/com/android/quickstep/TouchInteractionService.java47
-rw-r--r--quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java7
9 files changed, 186 insertions, 29 deletions
diff --git a/quickstep/src/com/android/quickstep/AnimatedFloat.java b/quickstep/src/com/android/quickstep/AnimatedFloat.java
index 214b3f3b9..84dfa457e 100644
--- a/quickstep/src/com/android/quickstep/AnimatedFloat.java
+++ b/quickstep/src/com/android/quickstep/AnimatedFloat.java
@@ -77,6 +77,12 @@ public class AnimatedFloat {
}
}
+ public void finishAnimation() {
+ if (mValueAnimator != null && mValueAnimator.isRunning()) {
+ mValueAnimator.end();
+ }
+ }
+
public ObjectAnimator getCurrentAnimation() {
return mValueAnimator;
}
diff --git a/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java b/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java
index b3ebd772c..5871a6d59 100644
--- a/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java
+++ b/quickstep/src/com/android/quickstep/BaseSwipeInteractionHandler.java
@@ -23,6 +23,7 @@ import com.android.quickstep.TouchConsumer.InteractionType;
public abstract class BaseSwipeInteractionHandler extends InternalStateHandler {
protected Runnable mGestureEndCallback;
+ protected boolean mIsGoingToHome;
public void setGestureEndCallback(Runnable gestureEndCallback) {
mGestureEndCallback = gestureEndCallback;
diff --git a/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java b/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
new file mode 100644
index 000000000..b92678a2e
--- /dev/null
+++ b/quickstep/src/com/android/quickstep/DeferredTouchConsumer.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2018 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.annotation.TargetApi;
+import android.os.Build;
+import android.view.Choreographer;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+
+/**
+ * A TouchConsumer which defers all events on the UIThread until the consumer is created.
+ */
+@TargetApi(Build.VERSION_CODES.P)
+public class DeferredTouchConsumer implements TouchConsumer {
+
+ private final VelocityTracker mVelocityTracker;
+ private final DeferredTouchProvider mTouchProvider;
+
+ private MotionEventQueue mMyQueue;
+ private TouchConsumer mTarget;
+
+ public DeferredTouchConsumer(DeferredTouchProvider touchProvider) {
+ mVelocityTracker = VelocityTracker.obtain();
+ mTouchProvider = touchProvider;
+ }
+
+ @Override
+ public void accept(MotionEvent event) {
+ mTarget.accept(event);
+ }
+
+ @Override
+ public void reset() {
+ mTarget.reset();
+ }
+
+ @Override
+ public void updateTouchTracking(int interactionType) {
+ mTarget.updateTouchTracking(interactionType);
+ }
+
+ @Override
+ public void onQuickScrubEnd() {
+ mTarget.onQuickScrubEnd();
+ }
+
+ @Override
+ public void onQuickScrubProgress(float progress) {
+ mTarget.onQuickScrubProgress(progress);
+ }
+
+ @Override
+ public void preProcessMotionEvent(MotionEvent ev) {
+ mVelocityTracker.addMovement(ev);
+ }
+
+ @Override
+ public Choreographer getIntrimChoreographer(MotionEventQueue queue) {
+ mMyQueue = queue;
+ return null;
+ }
+
+ @Override
+ public void deferInit() {
+ mTarget = mTouchProvider.createTouchConsumer(mVelocityTracker);
+ mTarget.getIntrimChoreographer(mMyQueue);
+ }
+
+ @Override
+ public boolean forceToLauncherConsumer() {
+ return mTarget.forceToLauncherConsumer();
+ }
+
+ @Override
+ public boolean deferNextEventToMainThread() {
+ // If our target is still null, defer the next target as well
+ TouchConsumer target = mTarget;
+ return target == null ? true : target.deferNextEventToMainThread();
+ }
+
+ public interface DeferredTouchProvider {
+
+ TouchConsumer createTouchConsumer(VelocityTracker tracker);
+ }
+}
diff --git a/quickstep/src/com/android/quickstep/MotionEventQueue.java b/quickstep/src/com/android/quickstep/MotionEventQueue.java
index 6e92d83c5..94b6faa39 100644
--- a/quickstep/src/com/android/quickstep/MotionEventQueue.java
+++ b/quickstep/src/com/android/quickstep/MotionEventQueue.java
@@ -53,6 +53,8 @@ public class MotionEventQueue {
ACTION_VIRTUAL | (4 << ACTION_POINTER_INDEX_SHIFT);
private static final int ACTION_RESET =
ACTION_VIRTUAL | (5 << ACTION_POINTER_INDEX_SHIFT);
+ private static final int ACTION_DEFER_INIT =
+ ACTION_VIRTUAL | (6 << ACTION_POINTER_INDEX_SHIFT);
private final EventArray mEmptyArray = new EventArray();
private final Object mExecutionLock = new Object();
@@ -76,10 +78,10 @@ public class MotionEventQueue {
public MotionEventQueue(Choreographer choreographer, TouchConsumer consumer) {
mMainChoreographer = choreographer;
mConsumer = consumer;
-
mCurrentChoreographer = mMainChoreographer;
mCurrentRunnable = mMainFrameCallback;
- setInterimChoreographerLocked(consumer.getIntrimChoreographer(this));
+
+ setInterimChoreographer(consumer.getIntrimChoreographer(this));
}
public void setInterimChoreographer(Choreographer choreographer) {
@@ -156,6 +158,9 @@ public class MotionEventQueue {
case ACTION_RESET:
mConsumer.reset();
break;
+ case ACTION_DEFER_INIT:
+ mConsumer.deferInit();
+ break;
default:
Log.e(TAG, "Invalid virtual event: " + event.getAction());
}
@@ -204,6 +209,14 @@ public class MotionEventQueue {
queueVirtualAction(ACTION_RESET, 0);
}
+ public void deferInit() {
+ queueVirtualAction(ACTION_DEFER_INIT, 0);
+ }
+
+ public TouchConsumer getConsumer() {
+ return mConsumer;
+ }
+
private static class EventArray extends ArrayList<MotionEvent> {
public int lastEventAction = ACTION_CANCEL;
diff --git a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
index ff7d434e7..fca844c6b 100644
--- a/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
+++ b/quickstep/src/com/android/quickstep/NavBarSwipeInteractionHandler.java
@@ -319,13 +319,14 @@ public class NavBarSwipeInteractionHandler extends BaseSwipeInteractionHandler i
/** Animates to the given progress, where 0 is the current app and 1 is overview. */
private void animateToProgress(float progress, long duration) {
+ mIsGoingToHome = Float.compare(progress, 1) == 0;
ObjectAnimator anim = mCurrentShift.animateToValue(progress).setDuration(duration);
anim.setInterpolator(Interpolators.SCROLL);
anim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
- mStateCallback.setState((Float.compare(mCurrentShift.value, 0) == 0)
- ? STATE_SCALED_SNAPSHOT_APP : STATE_SCALED_SNAPSHOT_RECENTS);
+ mStateCallback.setState(mIsGoingToHome
+ ? STATE_SCALED_SNAPSHOT_RECENTS : STATE_SCALED_SNAPSHOT_APP);
}
});
anim.start();
diff --git a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
index 9b2e82264..c96f6d73a 100644
--- a/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/OtherActivityTouchConsumer.java
@@ -25,9 +25,9 @@ import static android.view.MotionEvent.INVALID_POINTER_ID;
import static com.android.quickstep.RemoteRunnable.executeSafely;
import static com.android.quickstep.TouchInteractionService.DEBUG_SHOW_OVERVIEW_BUTTON;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
-import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
+import android.annotation.TargetApi;
import android.app.ActivityManager.RunningTaskInfo;
import android.app.ActivityOptions;
import android.content.Context;
@@ -39,6 +39,7 @@ import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
+import android.os.Build;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
@@ -70,6 +71,7 @@ import java.util.concurrent.TimeUnit;
/**
* Touch consumer for handling events originating from an activity other than Launcher
*/
+@TargetApi(Build.VERSION_CODES.P)
public class OtherActivityTouchConsumer extends ContextWrapper implements TouchConsumer {
private static final String TAG = "ActivityTouchConsumer";
@@ -97,16 +99,17 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
private VelocityTracker mVelocityTracker;
private MotionEventQueue mEventQueue;
+ private boolean mIsGoingToHome;
public OtherActivityTouchConsumer(Context base, RunningTaskInfo runningTaskInfo,
RecentsModel recentsModel, Intent homeIntent, ISystemUiProxy systemUiProxy,
MainThreadExecutor mainThreadExecutor, Choreographer backgroundThreadChoreographer,
- @HitTarget int downHitTarget) {
+ @HitTarget int downHitTarget, VelocityTracker velocityTracker) {
super(base);
mRunningTask = runningTaskInfo;
mRecentsModel = recentsModel;
mHomeIntent = homeIntent;
- mVelocityTracker = VelocityTracker.obtain();
+ mVelocityTracker = velocityTracker;
mISystemUiProxy = systemUiProxy;
mMainThreadExecutor = mainThreadExecutor;
mBackgroundThreadChoreographer = backgroundThreadChoreographer;
@@ -374,6 +377,7 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
if (mInteractionHandler != null) {
final BaseSwipeInteractionHandler handler = mInteractionHandler;
mInteractionHandler = null;
+ mIsGoingToHome = handler.mIsGoingToHome;
mMainThreadExecutor.execute(handler::reset);
}
}
@@ -428,4 +432,15 @@ public class OtherActivityTouchConsumer extends ContextWrapper implements TouchC
}
}
}
+
+ @Override
+ public boolean forceToLauncherConsumer() {
+ return mIsGoingToHome;
+ }
+
+ @Override
+ public boolean deferNextEventToMainThread() {
+ // TODO: Consider also check if the eventQueue is using mainThread of not.
+ return mInteractionHandler != null;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/TouchConsumer.java b/quickstep/src/com/android/quickstep/TouchConsumer.java
index f35f6a6f4..768fbda73 100644
--- a/quickstep/src/com/android/quickstep/TouchConsumer.java
+++ b/quickstep/src/com/android/quickstep/TouchConsumer.java
@@ -21,8 +21,6 @@ import android.support.annotation.IntDef;
import android.view.Choreographer;
import android.view.MotionEvent;
-import com.android.systemui.shared.system.NavigationBarCompat.HitTarget;
-
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.function.Consumer;
@@ -64,4 +62,14 @@ public interface TouchConsumer extends Consumer<MotionEvent> {
default Choreographer getIntrimChoreographer(MotionEventQueue queue) {
return null;
}
+
+ default void deferInit() { }
+
+ default boolean deferNextEventToMainThread() {
+ return false;
+ }
+
+ default boolean forceToLauncherConsumer() {
+ return false;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 12c21701c..5d0bec9c1 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -39,6 +39,7 @@ import android.util.Log;
import android.util.SparseArray;
import android.view.Choreographer;
import android.view.MotionEvent;
+import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
@@ -161,7 +162,6 @@ public class TouchInteractionService extends Service {
private Choreographer mMainThreadChoreographer;
private Choreographer mBackgroundThreadChoreographer;
- private MotionEventQueue mNoOpEventQueue;
@Override
public void onCreate() {
@@ -171,8 +171,7 @@ public class TouchInteractionService extends Service {
mMainThreadExecutor = new MainThreadExecutor();
mOverviewCommandHelper = new OverviewCommandHelper(this);
mMainThreadChoreographer = Choreographer.getInstance();
- mNoOpEventQueue = new MotionEventQueue(mMainThreadChoreographer, mNoOpTouchConsumer);
- mEventQueue = mNoOpEventQueue;
+ mEventQueue = new MotionEventQueue(mMainThreadChoreographer, mNoOpTouchConsumer);
sConnected = true;
@@ -194,31 +193,45 @@ public class TouchInteractionService extends Service {
}
private void onBinderPreMotionEvent(@HitTarget int downHitTarget) {
- RunningTaskInfo runningTaskInfo = mAM.getRunningTask();
-
mEventQueue.reset();
+ TouchConsumer oldConsumer = mEventQueue.getConsumer();
+ if (oldConsumer.deferNextEventToMainThread()) {
+ mEventQueue = new MotionEventQueue(mMainThreadChoreographer,
+ new DeferredTouchConsumer((v) -> getCurrentTouchConsumer(downHitTarget,
+ oldConsumer.forceToLauncherConsumer(), v)));
+ mEventQueue.deferInit();
+ } else {
+ mEventQueue = new MotionEventQueue(
+ mMainThreadChoreographer, getCurrentTouchConsumer(downHitTarget, false, null));
+ }
+ }
- if (runningTaskInfo == null) {
- mEventQueue = mNoOpEventQueue;
- } else if (runningTaskInfo.topActivity.equals(mOverviewCommandHelper.launcher)) {
- mEventQueue = getLauncherEventQueue();
+ private TouchConsumer getCurrentTouchConsumer(
+ @HitTarget int downHitTarget, boolean forceToLauncher, VelocityTracker tracker) {
+ RunningTaskInfo runningTaskInfo = mAM.getRunningTask();
+
+ if (runningTaskInfo == null && !forceToLauncher) {
+ return mNoOpTouchConsumer;
+ } else if (forceToLauncher ||
+ runningTaskInfo.topActivity.equals(mOverviewCommandHelper.launcher)) {
+ return getLauncherConsumer();
} else {
- mEventQueue = new MotionEventQueue(mMainThreadChoreographer,
- new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
+ if (tracker == null) {
+ tracker = VelocityTracker.obtain();
+ }
+ return new OtherActivityTouchConsumer(this, runningTaskInfo, mRecentsModel,
mOverviewCommandHelper.homeIntent, mISystemUiProxy, mMainThreadExecutor,
- mBackgroundThreadChoreographer, downHitTarget));
+ mBackgroundThreadChoreographer, downHitTarget, tracker);
}
}
- private MotionEventQueue getLauncherEventQueue() {
+ private TouchConsumer getLauncherConsumer() {
Launcher launcher = (Launcher) LauncherAppState.getInstance(this).getModel().getCallback();
if (launcher == null) {
- return mNoOpEventQueue;
+ return mNoOpTouchConsumer;
}
-
View target = launcher.getDragLayer();
- return new MotionEventQueue(mMainThreadChoreographer,
- new LauncherTouchConsumer(launcher, target));
+ return new LauncherTouchConsumer(launcher, target);
}
private static class LauncherTouchConsumer implements TouchConsumer {
diff --git a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
index bab8ef17a..7c242fa52 100644
--- a/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -720,13 +720,14 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
/** Animates to the given progress, where 0 is the current app and 1 is overview. */
private void animateToProgress(float progress, long duration) {
+ mIsGoingToHome = Float.compare(progress, 1) == 0;
ObjectAnimator anim = mCurrentShift.animateToValue(progress).setDuration(duration);
anim.setInterpolator(Interpolators.SCROLL);
anim.addListener(new AnimationSuccessListener() {
@Override
public void onAnimationSuccess(Animator animator) {
- setStateOnUiThread((Float.compare(mCurrentShift.value, 0) == 0)
- ? STATE_SCALED_CONTROLLER_APP : STATE_SCALED_CONTROLLER_RECENTS);
+ setStateOnUiThread(mIsGoingToHome ?
+ STATE_SCALED_CONTROLLER_RECENTS : STATE_SCALED_CONTROLLER_APP);
}
});
anim.start();
@@ -747,7 +748,7 @@ public class WindowTransformSwipeHandler extends BaseSwipeInteractionHandler {
}
private void invalidateHandler() {
- mCurrentShift.cancelAnimation();
+ mCurrentShift.finishAnimation();
if (mGestureEndCallback != null) {
mGestureEndCallback.run();