diff options
5 files changed, 57 insertions, 112 deletions
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index f70adefd7696..178359159eb6 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -564,11 +564,8 @@ final class ActivityRecord extends ConfigurationContainer { pw.print("requestedVrComponent="); pw.println(requestedVrComponent); } - final boolean waitingVisible = - mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this); - if (lastVisibleTime != 0 || waitingVisible || nowVisible) { - pw.print(prefix); pw.print("waitingVisible="); pw.print(waitingVisible); - pw.print(" nowVisible="); pw.print(nowVisible); + if (lastVisibleTime != 0 || nowVisible) { + pw.print(prefix); pw.print(" nowVisible="); pw.print(nowVisible); pw.print(" lastVisibleTime="); if (lastVisibleTime == 0) pw.print("0"); else TimeUtils.formatDuration(lastVisibleTime, now, pw); @@ -2358,27 +2355,6 @@ final class ActivityRecord extends ConfigurationContainer { if (!nowVisible) { nowVisible = true; lastVisibleTime = SystemClock.uptimeMillis(); - if (idle || mStackSupervisor.isStoppingNoHistoryActivity()) { - // If this activity was already idle or there is an activity that must be - // stopped immediately after visible, then we now need to make sure we perform - // the full stop of any activities that are waiting to do so. This is because - // we won't do that while they are still waiting for this one to become visible. - final int size = mStackSupervisor.mActivitiesWaitingForVisibleActivity.size(); - if (size > 0) { - for (int i = 0; i < size; i++) { - final ActivityRecord r = - mStackSupervisor.mActivitiesWaitingForVisibleActivity.get(i); - if (DEBUG_SWITCH) Log.v(TAG_SWITCH, "Was waiting for visible: " + r); - } - mStackSupervisor.mActivitiesWaitingForVisibleActivity.clear(); - mStackSupervisor.scheduleIdleLocked(); - } - } else { - // Instead of doing the full stop routine here, let's just hide any activities - // we now can, and let them stop when the normal idle happens. - mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */, - false /* remove */, true /* processPausingActivities */); - } mAtmService.scheduleAppGcsLocked(); } } @@ -2392,6 +2368,24 @@ final class ActivityRecord extends ConfigurationContainer { } } + void onAnimationFinished() { + if (mRootActivityContainer.allResumedActivitiesIdle() + || mStackSupervisor.isStoppingNoHistoryActivity()) { + // If all activities are already idle or there is an activity that must be + // stopped immediately after visible, then we now need to make sure we perform + // the full stop of this activity. This is because we won't do that while they are still + // waiting for the animation to finish. + if (mStackSupervisor.mStoppingActivities.contains(this)) { + mStackSupervisor.scheduleIdleLocked(); + } + } else { + // Instead of doing the full stop routine here, let's just hide any activities + // we now can, and let them stop when the normal idle happens. + mStackSupervisor.processStoppingActivitiesLocked(null /* idleActivity */, + false /* remove */, true /* processPausingActivities */); + } + } + /** * Called when the key dispatching to a window associated with the app window container * timed-out. @@ -2424,10 +2418,9 @@ final class ActivityRecord extends ConfigurationContainer { } private ActivityRecord getWaitingHistoryRecordLocked() { - // First find the real culprit... if this activity is waiting for - // another activity to start or has stopped, then the key dispatching + // First find the real culprit... if this activity has stopped, then the key dispatching // timeout should not be caused by this. - if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(this) || stopped) { + if (stopped) { final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack(); // Try to use the one which is closest to top. ActivityRecord r = stack.getResumedActivity(); diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java index 0b034b5ee334..82c0e213f12b 100644 --- a/services/core/java/com/android/server/wm/ActivityStack.java +++ b/services/core/java/com/android/server/wm/ActivityStack.java @@ -1807,10 +1807,6 @@ class ActivityStack extends ConfigurationContainer { } else if (prev.hasProcess()) { if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueue pending stop if needed: " + prev + " wasStopping=" + wasStopping + " visible=" + prev.visible); - if (mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(prev)) { - if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(TAG_PAUSE, - "Complete pause, no longer waiting: " + prev); - } if (prev.deferRelaunchUntilPaused) { // Complete the deferred relaunch that was waiting for pause to complete. if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Re-launching after pause: " + prev); @@ -1890,16 +1886,6 @@ class ActivityStack extends ConfigurationContainer { private 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 @@ -2715,7 +2701,6 @@ class ActivityStack extends ConfigurationContainer { mStackSupervisor.mStoppingActivities.remove(next); mStackSupervisor.mGoingToSleepActivities.remove(next); next.sleeping = false; - mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(next); if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Resuming " + next); @@ -2724,11 +2709,6 @@ class ActivityStack extends ConfigurationContainer { if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE, "resumeTopActivityLocked: Skip resume: some activity pausing."); - // Adding previous activity to the waiting visible list, or it would be stopped - // before top activity being visible. - if (prev != null && !next.nowVisible) { - mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev); - } return false; } @@ -2804,35 +2784,27 @@ class ActivityStack extends ConfigurationContainer { mLastNoHistoryActivity = null; } - if (prev != null && prev != next) { - if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev) - && !next.nowVisible) { - mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(prev); + if (prev != null && prev != next && next.nowVisible) { + + // The next activity is already visible, so hide the previous + // activity's windows right now so we can show the new one ASAP. + // We only do this if the previous is finishing, which should mean + // it is on top of the one being resumed so hiding it quickly + // is good. Otherwise, we want to do the normal route of allowing + // the resumed activity to be shown so we can decide if the + // previous should actually be hidden depending on whether the + // new one is found to be full-screen or not. + if (prev.finishing) { + prev.setVisibility(false); if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, - "Resuming top, waiting visible to hide: " + prev); + "Not waiting for visible to hide: " + prev + + ", nowVisible=" + next.nowVisible); } else { - // The next activity is already visible, so hide the previous - // activity's windows right now so we can show the new one ASAP. - // We only do this if the previous is finishing, which should mean - // it is on top of the one being resumed so hiding it quickly - // is good. Otherwise, we want to do the normal route of allowing - // the resumed activity to be shown so we can decide if the - // previous should actually be hidden depending on whether the - // new one is found to be full-screen or not. - if (prev.finishing) { - prev.setVisibility(false); - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, - "Not waiting for visible to hide: " + prev + ", waitingVisible=" - + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev) - + ", nowVisible=" + next.nowVisible); - } else { - if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, - "Previous already visible but still waiting to hide: " + prev - + ", waitingVisible=" - + mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(prev) - + ", nowVisible=" + next.nowVisible); - } + if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, + "Previous already visible but still waiting to hide: " + prev + + ", nowVisible=" + next.nowVisible); } + } // Launching this app's activity, make sure the app is no longer @@ -4089,9 +4061,6 @@ class ActivityStack extends ConfigurationContainer { dc.prepareAppTransition(transit, false); r.setVisibility(false); dc.executeAppTransition(); - if (!mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) { - mStackSupervisor.mActivitiesWaitingForVisibleActivity.add(r); - } } static final int FINISH_IMMEDIATELY = 0; @@ -4127,7 +4096,6 @@ class ActivityStack extends ConfigurationContainer { // make sure the record is cleaned out of other places. mStackSupervisor.mStoppingActivities.remove(r); mStackSupervisor.mGoingToSleepActivities.remove(r); - mStackSupervisor.mActivitiesWaitingForVisibleActivity.remove(r); final ActivityState prevState = r.getState(); if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to FINISHING: " + r); @@ -4733,8 +4701,6 @@ class ActivityStack extends ConfigurationContainer { "mStoppingActivities"); removeHistoryRecordsForAppLocked(mStackSupervisor.mGoingToSleepActivities, app, "mGoingToSleepActivities"); - removeHistoryRecordsForAppLocked(mStackSupervisor.mActivitiesWaitingForVisibleActivity, app, - "mActivitiesWaitingForVisibleActivity"); removeHistoryRecordsForAppLocked(mStackSupervisor.mFinishingActivities, app, "mFinishingActivities"); diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java index 758a76546c9b..d1108cc68eca 100644 --- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java @@ -267,12 +267,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { */ private final SparseIntArray mCurTaskIdForUser = new SparseIntArray(20); - /** List of activities that are waiting for a new activity to become visible before completing - * whatever operation they are supposed to do. */ - // TODO: Remove mActivitiesWaitingForVisibleActivity list and just remove activity from - // mStoppingActivities when something else comes up. - final ArrayList<ActivityRecord> mActivitiesWaitingForVisibleActivity = new ArrayList<>(); - /** List of processes waiting to find out when a specific activity becomes visible. */ private final ArrayList<WaitInfo> mWaitingForActivityVisible = new ArrayList<>(); @@ -550,7 +544,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { // This could happen, for example, if we are trimming activities // down to the max limit while they are still waiting to finish. mFinishingActivities.remove(r); - mActivitiesWaitingForVisibleActivity.remove(r); for (int i = mWaitingForActivityVisible.size() - 1; i >= 0; --i) { if (mWaitingForActivityVisible.get(i).matches(r.mActivityComponent)) { @@ -2142,28 +2135,27 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { final boolean nowVisible = mRootActivityContainer.allResumedActivitiesVisible(); for (int activityNdx = mStoppingActivities.size() - 1; activityNdx >= 0; --activityNdx) { ActivityRecord s = mStoppingActivities.get(activityNdx); - boolean waitingVisible = mActivitiesWaitingForVisibleActivity.contains(s); + + final boolean animating = s.mAppWindowToken.isSelfAnimating(); + if (DEBUG_STATES) Slog.v(TAG, "Stopping " + s + ": nowVisible=" + nowVisible - + " waitingVisible=" + waitingVisible + " finishing=" + s.finishing); - if (waitingVisible && nowVisible) { - mActivitiesWaitingForVisibleActivity.remove(s); - waitingVisible = false; - if (s.finishing) { - // If this activity is finishing, it is sitting on top of - // everyone else but we now know it is no longer needed... - // so get rid of it. Otherwise, we need to go through the - // normal flow and hide it once we determine that it is - // hidden by the activities in front of it. - if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); - s.setVisibility(false); - } + + " animating=" + animating + " finishing=" + s.finishing); + if (nowVisible && s.finishing) { + + // If this activity is finishing, it is sitting on top of + // everyone else but we now know it is no longer needed... + // so get rid of it. Otherwise, we need to go through the + // normal flow and hide it once we determine that it is + // hidden by the activities in front of it. + if (DEBUG_STATES) Slog.v(TAG, "Before stopping, can hide: " + s); + s.setVisibility(false); } if (remove) { final ActivityStack stack = s.getActivityStack(); final boolean shouldSleepOrShutDown = stack != null ? stack.shouldSleepOrShutDownActivities() : mService.isSleepingOrShuttingDownLocked(); - if (!waitingVisible || shouldSleepOrShutDown) { + if (!animating || shouldSleepOrShutDown) { if (!processPausingActivities && s.isState(PAUSING)) { // Defer processing pausing activities in this iteration and reschedule // a delayed idle to reprocess it again @@ -2178,9 +2170,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks { } 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); } } diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java index 78199d4412a6..220370c0859c 100644 --- a/services/core/java/com/android/server/wm/AppWindowToken.java +++ b/services/core/java/com/android/server/wm/AppWindowToken.java @@ -2784,6 +2784,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree getDisplayContent().mAppTransition.notifyAppTransitionFinishedLocked(token); scheduleAnimation(); + + mActivityRecord.onAnimationFinished(); } @Override diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java index e3beb19408e1..e59b6d743c52 100644 --- a/services/core/java/com/android/server/wm/RootActivityContainer.java +++ b/services/core/java/com/android/server/wm/RootActivityContainer.java @@ -2016,8 +2016,7 @@ class RootActivityContainer extends ConfigurationContainer final ActivityStack stack = display.getChildAt(stackNdx); final ActivityRecord r = stack.getResumedActivity(); if (r != null) { - if (!r.nowVisible - || mStackSupervisor.mActivitiesWaitingForVisibleActivity.contains(r)) { + if (!r.nowVisible) { return false; } foundResumed = true; @@ -2345,10 +2344,6 @@ class RootActivityContainer extends ConfigurationContainer printed |= dumpHistoryList(fd, pw, mStackSupervisor.mStoppingActivities, " ", "Stop", false, !dumpAll, false, dumpPackage, true, " Activities waiting to stop:", null); - printed |= dumpHistoryList(fd, pw, - mStackSupervisor.mActivitiesWaitingForVisibleActivity, " ", "Wait", - false, !dumpAll, false, dumpPackage, true, - " Activities waiting for another to become visible:", null); printed |= dumpHistoryList(fd, pw, mStackSupervisor.mGoingToSleepActivities, " ", "Sleep", false, !dumpAll, false, dumpPackage, true, " Activities waiting to sleep:", null); |