From c57b7f6e966f014db65372b3a10ef69e37ec89f5 Mon Sep 17 00:00:00 2001 From: Matthew Ng Date: Thu, 10 Aug 2017 15:37:19 -0700 Subject: Fixes quick switch animations for low end devices Currently using quick switch is fine but sometimes with animation glitches but very reproducible if tapping recents button very fast. The problem is that low end device Recents entrance animation also has the previous tasks animating downward causing more chances of animation instability. The problem is that transition is not finished and it is already starting to do the next toggled animation. When the transition from app to recents (RecentsImpl.toggleRecents) starts without finishing RecentsActivity.onStop, the previous frame will be visible for a couple of frames before the entrance animation starts (having the previous task animate down). Therefore restrict toggling to after RecentsActivity.onStop would allow the previous frame to finish and the transitions run normally. Bug: 62251652 Fixes: 64401391 Test: manual - using gobo device, launch multiple apps, rapidly tap recents button Change-Id: I4e70434bca3c9bec287fa30559b23a1e71b5ef20 --- .../src/com/android/systemui/recents/RecentsActivity.java | 1 + .../src/com/android/systemui/recents/RecentsImpl.java | 15 +++++++++++---- .../systemui/recents/views/RecentsTransitionHelper.java | 12 ++++++++---- .../systemui/recents/views/TaskStackAnimationHelper.java | 12 +++++++++++- 4 files changed, 31 insertions(+), 9 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index c0550b5c52e6..21b65f00a52c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -69,6 +69,7 @@ import com.android.systemui.recents.events.activity.ToggleRecentsEvent; import com.android.systemui.recents.events.component.ActivityUnpinnedEvent; import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent; import com.android.systemui.recents.events.component.ScreenPinningRequestEvent; +import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent; import com.android.systemui.recents.events.ui.AllTaskViewsDismissedEvent; import com.android.systemui.recents.events.ui.DeleteTaskDataEvent; import com.android.systemui.recents.events.ui.HideIncompatibleAppOverlayEvent; diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java index 86e93fdd63ad..1b8614313809 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java @@ -24,6 +24,7 @@ import static android.view.View.MeasureSpec; import android.app.ActivityManager; import android.app.ActivityManager.TaskSnapshot; import android.app.ActivityOptions; +import android.app.ActivityOptions.OnAnimationFinishedListener; import android.app.ActivityOptions.OnAnimationStartedListener; import android.content.ActivityNotFoundException; import android.content.Context; @@ -663,7 +664,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener mWaitingForTransitionStart = waitingForTransitionStart; if (!waitingForTransitionStart && mToggleFollowingTransitionStart) { - toggleRecents(DividerView.INVALID_RECENTS_GROW_TARGET); + mHandler.post(() -> toggleRecents(DividerView.INVALID_RECENTS_GROW_TARGET)); } mToggleFollowingTransitionStart = false; } @@ -866,6 +867,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener private Pair getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo runningTask, Rect windowOverrideRect) { + final boolean isLowRamDevice = Recents.getConfiguration().isLowRamDevice; if (runningTask != null && runningTask.stackId == FREEFORM_WORKSPACE_STACK_ID) { ArrayList specs = new ArrayList<>(); ArrayList tasks; @@ -896,8 +898,11 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener AppTransitionAnimationSpec[] specsArray = new AppTransitionAnimationSpec[specs.size()]; specs.toArray(specsArray); + // For low end ram devices, wait for transition flag is reset when Recents entrance + // animation is complete instead of when the transition animation starts return new Pair<>(ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView, - specsArray, mHandler, mResetToggleFlagListener, this), null); + specsArray, mHandler, isLowRamDevice ? null : mResetToggleFlagListener, this), + null); } else { // Update the destination rect Task toTask = new Task(); @@ -916,9 +921,11 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener toTask.key.id, thumbnail, rect)); }); + // For low end ram devices, wait for transition flag is reset when Recents entrance + // animation is complete instead of when the transition animation starts return new Pair<>(ActivityOptions.makeMultiThumbFutureAspectScaleAnimation(mContext, - mHandler, future.getFuture(), mResetToggleFlagListener, false /* scaleUp */), - future); + mHandler, future.getFuture(), isLowRamDevice ? null : mResetToggleFlagListener, + false /* scaleUp */), future); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java index 127822aec6df..b2675d7ac858 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java @@ -140,8 +140,10 @@ public class RecentsTransitionHelper { mHandler.postDelayed(mStartScreenPinningRunnable, 350); } - // Reset the state where we are waiting for the transition to start - EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false)); + if (!Recents.getConfiguration().isLowRamDevice) { + // Reset the state where we are waiting for the transition to start + EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false)); + } } }; } else { @@ -163,8 +165,10 @@ public class RecentsTransitionHelper { EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent()); stackView.cancelAllTaskViewAnimations(); - // Reset the state where we are waiting for the transition to start - EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false)); + if (!Recents.getConfiguration().isLowRamDevice) { + // Reset the state where we are waiting for the transition to start + EventBus.getDefault().send(new SetWaitingForTransitionStartEvent(false)); + } } }; } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java index 6e57044467bb..81bf6affc94a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java @@ -34,6 +34,8 @@ import com.android.systemui.recents.Recents; import com.android.systemui.recents.RecentsActivityLaunchState; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.RecentsDebugFlags; +import com.android.systemui.recents.events.EventBus; +import com.android.systemui.recents.events.component.SetWaitingForTransitionStartEvent; import com.android.systemui.recents.misc.ReferenceCountedTrigger; import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.TaskStack; @@ -241,6 +243,7 @@ public class TaskStackAnimationHelper { return; } + final boolean isLowRamDevice = Recents.getConfiguration().isLowRamDevice; int taskViewEnterFromAppDuration = res.getInteger( R.integer.recents_task_enter_from_app_duration); int taskViewEnterFromAffiliatedAppDuration = res.getInteger( @@ -248,6 +251,13 @@ public class TaskStackAnimationHelper { int dockGestureAnimDuration = appRes.getInteger( R.integer.long_press_dock_anim_duration); + // Since low ram devices have an animation when entering app -> recents, do not allow + // toggle until the animation is complete + if (launchState.launchedFromApp && !launchState.launchedViaDockGesture && isLowRamDevice) { + postAnimationTrigger.addLastDecrementRunnable(() -> EventBus.getDefault() + .send(new SetWaitingForTransitionStartEvent(false))); + } + // Create enter animations for each of the views from front to back List taskViews = mStackView.getTaskViews(); int taskViewCount = taskViews.size(); @@ -296,7 +306,7 @@ public class TaskStackAnimationHelper { AnimationProps taskAnimation = new AnimationProps() .setInterpolator(AnimationProps.ALPHA, ENTER_FROM_HOME_ALPHA_INTERPOLATOR) .setListener(postAnimationTrigger.decrementOnAnimationEnd()); - if (Recents.getConfiguration().isLowRamDevice) { + if (isLowRamDevice) { taskAnimation.setInterpolator(AnimationProps.BOUNDS, Interpolators.FAST_OUT_SLOW_IN) .setDuration(AnimationProps.BOUNDS, 150) -- cgit v1.2.3-59-g8ed1b