Loading core/java/android/app/ActivityThread.java +8 −1 Original line number Diff line number Diff line Loading @@ -7265,7 +7265,14 @@ public final class ActivityThread extends ClientTransactionHandler Slog.w(TAG, "Low overhead tracing feature is not enabled"); break; } if (profilerInfo.profileLongRunningMethods) { long microToNano = 1000; VMDebug.startLowOverheadTraceForLongRunningMethods( profilerInfo.durationMicros * microToNano); } else { VMDebug.startLowOverheadTraceForAllMethods(); } break; default: try { Loading core/java/android/app/ProfilerInfo.java +28 −3 Original line number Diff line number Diff line Loading @@ -98,9 +98,19 @@ public class ProfilerInfo implements Parcelable { */ public final int profilerOutputVersion; /** * Indicates if we should trace long running methods for lowoverhead tracing */ public final boolean profileLongRunningMethods; /** * The duration in microseconds for which the lowoverhed tracing has to be run */ public final long durationMicros; public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop, boolean streaming, String agent, boolean attachAgentDuringBind, int clockType, int profilerOutputVersion) { int profilerOutputVersion, boolean profileLongRunningMethods, long durationMicros) { profileFile = filename; profileFd = fd; samplingInterval = interval; Loading @@ -110,6 +120,8 @@ public class ProfilerInfo implements Parcelable { this.agent = agent; this.attachAgentDuringBind = attachAgentDuringBind; this.profilerOutputVersion = profilerOutputVersion; this.profileLongRunningMethods = profileLongRunningMethods; this.durationMicros = durationMicros; } public ProfilerInfo(ProfilerInfo in) { Loading @@ -122,6 +134,8 @@ public class ProfilerInfo implements Parcelable { attachAgentDuringBind = in.attachAgentDuringBind; clockType = in.clockType; profilerOutputVersion = in.profilerOutputVersion; profileLongRunningMethods = in.profileLongRunningMethods; durationMicros = in.durationMicros; } /** Loading Loading @@ -165,7 +179,8 @@ public class ProfilerInfo implements Parcelable { public ProfilerInfo setAgent(String agent, boolean attachAgentDuringBind) { return new ProfilerInfo(this.profileFile, this.profileFd, this.samplingInterval, this.autoStopProfiler, this.streamingOutput, agent, attachAgentDuringBind, this.clockType, this.profilerOutputVersion); this.clockType, this.profilerOutputVersion, this.profileLongRunningMethods, this.durationMicros); } /** Loading Loading @@ -207,6 +222,8 @@ public class ProfilerInfo implements Parcelable { out.writeBoolean(attachAgentDuringBind); out.writeInt(clockType); out.writeInt(profilerOutputVersion); out.writeBoolean(profileLongRunningMethods); out.writeLong(durationMicros); } /** @hide */ Loading @@ -222,6 +239,8 @@ public class ProfilerInfo implements Parcelable { proto.write(ProfilerInfoProto.AGENT, agent); proto.write(ProfilerInfoProto.CLOCK_TYPE, clockType); proto.write(ProfilerInfoProto.PROFILER_OUTPUT_VERSION, profilerOutputVersion); proto.write(ProfilerInfoProto.PROFILE_LONG_RUNNING_METHODS, profileLongRunningMethods); proto.write(ProfilerInfoProto.DURATION_MICROS, durationMicros); proto.end(token); } Loading @@ -248,6 +267,8 @@ public class ProfilerInfo implements Parcelable { attachAgentDuringBind = in.readBoolean(); clockType = in.readInt(); profilerOutputVersion = in.readInt(); profileLongRunningMethods = in.readBoolean(); durationMicros = in.readLong(); } @Override Loading @@ -265,7 +286,9 @@ public class ProfilerInfo implements Parcelable { && samplingInterval == other.samplingInterval && streamingOutput == other.streamingOutput && Objects.equals(agent, other.agent) && clockType == other.clockType && profilerOutputVersion == other.profilerOutputVersion; && profilerOutputVersion == other.profilerOutputVersion && profileLongRunningMethods == other.profileLongRunningMethods && durationMicros == other.durationMicros; } @Override Loading @@ -278,6 +301,8 @@ public class ProfilerInfo implements Parcelable { result = 31 * result + Objects.hashCode(agent); result = 31 * result + clockType; result = 31 * result + profilerOutputVersion; result = 31 * result + (profileLongRunningMethods ? 1 : 0); result = 31 * result + Long.hashCode(durationMicros); return result; } } core/proto/android/app/profilerinfo.proto +4 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ message ProfilerInfoProto { // Name of profile output file. optional string profile_file = 1; optional int32 profile_fd = 2; // The sampling interval rate in microseconds. optional int32 sampling_interval = 3; optional bool auto_stop_profiler = 4; optional bool streaming_output = 5; Loading @@ -37,4 +38,7 @@ message ProfilerInfoProto { optional string agent = 6; optional int32 clock_type = 7; optional int32 profiler_output_version = 8; optional bool profile_long_running_methods = 9; // Duration in microseconds for which the tracing needs to run. optional int64 duration_micros = 10; } services/core/java/com/android/server/am/ActivityManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -15916,8 +15916,10 @@ public class ActivityManagerService extends IActivityManager.Stub + android.Manifest.permission.SET_ACTIVITY_WATCHER); } if (start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR && (profilerInfo == null || profilerInfo.profileFd == null)) { if (start && (profilerInfo == null || (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR && profilerInfo.profileFd == null))) { throw new IllegalArgumentException("null profile info or fd"); } services/core/java/com/android/server/am/ActivityManagerShellCommand.java +41 −7 Original line number Diff line number Diff line Loading @@ -223,6 +223,8 @@ final class ActivityManagerShellCommand extends ShellCommand { private boolean mAttachAgentDuringBind; // Whether agent should be attached late. private int mClockType; // Whether we need thread cpu / wall clock / both. private int mProfilerOutputVersion; // The version of the profiler output. private boolean mLongRunningMethods; // Whether we need to trace only long running methods private long mDurationMicros; // duration in microseconds that specifies how long to trace. private int mDisplayId; private int mTaskDisplayAreaFeatureId; private int mWindowingMode; Loading Loading @@ -608,6 +610,8 @@ final class ActivityManagerShellCommand extends ShellCommand { mSamplingInterval = 0; mAutoStop = false; mStreaming = false; mLongRunningMethods = false; mDurationMicros = 0; mUserId = defUser; mDisplayId = INVALID_DISPLAY; mTaskDisplayAreaFeatureId = FEATURE_UNDEFINED; Loading Loading @@ -808,9 +812,9 @@ final class ActivityManagerShellCommand extends ShellCommand { return 1; } } profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, mStreaming, mAgent, mAttachAgentDuringBind, mClockType, mProfilerOutputVersion); profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, mStreaming, mAgent, mAttachAgentDuringBind, mClockType, mProfilerOutputVersion, mLongRunningMethods, mDurationMicros); } pw.println("Starting: " + intent); Loading Loading @@ -1173,6 +1177,8 @@ final class ActivityManagerShellCommand extends ShellCommand { mSamplingInterval = 0; mStreaming = false; mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT; mLongRunningMethods = false; mDurationMicros = 0; mProfilerOutputVersion = ProfilerInfo.OUTPUT_VERSION_DEFAULT; String process = null; Loading Loading @@ -1217,6 +1223,16 @@ final class ActivityManagerShellCommand extends ShellCommand { cmd = getNextArgRequired(); if ("start".equals(cmd)) { start = true; String opt; while ((opt = getNextOption()) != null) { if (opt.equals("--longrunning")) { mLongRunningMethods = true; } else if (opt.equals("--duration")) { // Convert milliseconds to micro seconds long milliToMicro = 1000; mDurationMicros = Long.parseLong(getNextArgRequired()) * milliToMicro; } } } else if ("stop".equals(cmd)) { start = false; } else { Loading Loading @@ -1245,16 +1261,21 @@ final class ActivityManagerShellCommand extends ShellCommand { // For regular method tracing profileFile should be provided with the start command. For // low overhead method tracing the profileFile is optional and provided with the stop // command. if ((start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR) || (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD && !start && getRemainingArgsCount() > 0)) { boolean hasFileArg = (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR && start) || (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD && !start && getRemainingArgsCount() > 0); if (hasFileArg) { profileFile = getNextArgRequired(); fd = openFileForSystem(profileFile, "w"); if (fd == null) { return -1; } } if (start || hasFileArg) { profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming, null, false, mClockType, mProfilerOutputVersion); null, false, mClockType, mProfilerOutputVersion, mLongRunningMethods, mDurationMicros); } if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) { Loading Loading @@ -4842,6 +4863,19 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" --user <USER_ID> | current: When supplying a process name,"); pw.println(" specify user of process to profile; uses current user if not"); pw.println(" specified."); pw.println(" profile lowoverhead start [--longrunning --duration DURATION] <PROCESS>"); pw.println(" Starts a lowoverhead trace on a process. The given <PROCESS>"); pw.println(" argument may be either a process name or pid. Options are:"); pw.println(" --longrunning: Traces methods that run longer than a specific"); pw.println(" threshold. This threshold is a build-time constant"); pw.println(" --duration DURATION: trace for the specified DURATION milliseconds."); pw.println(" This argument only applies for long running traces. A default"); pw.println(" value is used when duration is not specified."); pw.println(" profile lowoverhead stop <PROCESS> [<FILE>]"); pw.println(" Stops an ongoing lowoverhead trace on a process. The given"); pw.println(" <PROCESS> argument may be either a process name or pid."); pw.println(" An optional <FILE> argument may be provided to dump the"); pw.println(" collected trace"); pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] [-b <format>] "); pw.println(" <PROCESS> <FILE>"); pw.println(" Dump the heap of a process. The given <PROCESS> argument may"); Loading Loading
core/java/android/app/ActivityThread.java +8 −1 Original line number Diff line number Diff line Loading @@ -7265,7 +7265,14 @@ public final class ActivityThread extends ClientTransactionHandler Slog.w(TAG, "Low overhead tracing feature is not enabled"); break; } if (profilerInfo.profileLongRunningMethods) { long microToNano = 1000; VMDebug.startLowOverheadTraceForLongRunningMethods( profilerInfo.durationMicros * microToNano); } else { VMDebug.startLowOverheadTraceForAllMethods(); } break; default: try { Loading
core/java/android/app/ProfilerInfo.java +28 −3 Original line number Diff line number Diff line Loading @@ -98,9 +98,19 @@ public class ProfilerInfo implements Parcelable { */ public final int profilerOutputVersion; /** * Indicates if we should trace long running methods for lowoverhead tracing */ public final boolean profileLongRunningMethods; /** * The duration in microseconds for which the lowoverhed tracing has to be run */ public final long durationMicros; public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop, boolean streaming, String agent, boolean attachAgentDuringBind, int clockType, int profilerOutputVersion) { int profilerOutputVersion, boolean profileLongRunningMethods, long durationMicros) { profileFile = filename; profileFd = fd; samplingInterval = interval; Loading @@ -110,6 +120,8 @@ public class ProfilerInfo implements Parcelable { this.agent = agent; this.attachAgentDuringBind = attachAgentDuringBind; this.profilerOutputVersion = profilerOutputVersion; this.profileLongRunningMethods = profileLongRunningMethods; this.durationMicros = durationMicros; } public ProfilerInfo(ProfilerInfo in) { Loading @@ -122,6 +134,8 @@ public class ProfilerInfo implements Parcelable { attachAgentDuringBind = in.attachAgentDuringBind; clockType = in.clockType; profilerOutputVersion = in.profilerOutputVersion; profileLongRunningMethods = in.profileLongRunningMethods; durationMicros = in.durationMicros; } /** Loading Loading @@ -165,7 +179,8 @@ public class ProfilerInfo implements Parcelable { public ProfilerInfo setAgent(String agent, boolean attachAgentDuringBind) { return new ProfilerInfo(this.profileFile, this.profileFd, this.samplingInterval, this.autoStopProfiler, this.streamingOutput, agent, attachAgentDuringBind, this.clockType, this.profilerOutputVersion); this.clockType, this.profilerOutputVersion, this.profileLongRunningMethods, this.durationMicros); } /** Loading Loading @@ -207,6 +222,8 @@ public class ProfilerInfo implements Parcelable { out.writeBoolean(attachAgentDuringBind); out.writeInt(clockType); out.writeInt(profilerOutputVersion); out.writeBoolean(profileLongRunningMethods); out.writeLong(durationMicros); } /** @hide */ Loading @@ -222,6 +239,8 @@ public class ProfilerInfo implements Parcelable { proto.write(ProfilerInfoProto.AGENT, agent); proto.write(ProfilerInfoProto.CLOCK_TYPE, clockType); proto.write(ProfilerInfoProto.PROFILER_OUTPUT_VERSION, profilerOutputVersion); proto.write(ProfilerInfoProto.PROFILE_LONG_RUNNING_METHODS, profileLongRunningMethods); proto.write(ProfilerInfoProto.DURATION_MICROS, durationMicros); proto.end(token); } Loading @@ -248,6 +267,8 @@ public class ProfilerInfo implements Parcelable { attachAgentDuringBind = in.readBoolean(); clockType = in.readInt(); profilerOutputVersion = in.readInt(); profileLongRunningMethods = in.readBoolean(); durationMicros = in.readLong(); } @Override Loading @@ -265,7 +286,9 @@ public class ProfilerInfo implements Parcelable { && samplingInterval == other.samplingInterval && streamingOutput == other.streamingOutput && Objects.equals(agent, other.agent) && clockType == other.clockType && profilerOutputVersion == other.profilerOutputVersion; && profilerOutputVersion == other.profilerOutputVersion && profileLongRunningMethods == other.profileLongRunningMethods && durationMicros == other.durationMicros; } @Override Loading @@ -278,6 +301,8 @@ public class ProfilerInfo implements Parcelable { result = 31 * result + Objects.hashCode(agent); result = 31 * result + clockType; result = 31 * result + profilerOutputVersion; result = 31 * result + (profileLongRunningMethods ? 1 : 0); result = 31 * result + Long.hashCode(durationMicros); return result; } }
core/proto/android/app/profilerinfo.proto +4 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ message ProfilerInfoProto { // Name of profile output file. optional string profile_file = 1; optional int32 profile_fd = 2; // The sampling interval rate in microseconds. optional int32 sampling_interval = 3; optional bool auto_stop_profiler = 4; optional bool streaming_output = 5; Loading @@ -37,4 +38,7 @@ message ProfilerInfoProto { optional string agent = 6; optional int32 clock_type = 7; optional int32 profiler_output_version = 8; optional bool profile_long_running_methods = 9; // Duration in microseconds for which the tracing needs to run. optional int64 duration_micros = 10; }
services/core/java/com/android/server/am/ActivityManagerService.java +4 −2 Original line number Diff line number Diff line Loading @@ -15916,8 +15916,10 @@ public class ActivityManagerService extends IActivityManager.Stub + android.Manifest.permission.SET_ACTIVITY_WATCHER); } if (start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR && (profilerInfo == null || profilerInfo.profileFd == null)) { if (start && (profilerInfo == null || (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR && profilerInfo.profileFd == null))) { throw new IllegalArgumentException("null profile info or fd"); }
services/core/java/com/android/server/am/ActivityManagerShellCommand.java +41 −7 Original line number Diff line number Diff line Loading @@ -223,6 +223,8 @@ final class ActivityManagerShellCommand extends ShellCommand { private boolean mAttachAgentDuringBind; // Whether agent should be attached late. private int mClockType; // Whether we need thread cpu / wall clock / both. private int mProfilerOutputVersion; // The version of the profiler output. private boolean mLongRunningMethods; // Whether we need to trace only long running methods private long mDurationMicros; // duration in microseconds that specifies how long to trace. private int mDisplayId; private int mTaskDisplayAreaFeatureId; private int mWindowingMode; Loading Loading @@ -608,6 +610,8 @@ final class ActivityManagerShellCommand extends ShellCommand { mSamplingInterval = 0; mAutoStop = false; mStreaming = false; mLongRunningMethods = false; mDurationMicros = 0; mUserId = defUser; mDisplayId = INVALID_DISPLAY; mTaskDisplayAreaFeatureId = FEATURE_UNDEFINED; Loading Loading @@ -808,9 +812,9 @@ final class ActivityManagerShellCommand extends ShellCommand { return 1; } } profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, mStreaming, mAgent, mAttachAgentDuringBind, mClockType, mProfilerOutputVersion); profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, mStreaming, mAgent, mAttachAgentDuringBind, mClockType, mProfilerOutputVersion, mLongRunningMethods, mDurationMicros); } pw.println("Starting: " + intent); Loading Loading @@ -1173,6 +1177,8 @@ final class ActivityManagerShellCommand extends ShellCommand { mSamplingInterval = 0; mStreaming = false; mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT; mLongRunningMethods = false; mDurationMicros = 0; mProfilerOutputVersion = ProfilerInfo.OUTPUT_VERSION_DEFAULT; String process = null; Loading Loading @@ -1217,6 +1223,16 @@ final class ActivityManagerShellCommand extends ShellCommand { cmd = getNextArgRequired(); if ("start".equals(cmd)) { start = true; String opt; while ((opt = getNextOption()) != null) { if (opt.equals("--longrunning")) { mLongRunningMethods = true; } else if (opt.equals("--duration")) { // Convert milliseconds to micro seconds long milliToMicro = 1000; mDurationMicros = Long.parseLong(getNextArgRequired()) * milliToMicro; } } } else if ("stop".equals(cmd)) { start = false; } else { Loading Loading @@ -1245,16 +1261,21 @@ final class ActivityManagerShellCommand extends ShellCommand { // For regular method tracing profileFile should be provided with the start command. For // low overhead method tracing the profileFile is optional and provided with the stop // command. if ((start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR) || (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD && !start && getRemainingArgsCount() > 0)) { boolean hasFileArg = (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR && start) || (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD && !start && getRemainingArgsCount() > 0); if (hasFileArg) { profileFile = getNextArgRequired(); fd = openFileForSystem(profileFile, "w"); if (fd == null) { return -1; } } if (start || hasFileArg) { profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming, null, false, mClockType, mProfilerOutputVersion); null, false, mClockType, mProfilerOutputVersion, mLongRunningMethods, mDurationMicros); } if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) { Loading Loading @@ -4842,6 +4863,19 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" --user <USER_ID> | current: When supplying a process name,"); pw.println(" specify user of process to profile; uses current user if not"); pw.println(" specified."); pw.println(" profile lowoverhead start [--longrunning --duration DURATION] <PROCESS>"); pw.println(" Starts a lowoverhead trace on a process. The given <PROCESS>"); pw.println(" argument may be either a process name or pid. Options are:"); pw.println(" --longrunning: Traces methods that run longer than a specific"); pw.println(" threshold. This threshold is a build-time constant"); pw.println(" --duration DURATION: trace for the specified DURATION milliseconds."); pw.println(" This argument only applies for long running traces. A default"); pw.println(" value is used when duration is not specified."); pw.println(" profile lowoverhead stop <PROCESS> [<FILE>]"); pw.println(" Stops an ongoing lowoverhead trace on a process. The given"); pw.println(" <PROCESS> argument may be either a process name or pid."); pw.println(" An optional <FILE> argument may be provided to dump the"); pw.println(" collected trace"); pw.println(" dumpheap [--user <USER_ID> current] [-n] [-g] [-b <format>] "); pw.println(" <PROCESS> <FILE>"); pw.println(" Dump the heap of a process. The given <PROCESS> argument may"); Loading