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

Commit 057a651f authored by Andrii Kulian's avatar Andrii Kulian
Browse files

Cleanup ActivityStack#requestFinishActivityLocked

In an attempt to reduce the number of different finish* methods in
ActivityTaskManager codebase this CL consolidates
ActivityStack#requestFinishActivityLocked() into
ActivityRecord#finishActivityLocked().

It was used before to initiate activity finishing and the return
value indicated if the request was successful. It was different from
the return value of ActivityRecord#finishActivityLocked(), which only
returned 'true' if the activity record was removed from history
immediately. In order to accomodate both, this CL updates the finish
method in ActivityRecord to return an integer status value, so it can
now be used in both cases.

Bug: 137329632
Test: atest WmTests:ActivityRecordTests
Change-Id: I30ebc306637dea5e8b28ca4b4dfaab8df31d2be3
parent 296c5ef2
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ interface IActivityTaskManager {
    void moveTaskToFront(in IApplicationThread app, in String callingPackage, int task,
            int flags, in Bundle options);
    int getTaskForActivity(in IBinder token, in boolean onlyRoot);
    /** Finish all activities that were started for result from the specified activity. */
    void finishSubActivity(in IBinder token, in String resultWho, int requestCode);
    ParceledListSlice getRecentTasks(int maxNum, int flags, int userId);
    boolean willActivityBeVisible(in IBinder token);
+40 −9
Original line number Diff line number Diff line
@@ -163,6 +163,7 @@ import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.START_TAG;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
@@ -1630,22 +1631,52 @@ final class ActivityRecord extends ConfigurationContainer {
        setSavedState(null /* savedState */);
    }

    /** Activity finish request was not executed. */
    static final int FINISH_RESULT_CANCELLED = 0;
    /** Activity finish was requested, activity will be fully removed later. */
    static final int FINISH_RESULT_REQUESTED = 1;
    /** Activity finish was requested, activity was removed from history. */
    static final int FINISH_RESULT_REMOVED = 2;

    /** Definition of possible results for activity finish request. */
    @IntDef(prefix = { "FINISH_RESULT_" }, value = {
            FINISH_RESULT_CANCELLED,
            FINISH_RESULT_REQUESTED,
            FINISH_RESULT_REMOVED,
    })
    @interface FinishRequest {}

    /**
     * See {@link #finishActivityLocked(int, Intent, String, boolean, boolean)}
     */
    boolean finishActivityLocked(int resultCode, Intent resultData, String reason, boolean oomAdj) {
    @FinishRequest int finishActivityLocked(int resultCode, Intent resultData, String reason,
            boolean oomAdj) {
        return finishActivityLocked(resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
    }

    /**
     * @return Returns true if this activity has been removed from the history
     * list, or false if it is still in the list and will be removed later.
     * @return One of {@link FinishRequest} values:
     * {@link #FINISH_RESULT_REMOVED} if this activity has been removed from the history list.
     * {@link #FINISH_RESULT_REQUESTED} if removal process was started, but it is still in the list
     * and will be removed from history later.
     * {@link #FINISH_RESULT_CANCELLED} if activity is already finishing or in invalid state and the
     * request to finish it was not ignored.
     */
    boolean finishActivityLocked(int resultCode, Intent resultData, String reason, boolean oomAdj,
            boolean pauseImmediately) {
    @FinishRequest int finishActivityLocked(int resultCode, Intent resultData, String reason,
            boolean oomAdj, boolean pauseImmediately) {
        if (DEBUG_RESULTS || DEBUG_STATES) {
            Slog.v(TAG_STATES, "Finishing activity r=" + this + ", result=" + resultCode
                    + ", data=" + resultData + ", reason=" + reason);
        }

        if (finishing) {
            Slog.w(TAG, "Duplicate finish request for " + this);
            return false;
            Slog.w(TAG, "Duplicate finish request for r=" + this);
            return FINISH_RESULT_CANCELLED;
        }

        if (!isInStackLocked()) {
            Slog.w(TAG, "Finish request when not in stack for r=" + this);
            return FINISH_RESULT_CANCELLED;
        }

        mAtmService.mWindowManager.deferSurfaceLayout();
@@ -1737,12 +1768,12 @@ final class ActivityRecord extends ConfigurationContainer {
                        taskOverlay.prepareActivityHideTransitionAnimation(transit);
                    }
                }
                return removedActivity;
                return removedActivity ? FINISH_RESULT_REMOVED : FINISH_RESULT_REQUESTED;
            } else {
                if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + this);
            }

            return false;
            return FINISH_RESULT_REQUESTED;
        } finally {
            mAtmService.mWindowManager.continueSurfaceLayout();
        }
+15 −39
Original line number Diff line number Diff line
@@ -58,6 +58,8 @@ import static com.android.server.wm.ActivityDisplay.POSITION_BOTTOM;
import static com.android.server.wm.ActivityDisplay.POSITION_TOP;
import static com.android.server.wm.ActivityRecord.FINISH_AFTER_VISIBLE;
import static com.android.server.wm.ActivityRecord.FINISH_IMMEDIATELY;
import static com.android.server.wm.ActivityRecord.FINISH_RESULT_CANCELLED;
import static com.android.server.wm.ActivityRecord.FINISH_RESULT_REMOVED;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
@@ -1153,13 +1155,6 @@ class ActivityStack extends ConfigurationContainer {
        return null;
    }

    private TaskRecord bottomTask() {
        if (mTaskHistory.isEmpty()) {
            return null;
        }
        return mTaskHistory.get(0);
    }

    TaskRecord taskForIdLocked(int id) {
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            final TaskRecord task = mTaskHistory.get(taskNdx);
@@ -2787,8 +2782,8 @@ class ActivityStack extends ConfigurationContainer {
                !mLastNoHistoryActivity.finishing) {
            if (DEBUG_STATES) Slog.d(TAG_STATES,
                    "no-history finish of " + mLastNoHistoryActivity + " on new resume");
            requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
                    null, "resume-no-history", false);
            mLastNoHistoryActivity.finishActivityLocked(Activity.RESULT_CANCELED,
                    null /* resultData */, "resume-no-history", false /* oomAdj */);
            mLastNoHistoryActivity = null;
        }

@@ -3023,8 +3018,8 @@ class ActivityStack extends ConfigurationContainer {
                // If any exception gets thrown, toss away this
                // activity and try the next one.
                Slog.w(TAG, "Exception thrown during resume of " + next, e);
                requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
                        "resume-exception", true);
                next.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
                        "resume-exception", true /* oomAdj */);
                return true;
            }
        } else {
@@ -3452,7 +3447,7 @@ class ActivityStack extends ConfigurationContainer {
                    if (DEBUG_TASKS) Slog.w(TAG_TASKS,
                            "resetTaskIntendedTask: calling finishActivity on " + p);
                    if (p.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
                            "reset-task", false /* oomAdj */)) {
                            "reset-task", false /* oomAdj */) == FINISH_RESULT_REMOVED) {
                        end--;
                        srcPos--;
                    }
@@ -3760,10 +3755,9 @@ class ActivityStack extends ConfigurationContainer {
            if (!r.finishing) {
                if (!shouldSleepActivities()) {
                    if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
                    if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "stop-no-history", false)) {
                        // If {@link requestFinishActivityLocked} returns {@code true},
                        // {@link adjustFocusedActivityStack} would have been already called.
                    if (r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
                            "stop-no-history", false /* oomAdj */) != FINISH_RESULT_CANCELLED) {
                        // {@link adjustFocusedActivityStack} must have been already called.
                        r.resumeKeyDispatchingLocked();
                        return;
                    }
@@ -3812,25 +3806,7 @@ class ActivityStack extends ConfigurationContainer {
        }
    }

    /**
     * @return Returns true if the activity is being finished, false if for
     * some reason it is being left as-is.
     */
    final boolean requestFinishActivityLocked(IBinder token, int resultCode,
            Intent resultData, String reason, boolean oomAdj) {
        ActivityRecord r = isInStackLocked(token);
        if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
                "Finishing activity token=" + token + " r="
                + ", result=" + resultCode + ", data=" + resultData
                + ", reason=" + reason);
        if (r == null) {
            return false;
        }

        r.finishActivityLocked(resultCode, resultData, reason, oomAdj);
        return true;
    }

    /** Finish all activities that were started for result from the specified activity. */
    final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) {
        for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
            ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
@@ -4052,8 +4028,8 @@ class ActivityStack extends ConfigurationContainer {
        }
        final long origId = Binder.clearCallingIdentity();
        for (int i = start; i > finishTo; i--) {
            ActivityRecord r = activities.get(i);
            requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
            final ActivityRecord r = activities.get(i);
            r.finishActivityLocked(resultCode, resultData, "navigate-up", true /* oomAdj */);
            // Only return the supplied result for the first activity finished
            resultCode = Activity.RESULT_CANCELED;
            resultData = null;
@@ -4090,8 +4066,8 @@ class ActivityStack extends ConfigurationContainer {
                } catch (RemoteException e) {
                    foundParentInTask = false;
                }
                requestFinishActivityLocked(parent.appToken, resultCode,
                        resultData, "navigate-top", true);
                parent.finishActivityLocked(resultCode, resultData, "navigate-top",
                        true /* oomAdj */);
            }
        }
        Binder.restoreCallingIdentity(origId);
+2 −2
Original line number Diff line number Diff line
@@ -890,8 +890,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
                    Slog.e(TAG, "Second failure launching "
                            + r.intent.getComponent().flattenToShortString() + ", giving up", e);
                    proc.appDied();
                    stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
                            "2nd-crash", false);
                    r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
                            "2nd-crash", false /* oomAdj */);
                    return false;
                }

+6 −6
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PRE
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE;
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
import static com.android.server.wm.ActivityRecord.FINISH_RESULT_CANCELLED;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
@@ -1560,13 +1561,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
        }

        synchronized (mGlobalLock) {
            ActivityRecord r = ActivityRecord.isInStackLocked(token);
            final ActivityRecord r = ActivityRecord.isInStackLocked(token);
            if (r == null) {
                return true;
            }
            // Keep track of the root activity of the task before we finish it
            final TaskRecord tr = r.getTaskRecord();
            ActivityRecord rootR = tr.getRootActivity();
            final ActivityRecord rootR = tr.getRootActivity();
            if (rootR == null) {
                Slog.w(TAG, "Finishing task with all activities already finished");
            }
@@ -1616,7 +1617,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                    // because we don't support returning them across task boundaries. Also, to
                    // keep backwards compatibility we remove the task from recents when finishing
                    // task with root activity.
                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
                    res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false /* killProcess */,
                            finishWithRootActivity, "finish-activity");
                    if (!res) {
                        Slog.i(TAG, "Removing task failed to finish activity");
@@ -1624,8 +1625,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
                    // Explicitly dismissing the activity so reset its relaunch flag.
                    r.mRelaunchReason = RELAUNCH_REASON_NONE;
                } else {
                    res = tr.getStack().requestFinishActivityLocked(token, resultCode,
                            resultData, "app-request", true);
                    res = r.finishActivityLocked(resultCode, resultData, "app-request",
                            true /* oomAdj */) != FINISH_RESULT_CANCELLED;
                    if (!res) {
                        Slog.i(TAG, "Failed to finish by app-request");
                    }
@@ -1649,7 +1650,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {

                // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
                // can finish.
                final TaskRecord task = r.getTaskRecord();
                if (getLockTaskController().activityBlockedFromFinish(r)) {
                    return false;
                }
Loading