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

Commit 5658e4b9 authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Don't resume activity on start if there are activities pausing.

The path to start an activity if it isn't running was unconditionally
resuming the starting activity which we don't do if there are activities
pausing. It now starts the activity in a paused state if other activities
are pausing. It is then resumed when pause completes.

Also, improved logging in BoundsAnimationController and removed some
disabled code that has been in the codebase for 6yrs...

Bug: 26982752
Change-Id: Ie042fc938331127f1270fca1b5905b067b9dae7c
parent 5393a660
Loading
Loading
Loading
Loading
+13 −39
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
import static android.content.pm.ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;

import static android.content.res.Configuration.SCREENLAYOUT_UNDEFINED;
@@ -766,8 +767,8 @@ final class ActivityStack {

    void minimalResumeActivityLocked(ActivityRecord r) {
        r.state = ActivityState.RESUMED;
        if (DEBUG_STATES) Slog.v(TAG_STATES,
                "Moving to RESUMED: " + r + " (starting new instance)");
        if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to RESUMED: " + r + " (starting new instance)"
                + " callers=" + Debug.getCallers(5));
        mResumedActivity = r;
        r.task.touchActiveTime();
        mRecentTasks.addLocked(r.task);
@@ -1054,6 +1055,7 @@ final class ActivityStack {
                if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to PAUSED: " + r
                        + (timeout ? " (due to timeout)" : " (pause complete)"));
                completePauseLocked(true);
                return;
            } else {
                EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
                        r.userId, System.identityHashCode(r), r.shortComponentName,
@@ -1069,6 +1071,7 @@ final class ActivityStack {
                }
            }
        }
        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }

    final void activityStoppedLocked(ActivityRecord r, Bundle icicle,
@@ -1198,12 +1201,13 @@ final class ActivityStack {
            prev.cpuTimeAtResume = 0; // reset it
        }

        // Notify when the task stack has changed, but only if visibilities changed (not just
        // focus).
        // Notify when the task stack has changed, but only if visibilities changed (not just focus)
        if (mStackSupervisor.mAppVisibilitiesChangedSinceLastPause) {
            mService.notifyTaskStackChangedLocked();
            mStackSupervisor.mAppVisibilitiesChangedSinceLastPause = false;
        }

        mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
    }

    private void addToStopping(ActivityRecord r) {
@@ -2005,8 +2009,7 @@ final class ActivityStack {

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

        // If we are currently pausing an activity, then don't do anything
        // until that is done.
        // If we are currently pausing an activity, then don't do anything until that is done.
        if (!mStackSupervisor.allPausedActivitiesComplete()) {
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "resumeTopActivityLocked: Skip resume: some activity pausing.");
@@ -2014,40 +2017,10 @@ final class ActivityStack {
            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.
        // XXX "App Redirected" dialog is getting too many false positives
        // at this point, so turn off for now.
        if (false) {
            if (mLastStartedActivity != null && !mLastStartedActivity.finishing) {
                long now = SystemClock.uptimeMillis();
                final boolean inTime = mLastStartedActivity.startTime != 0
                        && (mLastStartedActivity.startTime + START_WARN_TIME) >= now;
                final int lastUid = mLastStartedActivity.info.applicationInfo.uid;
                final int nextUid = next.info.applicationInfo.uid;
                if (inTime && lastUid != nextUid
                        && lastUid != next.launchedFromUid
                        && mService.checkPermission(
                                android.Manifest.permission.STOP_APP_SWITCHES,
                                -1, next.launchedFromUid)
                        != PackageManager.PERMISSION_GRANTED) {
                    mService.showLaunchWarningLocked(mLastStartedActivity, next);
                } else {
                    next.startTime = now;
                    mLastStartedActivity = next;
                }
            } else {
                next.startTime = SystemClock.uptimeMillis();
                mLastStartedActivity = next;
            }
        }

        mStackSupervisor.setLaunchSource(next.info.applicationInfo.uid);

        // We need to start pausing the current activity so the top one
        // can be resumed...
        boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
        // We need to start pausing the current activity so the top one can be resumed...
        final boolean dontWaitForPause = (next.info.flags & FLAG_RESUME_WHILE_PAUSING) != 0;
        boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
        if (mResumedActivity != null) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
@@ -4425,7 +4398,8 @@ final class ActivityStack {

        try {
            if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_SWITCH,
                    "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r);
                    "Moving to " + (andResume ? "RESUMED" : "PAUSED") + " Relaunching " + r
                    + " callers=" + Debug.getCallers(6));
            r.forceNewConfig = false;
            r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents, changes,
                    !andResume, new Configuration(mService.mConfiguration),
+13 −4
Original line number Diff line number Diff line
@@ -1065,9 +1065,18 @@ public final class ActivityStackSupervisor implements DisplayListener {
        return resolveActivity(intent, rInfo, startFlags, profilerInfo);
    }

    final boolean realStartActivityLocked(ActivityRecord r,
            ProcessRecord app, boolean andResume, boolean checkConfig)
            throws RemoteException {
    final boolean realStartActivityLocked(ActivityRecord r, ProcessRecord app,
            boolean andResume, boolean checkConfig) throws RemoteException {

        if (!allPausedActivitiesComplete()) {
            // While there are activities pausing we skipping starting any new activities until
            // pauses are complete. NOTE: that we also do this for activities that are starting in
            // the paused state because they will first be resumed then paused on the client side.
            if (DEBUG_SWITCH || DEBUG_PAUSE || DEBUG_STATES) Slog.v(TAG_PAUSE,
                    "realStartActivityLocked: Skipping start of r=" + r
                    + " some activities pausing...");
            return false;
        }

        if (andResume) {
            r.startFreezingScreenLocked(app, 0);
@@ -2263,7 +2272,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
        boolean kept = true;
        try {
            final ActivityStack stack = moveTaskToStackUncheckedLocked(
                    task, stackId, toTop, forceFocus, "moveTaskToStack:" + reason);
                    task, stackId, toTop, forceFocus, reason + " moveTaskToStack");
            stackId = stack.mStackId;

            if (!animate) {
+31 −4
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.graphics.Rect;
import android.os.Debug;
import android.util.ArrayMap;
import android.util.Slog;
import android.view.animation.LinearInterpolator;
@@ -39,7 +40,10 @@ import android.view.animation.LinearInterpolator;
 * The object that is resized needs to implement {@link AnimateBoundsUser} interface.
 */
public class BoundsAnimationController {
    private static final String TAG = TAG_WITH_CLASS_NAME ? "BoundsAnimationController" : TAG_WM;
    private static final boolean DEBUG_LOCAL = false;
    private static final boolean DEBUG = DEBUG_LOCAL || DEBUG_ANIM;
    private static final String TAG = TAG_WITH_CLASS_NAME || DEBUG_LOCAL
            ? "BoundsAnimationController" : TAG_WM;
    private static final int DEBUG_ANIMATION_SLOW_DOWN_FACTOR = 1;

    // Only accessed on UI thread.
@@ -80,9 +84,9 @@ public class BoundsAnimationController {
            mTmpRect.top = (int) (mFrom.top * remains + mTo.top * value + 0.5f);
            mTmpRect.right = (int) (mFrom.right * remains + mTo.right * value + 0.5f);
            mTmpRect.bottom = (int) (mFrom.bottom * remains + mTo.bottom * value + 0.5f);
            if (DEBUG_ANIM) Slog.d(TAG, "animateUpdate: mTarget=" + mTarget + ", mBounds="
                    + mTmpRect + ", from=" + mFrom + ", mTo=" + mTo + ", value=" + value
                    + ", remains=" + remains);
            if (DEBUG) Slog.d(TAG, "animateUpdate: mTarget=" + mTarget + " mBounds="
                    + mTmpRect + " from=" + mFrom + " mTo=" + mTo + " value=" + value
                    + " remains=" + remains);
            if (!mTarget.setSize(mTmpRect)) {
                // Whoops, the target doesn't feel like animating anymore. Let's immediately finish
                // any further animation.
@@ -93,6 +97,8 @@ public class BoundsAnimationController {

        @Override
        public void onAnimationStart(Animator animation) {
            if (DEBUG) Slog.d(TAG, "onAnimationStart: mTarget=" + mTarget
                    + " mReplacement=" + mReplacement);
            if (!mReplacement) {
                mTarget.onAnimationStart();
            }
@@ -100,6 +106,8 @@ public class BoundsAnimationController {

        @Override
        public void onAnimationEnd(Animator animation) {
            if (DEBUG) Slog.d(TAG, "onAnimationEnd: mTarget=" + mTarget
                    + " mMoveToFullScreen=" + mMoveToFullScreen + " mWillReplace=" + mWillReplace);
            finishAnimation();
            if (mMoveToFullScreen && !mWillReplace) {
                mTarget.moveToFullscreen();
@@ -114,10 +122,18 @@ public class BoundsAnimationController {
        @Override
        public void cancel() {
            mWillReplace = true;
            if (DEBUG) Slog.d(TAG, "cancel: willReplace mTarget=" + mTarget);
            super.cancel();
        }

        /** Returns true if the animation target is the same as the input bounds. */
        public boolean isAnimatingTo(Rect bounds) {
            return mTo.equals(bounds);
        }

        private void finishAnimation() {
            if (DEBUG) Slog.d(TAG, "finishAnimation: mTarget=" + mTarget
                    + " callers" + Debug.getCallers(2));
            if (!mWillReplace) {
                mTarget.onAnimationEnd();
            }
@@ -167,7 +183,18 @@ public class BoundsAnimationController {

        final BoundsAnimator existing = mRunningAnimations.get(target);
        final boolean replacing = existing != null;

        if (DEBUG) Slog.d(TAG, "animateBounds: target=" + target + " from=" + from + " to=" + to
                + " moveToFullscreen=" + moveToFullscreen + " replacing=" + replacing);

        if (replacing) {
            if (existing.isAnimatingTo(to)) {
                // Just les the current animation complete if it has the same destination as the
                // one we are trying to start.
                if (DEBUG) Slog.d(TAG, "animateBounds: same destination as existing=" + existing
                        + " ignoring...");
                return;
            }
            existing.cancel();
        }
        final BoundsAnimator animator =