OSDN Git Service

Fixes quick switch animations for low end devices
authorMatthew Ng <ngmatthew@google.com>
Thu, 10 Aug 2017 22:37:19 +0000 (15:37 -0700)
committerMatthew Ng <ngmatthew@google.com>
Tue, 15 Aug 2017 21:59:43 +0000 (14:59 -0700)
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

packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java
packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java
packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java

index c0550b5..21b65f0 100644 (file)
@@ -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;
index 86e93fd..1b86143 100644 (file)
@@ -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<ActivityOptions, AppTransitionAnimationSpecsFuture>
             getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo runningTask,
                     Rect windowOverrideRect) {
+        final boolean isLowRamDevice = Recents.getConfiguration().isLowRamDevice;
         if (runningTask != null && runningTask.stackId == FREEFORM_WORKSPACE_STACK_ID) {
             ArrayList<AppTransitionAnimationSpec> specs = new ArrayList<>();
             ArrayList<Task> 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);
         }
     }
 
index 127822a..b2675d7 100644 (file)
@@ -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));
+                    }
                 }
             };
         }
index 6e57044..81bf6af 100644 (file)
@@ -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<TaskView> 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)