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

Commit 672fac6f authored by Chris Li's avatar Chris Li
Browse files

Refactor realStartActivityLocked

Refactor to make cleanup work easier.
Also avoid using throw-catch to handle the error when proc doesn't have
thread.

Bug: 323801078
Flag: EXEMPT refactor only
Test: pass existing tests
Change-Id: I13ab3ba355a53386c9db0f528b64374e951cac7d
parent efeea629
Loading
Loading
Loading
Loading
+120 −103
Original line number Diff line number Diff line
@@ -899,9 +899,81 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
                lockTaskController.startLockTaskMode(task, false, 0 /* blank UID */);
            }

            try {
            final RemoteException e = tryRealStartActivityInner(
                    task, r, proc, activityClientController, andResume);
            if (e != null) {
                if (r.launchFailed) {
                    // This is the second time we failed -- finish activity and give up.
                    Slog.e(TAG, "Second failure launching "
                            + r.intent.getComponent().flattenToShortString() + ", giving up", e);
                    proc.appDied("2nd-crash");
                    r.finishIfPossible("2nd-crash", false /* oomAdj */);
                    return false;
                }

                // This is the first time we failed -- restart process and
                // retry.
                r.launchFailed = true;
                r.detachFromProcess();
                throw e;
            }
        } finally {
            endDeferResume();
            proc.resumeConfigurationDispatch();
        }

        r.launchFailed = false;

        // Resume or pause requests are done as part of launch transaction,
        // so updating the state should be done accordingly.
        if (andResume && readyToResume()) {
            // As part of the process of launching, ActivityThread also performs
            // a resume.
            r.setState(RESUMED, "realStartActivityLocked");
            r.completeResumeLocked();
        } else if (r.isVisibleRequested()) {
            // This activity is not starting in the resumed state... which should look like we asked
            // it to pause+stop (but remain visible), and it has done so and reported back the
            // current icicle and other state.
            ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s "
                    + "(starting in paused state)", r);
            r.setState(PAUSED, "realStartActivityLocked");
            mRootWindowContainer.executeAppTransitionForAllDisplay();
        } else {
            // This activity is starting while invisible, so it should be stopped.
            r.setState(STOPPING, "realStartActivityLocked");
        }
        // Perform OOM scoring after the activity state is set, so the process can be updated with
        // the latest state.
        proc.onStartActivity(mService.mTopProcessState, r.info);

        // Launch the new version setup screen if needed.  We do this -after-
        // launching the initial activity (that is, home), so that it can have
        // a chance to initialize itself while in the background, making the
        // switch back to it faster and look better.
        if (mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask)) {
            mService.getActivityStartController().startSetupActivity();
        }

        // Update any services we are bound to that might care about whether
        // their client may have activities.
        if (r.app != null) {
            r.app.updateServiceConnectionActivities();
        }

        return true;
    }

    /** @return {@link RemoteException} if the app process failed to handle the activity start. */
    @Nullable
    private RemoteException tryRealStartActivityInner(
            @NonNull Task task,
            @NonNull ActivityRecord r,
            @NonNull WindowProcessController proc,
            @Nullable IActivityClientController activityClientController,
            boolean andResume) {
        if (!proc.hasThread()) {
                    throw new RemoteException();
            return new RemoteException();
        }
        List<ResultInfo> results = null;
        List<ReferrerIntent> newIntents = null;
@@ -911,10 +983,12 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
            results = r.results;
            newIntents = r.newIntents;
        }
                if (DEBUG_SWITCH) Slog.v(TAG_SWITCH,
        if (DEBUG_SWITCH) {
            Slog.v(TAG_SWITCH,
                    "Launching: " + r + " savedState=" + r.getSavedState()
                            + " with results=" + results + " newIntents=" + newIntents
                            + " andResume=" + andResume);
        }
        EventLogTags.writeWmRestartActivity(r.mUserId, System.identityHashCode(r),
                task.mTaskId, r.shortComponentName);
        updateHomeProcessIfNeeded(r);
@@ -972,12 +1046,16 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
            // transaction.
            mService.getLifecycleManager().dispatchPendingTransaction(proc.getThread());
        }
        try {
            mService.getLifecycleManager().scheduleTransactionItems(
                    proc.getThread(),
                    // Immediately dispatch the transaction, so that if it fails, the server can
                    // restart the process and retry now.
                    true /* shouldDispatchImmediately */,
                    launchActivityItem, lifecycleItem);
        } catch (RemoteException e) {
            return e;
        }

        if (procConfig.seq > mRootWindowContainer.getConfiguration().seq) {
            // If the seq is increased, there should be something changed (e.g. registered
@@ -999,68 +1077,7 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks {
                mService.setHeavyWeightProcess(r);
            }
        }

            } catch (RemoteException e) {
                if (r.launchFailed) {
                    // This is the second time we failed -- finish activity and give up.
                    Slog.e(TAG, "Second failure launching "
                            + r.intent.getComponent().flattenToShortString() + ", giving up", e);
                    proc.appDied("2nd-crash");
                    r.finishIfPossible("2nd-crash", false /* oomAdj */);
                    return false;
                }

                // This is the first time we failed -- restart process and
                // retry.
                r.launchFailed = true;
                r.detachFromProcess();
                throw e;
            }
        } finally {
            endDeferResume();
            proc.resumeConfigurationDispatch();
        }

        r.launchFailed = false;

        // TODO(lifecycler): Resume or pause requests are done as part of launch transaction,
        // so updating the state should be done accordingly.
        if (andResume && readyToResume()) {
            // As part of the process of launching, ActivityThread also performs
            // a resume.
            r.setState(RESUMED, "realStartActivityLocked");
            r.completeResumeLocked();
        } else if (r.isVisibleRequested()) {
            // This activity is not starting in the resumed state... which should look like we asked
            // it to pause+stop (but remain visible), and it has done so and reported back the
            // current icicle and other state.
            ProtoLog.v(WM_DEBUG_STATES, "Moving to PAUSED: %s "
                    + "(starting in paused state)", r);
            r.setState(PAUSED, "realStartActivityLocked");
            mRootWindowContainer.executeAppTransitionForAllDisplay();
        } else {
            // This activity is starting while invisible, so it should be stopped.
            r.setState(STOPPING, "realStartActivityLocked");
        }
        // Perform OOM scoring after the activity state is set, so the process can be updated with
        // the latest state.
        proc.onStartActivity(mService.mTopProcessState, r.info);

        // Launch the new version setup screen if needed.  We do this -after-
        // launching the initial activity (that is, home), so that it can have
        // a chance to initialize itself while in the background, making the
        // switch back to it faster and look better.
        if (mRootWindowContainer.isTopDisplayFocusedRootTask(rootTask)) {
            mService.getActivityStartController().startSetupActivity();
        }

        // Update any services we are bound to that might care about whether
        // their client may have activities.
        if (r.app != null) {
            r.app.updateServiceConnectionActivities();
        }

        return true;
        return null;
    }

    void updateHomeProcessIfNeeded(@NonNull ActivityRecord r) {