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

Commit dfbf9716 authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Don't throw exception for duplicate resume

A double resume request is possible when an activity receives two
consequent transactions with relaunch requests and the second is one
is omitted. We still get two resume requests for the final state.

Fixes: 74074327
Test: FrameworksCoreTests:ActivityThreadTest
Change-Id: I8bb8594948a17b7fbf595a49026ff33b54b66049
parent 1e36211a
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -124,6 +124,7 @@ import android.widget.Toast;
import android.widget.Toolbar;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.app.ToolbarActionBar;
import com.android.internal.app.WindowDecorActionBar;
@@ -7110,6 +7111,12 @@ public class Activity extends ContextThemeWrapper
        return mParent != null ? mParent.getActivityToken() : mToken;
    }

    /** @hide */
    @VisibleForTesting
    public final ActivityThread getActivityThread() {
        return mMainThread;
    }

    final void performCreate(Bundle icicle) {
        performCreate(icicle, null);
    }
+17 −6
Original line number Diff line number Diff line
@@ -3722,16 +3722,27 @@ public final class ActivityThread extends ClientTransactionHandler {
        //Slog.i(TAG, "Running services: " + mServices);
    }

    ActivityClientRecord performResumeActivity(IBinder token, boolean clearHide, String reason) {
    ActivityClientRecord performResumeActivity(IBinder token, boolean finalStateRequest,
            String reason) {
        ActivityClientRecord r = mActivities.get(token);
        if (localLOGV) Slog.v(TAG, "Performing resume of " + r
                + " finished=" + r.activity.mFinished);
        if (r != null && !r.activity.mFinished) {
            if (r.getLifecycleState() == ON_RESUME) {
                throw new IllegalStateException(
                if (!finalStateRequest) {
                    final RuntimeException e = new IllegalStateException(
                            "Trying to resume activity which is already resumed");
                    Slog.e(TAG, e.getMessage(), e);
                    Slog.e(TAG, r.getStateString());
                    // TODO(lifecycler): A double resume request is possible when an activity
                    // receives two consequent transactions with relaunch requests and "resumed"
                    // final state requests and the second relaunch is omitted. We still try to
                    // handle two resume requests for the final state. For cases other than this
                    // one, we don't expect it to happen.
                }
                return null;
            }
            if (clearHide) {
            if (finalStateRequest) {
                r.hideForNow = false;
                r.activity.mStartedActivity = false;
            }
@@ -3782,7 +3793,7 @@ public final class ActivityThread extends ClientTransactionHandler {
    }

    @Override
    public void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,
            String reason) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
@@ -3790,7 +3801,7 @@ public final class ActivityThread extends ClientTransactionHandler {
        mSomeActivitiesChanged = true;

        // TODO Push resumeArgs into the activity for consideration
        final ActivityClientRecord r = performResumeActivity(token, clearHide, reason);
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);

        if (r != null) {
            final Activity a = r.activity;
+10 −3
Original line number Diff line number Diff line
@@ -67,9 +67,16 @@ public abstract class ClientTransactionHandler {
    public abstract void handlePauseActivity(IBinder token, boolean finished, boolean userLeaving,
            int configChanges, PendingTransactionActions pendingActions, String reason);

    /** Resume the activity. */
    public abstract void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward,
            String reason);
    /**
     * Resume the activity.
     * @param token Target activity token.
     * @param finalStateRequest Flag indicating if this call is handling final lifecycle state
     *                          request for a transaction.
     * @param isForward Flag indicating if next transition is forward.
     * @param reason Reason for performing this operation.
     */
    public abstract void handleResumeActivity(IBinder token, boolean finalStateRequest,
            boolean isForward, String reason);

    /** Stop the activity. */
    public abstract void handleStopActivity(IBinder token, boolean show, int configChanges,
+2 −1
Original line number Diff line number Diff line
@@ -48,7 +48,8 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        client.handleResumeActivity(token, true /* clearHide */, mIsForward, "RESUME_ACTIVITY");
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }

+1 −1
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ public class TransactionExecutor {
                    mTransactionHandler.handleStartActivity(r, mPendingActions);
                    break;
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r.token, false /* clearHide */,
                    mTransactionHandler.handleResumeActivity(r.token, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                case ON_PAUSE:
Loading