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

Commit 26b28799 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "AM: Report launch state with activity launch info"

parents fc521004 bb9ab4b9
Loading
Loading
Loading
Loading
+51 −0
Original line number Original line Diff line number Diff line
@@ -16,11 +16,14 @@


package android.app;
package android.app;


import android.annotation.IntDef;
import android.content.ComponentName;
import android.content.ComponentName;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;


import java.io.PrintWriter;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;


/**
/**
 * Information returned after waiting for an activity start.
 * Information returned after waiting for an activity start.
@@ -28,11 +31,43 @@ import java.io.PrintWriter;
 * @hide
 * @hide
 */
 */
public class WaitResult implements Parcelable {
public class WaitResult implements Parcelable {

    /**
     * The state at which a launch sequence had started.
     *
     * @see <a href="https://developer.android.com/topic/performance/vitals/launch-time"App startup
     * time</a>
     */
    @Retention(RetentionPolicy.SOURCE)
    @IntDef(prefix = {"LAUNCH_STATE_"}, value = {
            LAUNCH_STATE_COLD,
            LAUNCH_STATE_WARM,
            LAUNCH_STATE_HOT
    })
    public @interface LaunchState {
    }

    /**
     * Cold launch sequence: a new process has started.
     */
    public static final int LAUNCH_STATE_COLD = 1;

    /**
     * Warm launch sequence: process reused, but activity has to be created.
     */
    public static final int LAUNCH_STATE_WARM = 2;

    /**
     * Hot launch sequence: process reused, activity brought-to-top.
     */
    public static final int LAUNCH_STATE_HOT = 3;

    public static final int INVALID_DELAY = -1;
    public static final int INVALID_DELAY = -1;
    public int result;
    public int result;
    public boolean timeout;
    public boolean timeout;
    public ComponentName who;
    public ComponentName who;
    public long totalTime;
    public long totalTime;
    public @LaunchState int launchState;


    public WaitResult() {
    public WaitResult() {
    }
    }
@@ -48,6 +83,7 @@ public class WaitResult implements Parcelable {
        dest.writeInt(timeout ? 1 : 0);
        dest.writeInt(timeout ? 1 : 0);
        ComponentName.writeToParcel(who, dest);
        ComponentName.writeToParcel(who, dest);
        dest.writeLong(totalTime);
        dest.writeLong(totalTime);
        dest.writeInt(launchState);
    }
    }


    public static final Parcelable.Creator<WaitResult> CREATOR
    public static final Parcelable.Creator<WaitResult> CREATOR
@@ -68,6 +104,7 @@ public class WaitResult implements Parcelable {
        timeout = source.readInt() != 0;
        timeout = source.readInt() != 0;
        who = ComponentName.readFromParcel(source);
        who = ComponentName.readFromParcel(source);
        totalTime = source.readLong();
        totalTime = source.readLong();
        launchState = source.readInt();
    }
    }


    public void dump(PrintWriter pw, String prefix) {
    public void dump(PrintWriter pw, String prefix) {
@@ -76,5 +113,19 @@ public class WaitResult implements Parcelable {
        pw.println(prefix + "  timeout=" + timeout);
        pw.println(prefix + "  timeout=" + timeout);
        pw.println(prefix + "  who=" + who);
        pw.println(prefix + "  who=" + who);
        pw.println(prefix + "  totalTime=" + totalTime);
        pw.println(prefix + "  totalTime=" + totalTime);
        pw.println(prefix + "  launchState=" + launchState);
    }

    public static String launchStateToString(@LaunchState int type) {
        switch (type) {
            case LAUNCH_STATE_COLD:
                return "COLD";
            case LAUNCH_STATE_WARM:
                return "WARM";
            case LAUNCH_STATE_HOT:
                return "HOT";
            default:
                return "UNKNOWN (" + type + ")";
        }
    }
    }
}
}
 No newline at end of file
+7 −0
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM;
import static android.app.ActivityTaskManager.RESIZE_MODE_USER;
import static android.app.ActivityTaskManager.RESIZE_MODE_USER;
import static android.app.WaitResult.launchStateToString;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
@@ -491,6 +492,7 @@ final class ActivityManagerShellCommand extends ShellCommand {
            final long endTime = SystemClock.uptimeMillis();
            final long endTime = SystemClock.uptimeMillis();
            PrintWriter out = mWaitOption ? pw : getErrPrintWriter();
            PrintWriter out = mWaitOption ? pw : getErrPrintWriter();
            boolean launched = false;
            boolean launched = false;
            boolean hotLaunch = false;
            switch (res) {
            switch (res) {
                case ActivityManager.START_SUCCESS:
                case ActivityManager.START_SUCCESS:
                    launched = true;
                    launched = true;
@@ -516,6 +518,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    break;
                    break;
                case ActivityManager.START_TASK_TO_FRONT:
                case ActivityManager.START_TASK_TO_FRONT:
                    launched = true;
                    launched = true;
                    //TODO(b/120981435) remove special case
                    hotLaunch = true;
                    out.println(
                    out.println(
                            "Warning: Activity not started, its current "
                            "Warning: Activity not started, its current "
                                    + "task has been brought to the front");
                                    + "task has been brought to the front");
@@ -563,6 +567,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
                    result.who = intent.getComponent();
                    result.who = intent.getComponent();
                }
                }
                pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
                pw.println("Status: " + (result.timeout ? "timeout" : "ok"));
                final @WaitResult.LaunchState int launchState =
                        hotLaunch ? WaitResult.LAUNCH_STATE_HOT : result.launchState;
                pw.println("LaunchState: " + launchStateToString(launchState));
                if (result.who != null) {
                if (result.who != null) {
                    pw.println("Activity: " + result.who.flattenToShortString());
                    pw.println("Activity: " + result.who.flattenToShortString());
                }
                }
+18 −1
Original line number Original line Diff line number Diff line
@@ -3,6 +3,9 @@ package com.android.server.wm;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_SUCCESS;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.ActivityManager.START_TASK_TO_FRONT;
import static android.app.ActivityManager.processStateAmToProto;
import static android.app.ActivityManager.processStateAmToProto;
import static android.app.WaitResult.LAUNCH_STATE_COLD;
import static android.app.WaitResult.LAUNCH_STATE_HOT;
import static android.app.WaitResult.LAUNCH_STATE_WARM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
@@ -80,6 +83,7 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;


import android.app.WaitResult;
import android.app.WindowConfiguration.WindowingMode;
import android.app.WindowConfiguration.WindowingMode;
import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
@@ -101,10 +105,10 @@ import android.util.StatsLog;
import android.util.TimeUtils;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
import android.util.proto.ProtoOutputStream;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.SomeArgs;
import com.android.internal.os.SomeArgs;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.LocalServices;


/**
/**
@@ -259,6 +263,19 @@ class ActivityMetricsLogger {
            activityRecordIdHashCode = System.identityHashCode(launchedActivity);
            activityRecordIdHashCode = System.identityHashCode(launchedActivity);
            this.windowsFullyDrawnDelayMs = windowsFullyDrawnDelayMs;
            this.windowsFullyDrawnDelayMs = windowsFullyDrawnDelayMs;
        }
        }

        @WaitResult.LaunchState int getLaunchState() {
            switch (type) {
                case TYPE_TRANSITION_WARM_LAUNCH:
                    return LAUNCH_STATE_WARM;
                case TYPE_TRANSITION_HOT_LAUNCH:
                    return LAUNCH_STATE_HOT;
                case TYPE_TRANSITION_COLD_LAUNCH:
                    return LAUNCH_STATE_COLD;
                default:
                    return -1;
            }
        }
    }
    }


    ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context, Looper looper) {
    ActivityMetricsLogger(ActivityStackSupervisor supervisor, Context context, Looper looper) {
+4 −2
Original line number Original line Diff line number Diff line
@@ -145,6 +145,7 @@ import android.app.ActivityOptions;
import android.app.PendingIntent;
import android.app.PendingIntent;
import android.app.PictureInPictureParams;
import android.app.PictureInPictureParams;
import android.app.ResultInfo;
import android.app.ResultInfo;
import android.app.WaitResult.LaunchState;
import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ActivityLifecycleItem;
import android.app.servertransaction.ActivityLifecycleItem;
import android.app.servertransaction.ActivityRelaunchItem;
import android.app.servertransaction.ActivityRelaunchItem;
@@ -2180,7 +2181,7 @@ final class ActivityRecord extends ConfigurationContainer {
                .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
                .getActivityMetricsLogger().logAppTransitionReportedDrawn(this, restoredFromBundle);
        if (info != null) {
        if (info != null) {
            mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
            mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
                    info.windowsFullyDrawnDelayMs);
                    info.windowsFullyDrawnDelayMs, info.getLaunchState());
        }
        }
    }
    }


@@ -2204,8 +2205,9 @@ final class ActivityRecord extends ConfigurationContainer {
            final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
            final WindowingModeTransitionInfoSnapshot info = mStackSupervisor
                    .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
                    .getActivityMetricsLogger().notifyWindowsDrawn(getWindowingMode(), timestamp);
            final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
            final int windowsDrawnDelayMs = info != null ? info.windowsDrawnDelayMs : INVALID_DELAY;
            final @LaunchState int launchState = info != null ? info.getLaunchState() : -1;
            mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
            mStackSupervisor.reportActivityLaunchedLocked(false /* timeout */, this,
                    windowsDrawnDelayMs);
                    windowsDrawnDelayMs, launchState);
            mStackSupervisor.sendWaitingVisibleReportLocked(this);
            mStackSupervisor.sendWaitingVisibleReportLocked(this);
            finishLaunchTickingLocked();
            finishLaunchTickingLocked();
            if (task != null) {
            if (task != null) {
+5 −2
Original line number Original line Diff line number Diff line
@@ -599,7 +599,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
        }
        }
    }
    }


    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, long totalTime) {
    void reportActivityLaunchedLocked(boolean timeout, ActivityRecord r, long totalTime,
            @WaitResult.LaunchState int launchState) {
        boolean changed = false;
        boolean changed = false;
        for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
        for (int i = mWaitingActivityLaunched.size() - 1; i >= 0; i--) {
            WaitResult w = mWaitingActivityLaunched.remove(i);
            WaitResult w = mWaitingActivityLaunched.remove(i);
@@ -610,6 +611,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
                    w.who = new ComponentName(r.info.packageName, r.info.name);
                    w.who = new ComponentName(r.info.packageName, r.info.name);
                }
                }
                w.totalTime = totalTime;
                w.totalTime = totalTime;
                w.launchState = launchState;
                // Do not modify w.result.
                // Do not modify w.result.
            }
            }
        }
        }
@@ -1252,7 +1254,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
            mHandler.removeMessages(IDLE_TIMEOUT_MSG, r);
            r.finishLaunchTickingLocked();
            r.finishLaunchTickingLocked();
            if (fromTimeout) {
            if (fromTimeout) {
                reportActivityLaunchedLocked(fromTimeout, r, INVALID_DELAY);
                reportActivityLaunchedLocked(fromTimeout, r, INVALID_DELAY,
                        -1 /* launchState */);
            }
            }


            // This is a hack to semi-deal with a race condition
            // This is a hack to semi-deal with a race condition
Loading