Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b9ee4f44 authored by Dianne Hackborn's avatar Dianne Hackborn Committed by Android (Google) Code Review
Browse files

Merge "Revert "Don't wait for current activity to pause before resuming next.""

parents 30e2fbe0 621e2fec
Loading
Loading
Loading
Loading
+11 −17
Original line number Diff line number Diff line
@@ -138,7 +138,6 @@ import java.io.StringWriter;
import java.lang.IllegalStateException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -2752,7 +2751,13 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
        // Just in case...
        mMainStack.appDiedLocked(app);
        if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
            if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
            mMainStack.mPausingActivity = null;
        }
        if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
            mMainStack.mLastPausedActivity = null;
        }
        // Remove this application's activities from active lists.
        mMainStack.removeHistoryRecordsForAppLocked(app);
@@ -6488,7 +6493,7 @@ public final class ActivityManagerService extends ActivityManagerNative
                mMainStack.stopIfSleepingLocked();
                final long endTime = System.currentTimeMillis() + timeout;
                while (mMainStack.mResumedActivity != null
                        || mMainStack.mPausingActivities.size() > 0) {
                        || mMainStack.mPausingActivity != null) {
                    long delay = endTime - System.currentTimeMillis();
                    if (delay <= 0) {
                        Slog.w(TAG, "Activity manager shutdown timed out");
@@ -8295,13 +8300,8 @@ public final class ActivityManagerService extends ActivityManagerNative
        }
        pw.println(" ");
        if (mMainStack.mPausingActivities.size() > 0) {
            pw.println("  mPausingActivities: " + Arrays.toString(
                    mMainStack.mPausingActivities.toArray()));
        }
        if (mMainStack.mInputPausedActivities.size() > 0) {
            pw.println("  mInputPausedActivities: " + Arrays.toString(
                    mMainStack.mInputPausedActivities.toArray()));
        if (mMainStack.mPausingActivity != null) {
            pw.println("  mPausingActivity: " + mMainStack.mPausingActivity);
        }
        pw.println("  mResumedActivity: " + mMainStack.mResumedActivity);
        pw.println("  mFocusedActivity: " + mFocusedActivity);
@@ -13876,13 +13876,7 @@ public final class ActivityManagerService extends ActivityManagerNative
    private final ActivityRecord resumedAppLocked() {
        ActivityRecord resumedActivity = mMainStack.mResumedActivity;
        if (resumedActivity == null || resumedActivity.app == null) {
            for (int i=mMainStack.mPausingActivities.size()-1; i>=0; i--) {
                ActivityRecord r = mMainStack.mPausingActivities.get(i);
                if (r.app != null) {
                    resumedActivity = r;
                    break;
                }
            }
            resumedActivity = mMainStack.mPausingActivity;
            if (resumedActivity == null || resumedActivity.app == null) {
                resumedActivity = mMainStack.topRunningActivityLocked(null);
            }
+1 −4
Original line number Diff line number Diff line
@@ -602,7 +602,6 @@ final class ActivityRecord {
    
    public void windowsDrawn() {
        synchronized(service) {
            stack.reportActivityDrawnLocked(this);
            if (launchTime != 0) {
                final long curTime = SystemClock.uptimeMillis();
                final long thisTime = curTime - launchTime;
@@ -691,9 +690,7 @@ final class ActivityRecord {
            // Hmmm, who might we be waiting for?
            r = stack.mResumedActivity;
            if (r == null) {
                if (stack.mPausingActivities.size() > 0) {
                    r = stack.mPausingActivities.get(stack.mPausingActivities.size()-1);
                }
                r = stack.mPausingActivity;
            }
            // Both of those null?  Fall back to 'this' again
            if (r == null) {
+76 −118
Original line number Diff line number Diff line
@@ -227,13 +227,7 @@ final class ActivityStack {
     * When we are in the process of pausing an activity, before starting the
     * next one, this variable holds the activity that is currently being paused.
     */
    final ArrayList<ActivityRecord> mPausingActivities = new ArrayList<ActivityRecord>();

    /**
     * These activities currently have their input paused, as they want for
     * the next top activity to have its windows visible.
     */
    final ArrayList<ActivityRecord> mInputPausedActivities = new ArrayList<ActivityRecord>();
    ActivityRecord mPausingActivity = null;

    /**
     * This is the last activity that we put into the paused state.  This is
@@ -813,9 +807,9 @@ final class ActivityStack {
                startPausingLocked(false, true);
                return;
            }
            if (mPausingActivities.size() > 0) {
            if (mPausingActivity != null) {
                // Still waiting for something to pause; can't sleep yet.
                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still waiting to pause " + mPausingActivities);
                if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still waiting to pause " + mPausingActivity);
                return;
            }

@@ -878,6 +872,11 @@ final class ActivityStack {
    }

    private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
        if (mPausingActivity != null) {
            RuntimeException e = new RuntimeException();
            Slog.e(TAG, "Trying to pause when pause is already pending for "
                  + mPausingActivity, e);
        }
        ActivityRecord prev = mResumedActivity;
        if (prev == null) {
            RuntimeException e = new RuntimeException();
@@ -885,25 +884,19 @@ final class ActivityStack {
            resumeTopActivityLocked(null);
            return;
        }
        if (mPausingActivities.contains(prev)) {
            RuntimeException e = new RuntimeException();
            Slog.e(TAG, "Trying to pause when pause when already pausing " + prev, e);
        }
        if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
        else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
        mResumedActivity = null;
        mPausingActivities.add(prev);
        mPausingActivity = prev;
        mLastPausedActivity = prev;
        prev.state = ActivityState.PAUSING;
        prev.task.touchActiveTime();
        prev.updateThumbnail(screenshotActivities(prev), null);

        mService.updateCpuStats();
        ActivityRecord pausing;
        
        if (prev.app != null && prev.app.thread != null) {
            if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
            pausing = prev;
            try {
                EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
                        System.identityHashCode(prev),
@@ -916,14 +909,12 @@ final class ActivityStack {
            } catch (Exception e) {
                // Ignore exception, if process died other code will cleanup.
                Slog.w(TAG, "Exception thrown during pause", e);
                mPausingActivities.remove(prev);
                mPausingActivity = null;
                mLastPausedActivity = null;
                pausing = null;
            }
        } else {
            mPausingActivities.remove(prev);
            mPausingActivity = null;
            mLastPausedActivity = null;
            pausing = null;
        }

        // If we are not going to sleep, we want to ensure the device is
@@ -937,28 +928,18 @@ final class ActivityStack {
            }
        }

        if (pausing != null) {

        if (mPausingActivity != null) {
            // Have the window manager pause its key dispatching until the new
            // activity has started.  If we're pausing the activity just because
            // the screen is being turned off and the UI is sleeping, don't interrupt
            // key dispatch; the same activity will pick it up again on wakeup.
            if (!uiSleeping) {
                pausing.pauseKeyDispatchingLocked();
                mInputPausedActivities.add(prev);
                prev.pauseKeyDispatchingLocked();
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off");
            }

            if (pausing.configDestroy) {
                // The previous is being paused because the configuration
                // is changing, which means it is actually stopping...
                // To juggle the fact that we are also starting a new
                // instance right now, we need to first completely stop
                // the current instance before starting the new one.
                if (DEBUG_PAUSE) Slog.v(TAG, "Destroying at pause: " + prev);
                destroyActivityLocked(pausing, true, false, "pause-config");
            }

            // Schedule a pause timeout in case the app doesn't respond.
            // We don't give it much time because this directly impacts the
            // responsiveness seen by the user.
@@ -970,10 +951,7 @@ final class ActivityStack {
            // This activity failed to schedule the
            // pause, so just treat it as being paused now.
            if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
        }

        if (!mService.isSleeping()) {
            resumeTopActivityLocked(pausing);
            resumeTopActivityLocked(null);
        }
    }
    
@@ -988,17 +966,16 @@ final class ActivityStack {
            if (index >= 0) {
                r = mHistory.get(index);
                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
                if (mPausingActivities.contains(r)) {
                if (mPausingActivity == r) {
                    if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
                            + (timeout ? " (due to timeout)" : " (pause complete)"));
                    r.state = ActivityState.PAUSED;
                    completePauseLocked(r);
                    completePauseLocked();
                } else {
                    ActivityRecord old = mPausingActivities.size() > 0
                            ? mPausingActivities.get(0) : null;
                    EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                            System.identityHashCode(r), r.shortComponentName, 
                            old != null ? old.shortComponentName : "(none)");
                            mPausingActivity != null
                                ? mPausingActivity.shortComponentName : "(none)");
                }
            }
        }
@@ -1024,14 +1001,8 @@ final class ActivityStack {
                ProcessRecord fgApp = null;
                if (mResumedActivity != null) {
                    fgApp = mResumedActivity.app;
                } else {
                    for (int i=mPausingActivities.size()-1; i>=0; i--) {
                        ActivityRecord pausing = mPausingActivities.get(i);
                        if (pausing.app == r.app) {
                            fgApp = pausing.app;
                            break;
                        }
                    }
                } else if (mPausingActivity != null) {
                    fgApp = mPausingActivity.app;
                }
                if (r.app != null && fgApp != null && r.app != fgApp
                        && r.lastVisibleTime > mService.mPreviousProcessVisibleTime
@@ -1043,9 +1014,11 @@ final class ActivityStack {
        }
    }

    private final void completePauseLocked(ActivityRecord prev) {
    private final void completePauseLocked() {
        ActivityRecord prev = mPausingActivity;
        if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
        
        if (prev != null) {
            if (prev.finishing) {
                if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
                prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
@@ -1081,12 +1054,19 @@ final class ActivityStack {
                if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);
                prev = null;
            }
        mPausingActivities.remove(prev);
            mPausingActivity = null;
        }

        if (mService.isSleeping()) {
        if (!mService.isSleeping()) {
            resumeTopActivityLocked(prev);
        } else {
            checkReadyForSleepLocked();
        }
        
        if (prev != null) {
            prev.resumeKeyDispatchingLocked();
        }

        if (prev.app != null && prev.cpuTimeAtResume > 0
                && mService.mBatteryStatsService.isOnBattery()) {
            long diff = 0;
@@ -1142,9 +1122,7 @@ final class ActivityStack {
        if (mMainStack) {
            mService.setFocusedActivityLocked(next);
        }
        if (mInputPausedActivities.remove(next)) {
        next.resumeKeyDispatchingLocked();
        }
        ensureActivitiesVisibleLocked(null, 0);
        mService.mWindowManager.executeAppTransition();
        mNoAnimActivities.clear();
@@ -1374,6 +1352,13 @@ final class ActivityStack {

        if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);

        // If we are currently pausing an activity, then don't do anything
        // until that is done.
        if (mPausingActivity != null) {
            if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity);
            return false;
        }

        // Okay we are now going to start a switch, to 'next'.  We may first
        // have to pause the current activity, but this is an important point
        // where we have decided to go to 'next' so keep track of that.
@@ -2455,7 +2440,7 @@ final class ActivityStack {
        
        err = startActivityUncheckedLocked(r, sourceRecord,
                grantedUriPermissions, grantedMode, onlyIfNeeded, true);
        if (mDismissKeyguardOnNextActivity && mPausingActivities.size() == 0) {
        if (mDismissKeyguardOnNextActivity && mPausingActivity == null) {
            // Someone asked to have the keyguard dismissed on the next
            // activity start, but we are not actually doing an activity
            // switch...  just dismiss the keyguard now, because we
@@ -3127,17 +3112,6 @@ final class ActivityStack {
        mService.notifyAll();
    }
    
    void reportActivityDrawnLocked(ActivityRecord r) {
        if (mResumedActivity == r) {
            // Once the resumed activity has been drawn, we can stop
            // pausing input on all other activities.
            for (int i=mInputPausedActivities.size()-1; i>=0; i--) {
                mInputPausedActivities.get(i).resumeKeyDispatchingLocked();
            }
            mInputPausedActivities.clear();
        }
    }

    void reportActivityVisibleLocked(ActivityRecord r) {
        for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) {
            WaitResult w = mWaitingActivityVisible.get(i);
@@ -3196,9 +3170,7 @@ final class ActivityStack {
                    mService.setFocusedActivityLocked(topRunningActivityLocked(null));
                }
            }
            if (mInputPausedActivities.remove(r)) {
            r.resumeKeyDispatchingLocked();
            }
            try {
                r.stopped = false;
                if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPING: " + r
@@ -3524,7 +3496,7 @@ final class ActivityStack {
            // Tell window manager to prepare for this one to be removed.
            mService.mWindowManager.setAppVisibility(r.appToken, false);
                
            if (!mPausingActivities.contains(r)) {
            if (mPausingActivity == null) {
                if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r);
                if (DEBUG_USER_LEAVING) Slog.v(TAG, "finish() => pause with userLeaving=false");
                startPausingLocked(false, false);
@@ -3608,20 +3580,6 @@ final class ActivityStack {
        return r;
    }

    final void appDiedLocked(ProcessRecord app) {
        for (int i=mPausingActivities.size()-1; i>=0; i--) {
            ActivityRecord r = mPausingActivities.get(i);
            if (r.app == app) {
                if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " + r);
                mPausingActivities.remove(i);
                mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
            }
        }
        if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
            mLastPausedActivity = null;
        }
    }

    /**
     * Perform the common clean-up of an activity record.  This is called both
     * as part of destroyActivityLocked() (when destroying the client-side