Some quick scrub fixes

> Skipping quick scrub, if its already in progress, or is waiting on previous task launch
> Restoring to proper state is the task animation is cancelled before launcher gets onStop
> Crash when using quickscrub before last list has loaded

Bug: 77289180
Bug: 77856587
Bug: 79919440
Change-Id: I8db127bf9539cfc8f47c1e86c5030637845749d4
This commit is contained in:
Sunny Goyal 2018-05-18 11:12:23 -07:00
parent f9d38098ca
commit 32359e6b85
4 changed files with 71 additions and 23 deletions

View File

@ -127,13 +127,6 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
private RemoteAnimationProvider mRemoteAnimationProvider; private RemoteAnimationProvider mRemoteAnimationProvider;
private final AnimatorListenerAdapter mReapplyStateListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLauncher.getStateManager().reapplyState();
}
};
private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() { private final AnimatorListenerAdapter mForceInvisibleListener = new AnimatorListenerAdapter() {
@Override @Override
public void onAnimationStart(Animator animation) { public void onAnimationStart(Animator animation) {
@ -260,7 +253,13 @@ public class LauncherAppTransitionManagerImpl extends LauncherAppTransitionManag
launcherAnim.setDuration(RECENTS_LAUNCH_DURATION); launcherAnim.setDuration(RECENTS_LAUNCH_DURATION);
// Make sure recents gets fixed up by resetting task alphas and scales, etc. // Make sure recents gets fixed up by resetting task alphas and scales, etc.
windowAnimEndListener = mReapplyStateListener; windowAnimEndListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mLauncher.getStateManager().moveToRestState();
mLauncher.getStateManager().reapplyState();
}
};
} else { } else {
AnimatorPlaybackController controller = AnimatorPlaybackController controller =
mLauncher.getStateManager() mLauncher.getStateManager()

View File

@ -63,6 +63,7 @@ public class QuickScrubController implements OnAlarmListener {
private final BaseActivity mActivity; private final BaseActivity mActivity;
private boolean mInQuickScrub; private boolean mInQuickScrub;
private boolean mWaitingForTaskLaunch;
private int mQuickScrubSection; private int mQuickScrubSection;
private boolean mStartedFromHome; private boolean mStartedFromHome;
private boolean mFinishedTransitionToQuickScrub; private boolean mFinishedTransitionToQuickScrub;
@ -79,11 +80,11 @@ public class QuickScrubController implements OnAlarmListener {
} }
public void onQuickScrubStart(boolean startingFromHome, ActivityControlHelper controlHelper) { public void onQuickScrubStart(boolean startingFromHome, ActivityControlHelper controlHelper) {
prepareQuickScrub(TAG);
mInQuickScrub = true; mInQuickScrub = true;
mStartedFromHome = startingFromHome; mStartedFromHome = startingFromHome;
mQuickScrubSection = 0; mQuickScrubSection = 0;
mFinishedTransitionToQuickScrub = false; mFinishedTransitionToQuickScrub = false;
mOnFinishedTransitionToQuickScrubRunnable = null;
mActivityControlHelper = controlHelper; mActivityControlHelper = controlHelper;
snapToNextTaskIfAvailable(); snapToNextTaskIfAvailable();
@ -99,11 +100,17 @@ public class QuickScrubController implements OnAlarmListener {
Runnable launchTaskRunnable = () -> { Runnable launchTaskRunnable = () -> {
TaskView taskView = mRecentsView.getPageAt(page); TaskView taskView = mRecentsView.getPageAt(page);
if (taskView != null) { if (taskView != null) {
mWaitingForTaskLaunch = true;
taskView.launchTask(true, (result) -> { taskView.launchTask(true, (result) -> {
if (!result) { if (!result) {
taskView.notifyTaskLaunchFailed(TAG); taskView.notifyTaskLaunchFailed(TAG);
breakOutOfQuickScrub(); breakOutOfQuickScrub();
} else {
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(Touch.DRAGDROP,
LauncherLogProto.Action.Direction.NONE, page,
TaskUtils.getComponentKeyForTask(taskView.getTask().key));
} }
mWaitingForTaskLaunch = false;
}, taskView.getHandler()); }, taskView.getHandler());
} else { } else {
breakOutOfQuickScrub(); breakOutOfQuickScrub();
@ -123,9 +130,19 @@ public class QuickScrubController implements OnAlarmListener {
mOnFinishedTransitionToQuickScrubRunnable = launchTaskRunnable; mOnFinishedTransitionToQuickScrubRunnable = launchTaskRunnable;
} }
} }
mActivity.getUserEventDispatcher().logTaskLaunchOrDismiss(Touch.DRAGDROP, }
LauncherLogProto.Action.Direction.NONE, page,
TaskUtils.getComponentKeyForTask(mRecentsView.getPageAt(page).getTask().key)); /**
* Initializes the UI for quick scrub, returns true if success.
*/
public boolean prepareQuickScrub(String tag) {
if (mWaitingForTaskLaunch || mInQuickScrub) {
Log.d(tag, "Waiting for last scrub to finish, will skip this interaction");
return false;
}
mOnFinishedTransitionToQuickScrubRunnable = null;
mRecentsView.setNextPageSwitchRunnable(null);
return true;
} }
/** /**
@ -166,9 +183,11 @@ public class QuickScrubController implements OnAlarmListener {
public void onFinishedTransitionToQuickScrub() { public void onFinishedTransitionToQuickScrub() {
mFinishedTransitionToQuickScrub = true; mFinishedTransitionToQuickScrub = true;
if (mOnFinishedTransitionToQuickScrubRunnable != null) { Runnable action = mOnFinishedTransitionToQuickScrubRunnable;
mOnFinishedTransitionToQuickScrubRunnable.run(); // Clear the runnable before executing it, to prevent potential recursion.
mOnFinishedTransitionToQuickScrubRunnable = null; mOnFinishedTransitionToQuickScrubRunnable = null;
if (action != null) {
action.run();
} }
} }

View File

@ -349,12 +349,20 @@ public class TouchInteractionService extends Service {
return; return;
} }
if (interactionType == INTERACTION_QUICK_SCRUB) { if (interactionType == INTERACTION_QUICK_SCRUB) {
if (!mQuickScrubController.prepareQuickScrub(TAG)) {
mInvalidated = true;
return;
}
OverviewCallbacks.get(mActivity).closeAllWindows(); OverviewCallbacks.get(mActivity).closeAllWindows();
ActivityManagerWrapper.getInstance() ActivityManagerWrapper.getInstance()
.closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS); .closeSystemWindows(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
mStartPending = true; mStartPending = true;
Runnable action = () -> { Runnable action = () -> {
if (!mQuickScrubController.prepareQuickScrub(TAG)) {
mInvalidated = true;
return;
}
mActivityHelper.onQuickInteractionStart(mActivity, null, true); mActivityHelper.onQuickInteractionStart(mActivity, null, true);
mQuickScrubController.onQuickScrubProgress(mLastProgress); mQuickScrubController.onQuickScrubProgress(mLastProgress);
mStartPending = false; mStartPending = false;
@ -384,7 +392,7 @@ public class TouchInteractionService extends Service {
@Override @Override
public void onQuickScrubProgress(float progress) { public void onQuickScrubProgress(float progress) {
mLastProgress = progress; mLastProgress = progress;
if (mInvalidated || mEndPending) { if (mInvalidated || mStartPending) {
return; return;
} }
mQuickScrubController.onQuickScrubProgress(progress); mQuickScrubController.onQuickScrubProgress(progress);

View File

@ -109,6 +109,8 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private static final int STATE_CAPTURE_SCREENSHOT = 1 << 14; private static final int STATE_CAPTURE_SCREENSHOT = 1 << 14;
private static final int STATE_SCREENSHOT_CAPTURED = 1 << 15; private static final int STATE_SCREENSHOT_CAPTURED = 1 << 15;
private static final int STATE_RESUME_LAST_TASK = 1 << 16;
private static final int LAUNCHER_UI_STATES = private static final int LAUNCHER_UI_STATES =
STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE STATE_LAUNCHER_PRESENT | STATE_LAUNCHER_DRAWN | STATE_ACTIVITY_MULTIPLIER_COMPLETE
| STATE_LAUNCHER_STARTED; | STATE_LAUNCHER_STARTED;
@ -139,6 +141,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
"STATE_QUICK_SCRUB_END", "STATE_QUICK_SCRUB_END",
"STATE_CAPTURE_SCREENSHOT", "STATE_CAPTURE_SCREENSHOT",
"STATE_SCREENSHOT_CAPTURED", "STATE_SCREENSHOT_CAPTURED",
"STATE_RESUME_LAST_TASK",
}; };
public static final long MAX_SWIPE_DURATION = 350; public static final long MAX_SWIPE_DURATION = 350;
@ -187,6 +190,7 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
private boolean mGestureStarted; private boolean mGestureStarted;
private int mLogAction = Touch.SWIPE; private int mLogAction = Touch.SWIPE;
private float mCurrentQuickScrubProgress; private float mCurrentQuickScrubProgress;
private boolean mQuickScrubBlocked;
private @InteractionType int mInteractionType = INTERACTION_NORMAL; private @InteractionType int mInteractionType = INTERACTION_NORMAL;
@ -239,9 +243,12 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_APP_CONTROLLER_RECEIVED, mStateCallback.addCallback(STATE_LAUNCHER_STARTED | STATE_APP_CONTROLLER_RECEIVED,
this::sendRemoteAnimationsToAnimationFactory); this::sendRemoteAnimationsToAnimationFactory);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
| STATE_SCALED_CONTROLLER_APP, mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SCALED_CONTROLLER_APP,
this::resumeLastTaskForQuickstep);
mStateCallback.addCallback(STATE_RESUME_LAST_TASK | STATE_APP_CONTROLLER_RECEIVED,
this::resumeLastTask); this::resumeLastTask);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_APP_CONTROLLER_RECEIVED
| STATE_ACTIVITY_MULTIPLIER_COMPLETE | STATE_ACTIVITY_MULTIPLIER_COMPLETE
| STATE_CAPTURE_SCREENSHOT, | STATE_CAPTURE_SCREENSHOT,
@ -258,9 +265,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
| STATE_GESTURE_COMPLETED, | STATE_GESTURE_COMPLETED,
this::setupLauncherUiAfterSwipeUpAnimation); this::setupLauncherUiAfterSwipeUpAnimation);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_SCALED_CONTROLLER_APP,
this::reset);
mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler); mStateCallback.addCallback(STATE_HANDLER_INVALIDATED, this::invalidateHandler);
mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED, mStateCallback.addCallback(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED,
this::invalidateHandlerWithLauncher); this::invalidateHandlerWithLauncher);
@ -656,10 +660,16 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
anim.start(); anim.start();
} }
@UiThread
private void resumeLastTaskForQuickstep() {
setStateOnUiThread(STATE_RESUME_LAST_TASK);
doLogGesture(false /* toLauncher */);
reset();
}
@UiThread @UiThread
private void resumeLastTask() { private void resumeLastTask() {
mRecentsAnimationWrapper.finish(false /* toHome */, null); mRecentsAnimationWrapper.finish(false /* toHome */, null);
doLogGesture(false /* toLauncher */);
} }
public void reset() { public void reset() {
@ -760,6 +770,11 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
} }
private void onQuickScrubStart() { private void onQuickScrubStart() {
if (!mQuickScrubController.prepareQuickScrub(TAG)) {
mQuickScrubBlocked = true;
setStateOnUiThread(STATE_RESUME_LAST_TASK | STATE_HANDLER_INVALIDATED);
return;
}
if (mLauncherTransitionController != null) { if (mLauncherTransitionController != null) {
mLauncherTransitionController.getAnimationPlayer().end(); mLauncherTransitionController.getAnimationPlayer().end();
mLauncherTransitionController = null; mLauncherTransitionController = null;
@ -793,12 +808,16 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
} }
private void onFinishedTransitionToQuickScrub() { private void onFinishedTransitionToQuickScrub() {
if (mQuickScrubBlocked) {
return;
}
mQuickScrubController.onFinishedTransitionToQuickScrub(); mQuickScrubController.onFinishedTransitionToQuickScrub();
} }
public void onQuickScrubProgress(float progress) { public void onQuickScrubProgress(float progress) {
mCurrentQuickScrubProgress = progress; mCurrentQuickScrubProgress = progress;
if (Looper.myLooper() != Looper.getMainLooper() || mQuickScrubController == null) { if (Looper.myLooper() != Looper.getMainLooper() || mQuickScrubController == null
|| mQuickScrubBlocked) {
return; return;
} }
mQuickScrubController.onQuickScrubProgress(progress); mQuickScrubController.onQuickScrubProgress(progress);
@ -809,6 +828,9 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity> {
} }
private void switchToFinalAppAfterQuickScrub() { private void switchToFinalAppAfterQuickScrub() {
if (mQuickScrubBlocked) {
return;
}
mQuickScrubController.onQuickScrubEnd(); mQuickScrubController.onQuickScrubEnd();
// Normally this is handled in reset(), but since we are still scrubbing after the // Normally this is handled in reset(), but since we are still scrubbing after the