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

Commit 6e4f5748 authored by Riddle Hsu's avatar Riddle Hsu Committed by Android (Google) Code Review
Browse files

Merge "Add a new launch type for hot start with relaunched activity"

parents 351a4ce3 59c2e7cf
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3768,6 +3768,7 @@ message AppStartOccurred {
        WARM = 1;
        HOT = 2;
        COLD = 3;
        RELAUNCH = 4;
    }
    // The transition type.
    optional TransitionType type = 3;
@@ -3829,6 +3830,7 @@ message AppStartCanceled {
        WARM = 1;
        HOT = 2;
        COLD = 3;
        RELAUNCH = 4;
    }
    // The transition type.
    optional TransitionType type = 3;
+17 −1
Original line number Diff line number Diff line
@@ -40,13 +40,20 @@ public class WaitResult implements Parcelable {
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"LAUNCH_STATE_"}, value = {
            LAUNCH_STATE_UNKNOWN,
            LAUNCH_STATE_COLD,
            LAUNCH_STATE_WARM,
            LAUNCH_STATE_HOT
            LAUNCH_STATE_HOT,
            LAUNCH_STATE_RELAUNCH
    })
    public @interface LaunchState {
    }

    /**
     * Not considered as a launch event, e.g. the activity is already on top.
     */
    public static final int LAUNCH_STATE_UNKNOWN = 0;

    /**
     * Cold launch sequence: a new process has started.
     */
@@ -62,6 +69,13 @@ public class WaitResult implements Parcelable {
     */
    public static final int LAUNCH_STATE_HOT = 3;

    /**
     * Relaunch launch sequence: process reused, but activity has to be destroyed and created.
     * E.g. the current device configuration is different from the background activity that will be
     * brought to foreground, and the activity doesn't declare to handle the change.
     */
    public static final int LAUNCH_STATE_RELAUNCH = 4;

    public static final int INVALID_DELAY = -1;
    public int result;
    public boolean timeout;
@@ -124,6 +138,8 @@ public class WaitResult implements Parcelable {
                return "WARM";
            case LAUNCH_STATE_HOT:
                return "HOT";
            case LAUNCH_STATE_RELAUNCH:
                return "RELAUNCH";
            default:
                return "UNKNOWN (" + type + ")";
        }
+22 −14
Original line number Diff line number Diff line
@@ -3,8 +3,10 @@ package com.android.server.wm;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.ActivityManager.processStateAmToProto;
import static android.app.WaitResult.INVALID_DELAY;
import static android.app.WaitResult.LAUNCH_STATE_COLD;
import static android.app.WaitResult.LAUNCH_STATE_HOT;
import static android.app.WaitResult.LAUNCH_STATE_RELAUNCH;
import static android.app.WaitResult.LAUNCH_STATE_WARM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
@@ -130,7 +132,6 @@ class ActivityMetricsLogger {
     * transition, in the case the launch is standalone (e.g. from recents).
     */
    private static final int IGNORE_CALLER = -1;
    private static final int INVALID_DELAY = -1;

    // Preallocated strings we are sending to tron, so we don't have to allocate a new one every
    // time we log.
@@ -220,6 +221,8 @@ class ActivityMetricsLogger {
        boolean mLoggedStartingWindowDrawn;
        /** If the any app transitions have been logged as starting. */
        boolean mLoggedTransitionStarting;
        /** Whether any activity belonging to this transition has relaunched. */
        boolean mRelaunched;

        /** Non-null if the application has reported drawn but its window hasn't. */
        @Nullable Runnable mPendingFullyDrawn;
@@ -351,6 +354,7 @@ class ActivityMetricsLogger {
         */
        final int windowsFullyDrawnDelayMs;
        final int activityRecordIdHashCode;
        final boolean relaunched;

        private TransitionInfoSnapshot(TransitionInfo info) {
            this(info, info.mLastLaunchedActivity, INVALID_DELAY);
@@ -379,6 +383,7 @@ class ActivityMetricsLogger {
            launchedActivityShortComponentName = launchedActivity.shortComponentName;
            activityRecordIdHashCode = System.identityHashCode(launchedActivity);
            this.windowsFullyDrawnDelayMs = windowsFullyDrawnDelayMs;
            relaunched = info.mRelaunched;
        }

        @WaitResult.LaunchState int getLaunchState() {
@@ -386,7 +391,7 @@ class ActivityMetricsLogger {
                case TYPE_TRANSITION_WARM_LAUNCH:
                    return LAUNCH_STATE_WARM;
                case TYPE_TRANSITION_HOT_LAUNCH:
                    return LAUNCH_STATE_HOT;
                    return relaunched ? LAUNCH_STATE_RELAUNCH : LAUNCH_STATE_HOT;
                case TYPE_TRANSITION_COLD_LAUNCH:
                    return LAUNCH_STATE_COLD;
                default:
@@ -673,6 +678,13 @@ class ActivityMetricsLogger {
        }
    }

    void notifyActivityRelaunched(ActivityRecord r) {
        final TransitionInfo info = getActiveTransitionInfo(r);
        if (info != null) {
            info.mRelaunched = true;
        }
    }

    /** Makes sure that the reference to the removed activity is cleared. */
    void notifyActivityRemoved(@NonNull ActivityRecord r) {
        mLastTransitionInfo.remove(r);
@@ -800,13 +812,13 @@ class ActivityMetricsLogger {
                FrameworkStatsLog.APP_START_CANCELED,
                activity.info.applicationInfo.uid,
                activity.packageName,
                convertAppStartTransitionType(type),
                getAppStartTransitionType(type, info.mRelaunched),
                activity.info.name);
        if (DEBUG_METRICS) {
            Slog.i(TAG, String.format("APP_START_CANCELED(%s, %s, %s, %s)",
                    activity.info.applicationInfo.uid,
                    activity.packageName,
                    convertAppStartTransitionType(type),
                    getAppStartTransitionType(type, info.mRelaunched),
                    activity.info.name));
        }
    }
@@ -871,7 +883,7 @@ class ActivityMetricsLogger {
                FrameworkStatsLog.APP_START_OCCURRED,
                info.applicationInfo.uid,
                info.packageName,
                convertAppStartTransitionType(info.type),
                getAppStartTransitionType(info.type, info.relaunched),
                info.launchedActivityName,
                info.launchedActivityLaunchedFromPackage,
                isInstantApp,
@@ -891,7 +903,7 @@ class ActivityMetricsLogger {
            Slog.i(TAG, String.format("APP_START_OCCURRED(%s, %s, %s, %s, %s)",
                    info.applicationInfo.uid,
                    info.packageName,
                    convertAppStartTransitionType(info.type),
                    getAppStartTransitionType(info.type, info.relaunched),
                    info.launchedActivityName,
                    info.launchedActivityLaunchedFromPackage));
        }
@@ -918,7 +930,7 @@ class ActivityMetricsLogger {
        Log.i(TAG, sb.toString());
    }

    private int convertAppStartTransitionType(int tronType) {
    private static int getAppStartTransitionType(int tronType, boolean relaunched) {
        if (tronType == TYPE_TRANSITION_COLD_LAUNCH) {
            return FrameworkStatsLog.APP_START_OCCURRED__TYPE__COLD;
        }
@@ -926,17 +938,13 @@ class ActivityMetricsLogger {
            return FrameworkStatsLog.APP_START_OCCURRED__TYPE__WARM;
        }
        if (tronType == TYPE_TRANSITION_HOT_LAUNCH) {
            return FrameworkStatsLog.APP_START_OCCURRED__TYPE__HOT;
            return relaunched
                    ? FrameworkStatsLog.APP_START_OCCURRED__TYPE__RELAUNCH
                    : FrameworkStatsLog.APP_START_OCCURRED__TYPE__HOT;
        }
        return FrameworkStatsLog.APP_START_OCCURRED__TYPE__UNKNOWN;
    }

    /** @return the last known window drawn delay of the given activity. */
    int getLastDrawnDelayMs(ActivityRecord r) {
        final TransitionInfo info = mLastTransitionInfo.get(r);
        return info != null ? info.mWindowsDrawnDelayMs : INVALID_DELAY;
    }

    /** @see android.app.Activity#reportFullyDrawn */
    TransitionInfoSnapshot logAppTransitionReportedDrawn(ActivityRecord r,
            boolean restoredFromBundle) {
+6 −8
Original line number Diff line number Diff line
@@ -226,7 +226,7 @@ import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.app.ResultInfo;
import android.app.WaitResult.LaunchState;
import android.app.WaitResult;
import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ActivityLifecycleItem;
import android.app.servertransaction.ActivityRelaunchItem;
@@ -3130,6 +3130,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
    }

    void finishRelaunching() {
        mTaskSupervisor.getActivityMetricsLogger().notifyActivityRelaunched(this);
        unfreezeBounds();

        if (mPendingRelaunchCount > 0) {
@@ -5435,14 +5436,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
                .getActivityMetricsLogger().notifyWindowsDrawn(this, timestampNs);
        final boolean validInfo = info != null;
        final int windowsDrawnDelayMs = validInfo ? info.windowsDrawnDelayMs : INVALID_DELAY;
        final @LaunchState int launchState = validInfo ? info.getLaunchState() : -1;
        final @WaitResult.LaunchState int launchState =
                validInfo ? info.getLaunchState() : WaitResult.LAUNCH_STATE_UNKNOWN;
        // The activity may have been requested to be invisible (another activity has been launched)
        // so there is no valid info. But if it is the current top activity (e.g. sleeping), the
        // invalid state is still reported to make sure the waiting result is notified.
        if (validInfo || this == getDisplayArea().topRunningActivity()) {
            mTaskSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
                    windowsDrawnDelayMs, launchState);
            mTaskSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs);
            mTaskSupervisor.stopWaitingForActivityVisible(this, windowsDrawnDelayMs, launchState);
        }
        finishLaunchTickingLocked();
        if (task != null) {
@@ -7163,11 +7165,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
            } else {
                mRelaunchReason = RELAUNCH_REASON_NONE;
            }
            if (!attachedToProcess()) {
                ProtoLog.v(WM_DEBUG_CONFIGURATION,
                        "Config is destroying non-running %s", this);
                destroyImmediately("config");
            } else if (mState == PAUSING) {
            if (mState == PAUSING) {
                // A little annoying: we are waiting for this activity to finish pausing. Let's not
                // do anything now, but just flag that it needs to be restarted when done pausing.
                ProtoLog.v(WM_DEBUG_CONFIGURATION,
+0 −4
Original line number Diff line number Diff line
@@ -28,8 +28,6 @@ import static android.app.ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WaitResult.LAUNCH_STATE_COLD;
import static android.app.WaitResult.LAUNCH_STATE_HOT;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -819,8 +817,6 @@ class ActivityStarter {
                break;
            }
            case START_TASK_TO_FRONT: {
                mRequest.waitResult.launchState =
                        r.attachedToProcess() ? LAUNCH_STATE_HOT : LAUNCH_STATE_COLD;
                // ActivityRecord may represent a different activity, but it should not be
                // in the resumed state.
                if (r.nowVisible && r.isState(RESUMED)) {
Loading