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

Commit 3b21bdc2 authored by Louis Chang's avatar Louis Chang
Browse files

Fix Launcher crash while handling top resumed state

The process of current top resumed activity was killed. Before getting
the callbacks from binder death recipient, the process was being restarted
while bringing up other non-UI components - such as sending broadcast.
Since the top resumed activity was not being updated, ATM had to schedule
to the client for dropping the top resumed state after process bound.
So, exceptions thrown because it was illegal to drop the top resumed state
for a fresh client.

Check if necessary to update top resumed activity whenever the stack resumed
activity changes.

Bug: 128837461
Test: run emulator for 10 times
Test: atest ActivityLifecycleTopResumedStateTests
Test: atest ActivityLifecycleKeyguardTests
Test: atest ActivityLifecycleTests

Change-Id: Iefde9bbe5ae50f3a241235faa505a2e58ed681ee
parent 6839f419
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -693,13 +693,13 @@ final class ActivityRecord extends ConfigurationContainer {
        }
    }

    void scheduleTopResumedActivityChanged(boolean onTop) {
    boolean scheduleTopResumedActivityChanged(boolean onTop) {
        if (!attachedToProcess()) {
            if (DEBUG_STATES) {
                Slog.w(TAG, "Can't report activity position update - client not running"
                                + ", activityRecord=" + this);
            }
            return;
            return false;
        }
        try {
            if (DEBUG_STATES) {
@@ -710,7 +710,9 @@ final class ActivityRecord extends ConfigurationContainer {
                    TopResumedActivityChangeItem.obtain(onTop));
        } catch (RemoteException e) {
            // If process died, whatever.
            return false;
        }
        return true;
    }

    void updateMultiWindowMode() {
@@ -3408,7 +3410,6 @@ final class ActivityRecord extends ConfigurationContainer {
            transaction.addCallback(callbackItem);
            transaction.setLifecycleStateRequest(lifecycleItem);
            mAtmService.getLifecycleManager().scheduleTransaction(transaction);
            mStackSupervisor.updateTopResumedActivityIfNeeded();
            // Note: don't need to call pauseIfSleepingLocked() here, because the caller will only
            // request resume if this activity is currently resumed, which implies we aren't
            // sleeping.
+1 −2
Original line number Diff line number Diff line
@@ -1500,7 +1500,6 @@ class ActivityStack extends ConfigurationContainer {
                + " callers=" + Debug.getCallers(5));
        r.setState(RESUMED, "minimalResumeActivityLocked");
        r.completeResumeLocked();
        mStackSupervisor.updateTopResumedActivityIfNeeded();
        if (DEBUG_SAVED_STATE) Slog.i(TAG_SAVED_STATE,
                "Launch completed; removing icicle of " + r.icicle);
    }
@@ -2571,7 +2570,6 @@ class ActivityStack extends ConfigurationContainer {
            // Protect against recursion.
            mInResumeTopActivity = true;
            result = resumeTopActivityInnerLocked(prev, options);
            mStackSupervisor.updateTopResumedActivityIfNeeded();

            // When resuming the top activity, it may be necessary to pause the top activity (for
            // example, returning to the lock screen. We suppress the normal pause logic in
@@ -2606,6 +2604,7 @@ class ActivityStack extends ConfigurationContainer {
        if (DEBUG_STACK) Slog.d(TAG_STACK, "setResumedActivity stack:" + this + " + from: "
                + mResumedActivity + " to:" + r + " reason:" + reason);
        mResumedActivity = r;
        mStackSupervisor.updateTopResumedActivityIfNeeded();
    }

    @GuardedBy("mService")
+2 −3
Original line number Diff line number Diff line
@@ -853,7 +853,6 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {

                // Schedule transaction.
                mService.getLifecycleManager().scheduleTransaction(clientTransaction);
                updateTopResumedActivityIfNeeded();

                if ((proc.mInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0
                        && mService.mHasHeavyWeightFeature) {
@@ -2321,8 +2320,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
        // mTopResumedActivityWaitingForPrev == true at this point would mean that an activity
        // before the prevTopActivity one hasn't reported back yet. So server never sent the top
        // resumed state change message to prevTopActivity.
        if (prevActivityReceivedTopState) {
            prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */);
        if (prevActivityReceivedTopState
                && prevTopActivity.scheduleTopResumedActivityChanged(false /* onTop */)) {
            scheduleTopResumedStateLossTimeout(prevTopActivity);
            mTopResumedActivityWaitingForPrev = true;
        }