From 5db9ae400139535381a0290efe2149cc63a24fc7 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Mon, 25 Jun 2018 16:14:50 +0200 Subject: Defer stop for all activities becoming invisible If we are deferring a stop until a window is becoming visible, it's a good idea to also defer stopping all other activities that are go into stopping state to avoid flickers. Furthermore we need to fix an issue where activities weren't cleared from mActivitiesWaitingForVisibleActivity which messed up the newly introduced logic. This fixes an issue with quickstep when swiping right and the previous activity hasn't finished pausing yet when we start the new activity. In the normal case, prev=Launcher and all is fine, as we wait with stopping launcher until the animation is done. In the bad case, prev=the previous activity that was on screen before swiping, so Launcher doesn't get added to the waiting list, which means that it will be stopped too early, aborting the animation because Launcher is also driving it. Test: ActivityManagerDisplayLockedKeyguardTests Test: go/wm-smoke Test: Swipe right from Chrome to any other app, observe no jump Fixes: 80313326 Bug: 110032866 Change-Id: I39454fe218ac10ef73cc4ca23efc7c9fb3bc87ad --- services/core/java/com/android/server/am/ActivityStack.java | 10 ++++++++++ .../java/com/android/server/am/ActivityStackSupervisor.java | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index aea29ac066a3..f58f717878f1 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1654,6 +1654,16 @@ class ActivityStack extends ConfigurationContai void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed) { if (!mStackSupervisor.mStoppingActivities.contains(r)) { mStackSupervisor.mStoppingActivities.add(r); + + // Some activity is waiting for another activity to become visible before it's being + // stopped, which means that we also want to wait with stopping this one to avoid + // flickers. + if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.isEmpty() + && !mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) { + if (DEBUG_SWITCH) Slog.i(TAG_SWITCH, "adding to waiting visible activity=" + r + + " existing=" + mStackSupervisor.mActivitiesWaitingForVisibleActivity); + mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(r); + } } // If we already have a few activities waiting to stop, then give up diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index e034b824dc50..a6cd9f726bd1 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -3930,6 +3930,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D stops = new ArrayList<>(); } stops.add(s); + + // Make sure to remove it in all cases in case we entered this block with + // shouldSleepOrShutDown + mActivitiesWaitingForVisibleActivity.remove(s); mStoppingActivities.remove(activityNdx); } } -- cgit v1.2.3-59-g8ed1b