diff options
5 files changed, 74 insertions, 18 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 1ac887b11603..5330feffe8c0 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -968,6 +968,7 @@ public final class ActivityThread extends ClientTransactionHandler boolean autoStopProfiler; boolean streamingOutput; int mClockType; + int mProfilerOutputVersion; boolean profiling; boolean handlingProfiling; public void setProfiler(ProfilerInfo profilerInfo) { @@ -995,6 +996,7 @@ public final class ActivityThread extends ClientTransactionHandler autoStopProfiler = profilerInfo.autoStopProfiler; streamingOutput = profilerInfo.streamingOutput; mClockType = profilerInfo.clockType; + mProfilerOutputVersion = profilerInfo.profilerOutputVersion; } public void startProfiling() { if (profileFd == null || profiling) { @@ -1002,9 +1004,11 @@ public final class ActivityThread extends ClientTransactionHandler } try { int bufferSize = SystemProperties.getInt("debug.traceview-buffer-size-mb", 8); + int flags = 0; + flags = mClockType | ProfilerInfo.getFlagsForOutputVersion(mProfilerOutputVersion); VMDebug.startMethodTracing(profileFile, profileFd.getFileDescriptor(), - bufferSize * 1024 * 1024, mClockType, samplingInterval != 0, - samplingInterval, streamingOutput); + bufferSize * 1024 * 1024, flags, samplingInterval != 0, samplingInterval, + streamingOutput); profiling = true; } catch (RuntimeException e) { Slog.w(TAG, "Profiling failed on path " + profileFile, e); @@ -7052,6 +7056,7 @@ public final class ActivityThread extends ClientTransactionHandler mProfiler.autoStopProfiler = data.initProfilerInfo.autoStopProfiler; mProfiler.streamingOutput = data.initProfilerInfo.streamingOutput; mProfiler.mClockType = data.initProfilerInfo.clockType; + mProfiler.mProfilerOutputVersion = data.initProfilerInfo.profilerOutputVersion; if (data.initProfilerInfo.attachAgentDuringBind) { agent = data.initProfilerInfo.agent; } diff --git a/core/java/android/app/ProfilerInfo.java b/core/java/android/app/ProfilerInfo.java index f7a3d78af207..bcae22a38f9e 100644 --- a/core/java/android/app/ProfilerInfo.java +++ b/core/java/android/app/ProfilerInfo.java @@ -32,7 +32,8 @@ import java.util.Objects; * {@hide} */ public class ProfilerInfo implements Parcelable { - + // Version of the profiler output + public static final int OUTPUT_VERSION_DEFAULT = 1; // CLOCK_TYPE_DEFAULT chooses the default used by ART. ART uses CLOCK_TYPE_DUAL by default (see // kDefaultTraceClockSource in art/runtime/runtime_globals.h). public static final int CLOCK_TYPE_DEFAULT = 0x000; @@ -43,6 +44,9 @@ public class ProfilerInfo implements Parcelable { public static final int CLOCK_TYPE_WALL = 0x010; public static final int CLOCK_TYPE_THREAD_CPU = 0x100; public static final int CLOCK_TYPE_DUAL = 0x110; + // The second and third bits of the flags field specify the trace format version. This should + // match with kTraceFormatVersionShift defined in art/runtime/trace.h. + public static final int TRACE_FORMAT_VERSION_SHIFT = 1; private static final String TAG = "ProfilerInfo"; @@ -83,8 +87,14 @@ public class ProfilerInfo implements Parcelable { */ public final int clockType; + /** + * Indicates the version of profiler output. + */ + public final int profilerOutputVersion; + public ProfilerInfo(String filename, ParcelFileDescriptor fd, int interval, boolean autoStop, - boolean streaming, String agent, boolean attachAgentDuringBind, int clockType) { + boolean streaming, String agent, boolean attachAgentDuringBind, int clockType, + int profilerOutputVersion) { profileFile = filename; profileFd = fd; samplingInterval = interval; @@ -93,6 +103,7 @@ public class ProfilerInfo implements Parcelable { this.clockType = clockType; this.agent = agent; this.attachAgentDuringBind = attachAgentDuringBind; + this.profilerOutputVersion = profilerOutputVersion; } public ProfilerInfo(ProfilerInfo in) { @@ -104,6 +115,7 @@ public class ProfilerInfo implements Parcelable { agent = in.agent; attachAgentDuringBind = in.attachAgentDuringBind; clockType = in.clockType; + profilerOutputVersion = in.profilerOutputVersion; } /** @@ -125,13 +137,29 @@ public class ProfilerInfo implements Parcelable { } /** + * Get the flags that need to be passed to VMDebug.startMethodTracing to specify the desired + * output format. + */ + public static int getFlagsForOutputVersion(int version) { + // Only two version 1 and version 2 are supported. Just use the default if we see an unknown + // version. + if (version != 1 || version != 2) { + version = OUTPUT_VERSION_DEFAULT; + } + + // The encoded version in the flags starts from 0, where as the version that we read from + // user starts from 1. So, subtract one before encoding it in the flags. + return (version - 1) << TRACE_FORMAT_VERSION_SHIFT; + } + + /** * Return a new ProfilerInfo instance, with fields populated from this object, * and {@link agent} and {@link attachAgentDuringBind} as given. */ 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.clockType, this.profilerOutputVersion); } /** @@ -172,6 +200,7 @@ public class ProfilerInfo implements Parcelable { out.writeString(agent); out.writeBoolean(attachAgentDuringBind); out.writeInt(clockType); + out.writeInt(profilerOutputVersion); } /** @hide */ @@ -186,6 +215,7 @@ public class ProfilerInfo implements Parcelable { proto.write(ProfilerInfoProto.STREAMING_OUTPUT, streamingOutput); proto.write(ProfilerInfoProto.AGENT, agent); proto.write(ProfilerInfoProto.CLOCK_TYPE, clockType); + proto.write(ProfilerInfoProto.PROFILER_OUTPUT_VERSION, profilerOutputVersion); proto.end(token); } @@ -211,6 +241,7 @@ public class ProfilerInfo implements Parcelable { agent = in.readString(); attachAgentDuringBind = in.readBoolean(); clockType = in.readInt(); + profilerOutputVersion = in.readInt(); } @Override @@ -226,9 +257,9 @@ public class ProfilerInfo implements Parcelable { return Objects.equals(profileFile, other.profileFile) && autoStopProfiler == other.autoStopProfiler && samplingInterval == other.samplingInterval - && streamingOutput == other.streamingOutput - && Objects.equals(agent, other.agent) - && clockType == other.clockType; + && streamingOutput == other.streamingOutput && Objects.equals(agent, other.agent) + && clockType == other.clockType + && profilerOutputVersion == other.profilerOutputVersion; } @Override @@ -240,6 +271,7 @@ public class ProfilerInfo implements Parcelable { result = 31 * result + (streamingOutput ? 1 : 0); result = 31 * result + Objects.hashCode(agent); result = 31 * result + clockType; + result = 31 * result + profilerOutputVersion; return result; } } diff --git a/core/proto/android/app/profilerinfo.proto b/core/proto/android/app/profilerinfo.proto index 86261ecdf54e..9941b83c1cb9 100644 --- a/core/proto/android/app/profilerinfo.proto +++ b/core/proto/android/app/profilerinfo.proto @@ -36,4 +36,5 @@ message ProfilerInfoProto { // Denotes an agent (and its parameters) to attach for profiling. optional string agent = 6; optional int32 clock_type = 7; + optional int32 profiler_output_version = 8; } diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index de039fbdd509..c13f02ebdf1b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -173,6 +173,8 @@ final class ActivityManagerShellCommand extends ShellCommand { private static final DateTimeFormatter LOG_NAME_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss", Locale.ROOT); + private static final String PROFILER_OUTPUT_VERSION_FLAG = "--profiler-output-version"; + // IPC interface to activity manager -- don't need to do additional security checks. final IActivityManager mInterface; final IActivityTaskManager mTaskInterface; @@ -198,6 +200,7 @@ final class ActivityManagerShellCommand extends ShellCommand { private String mAgent; // Agent to attach on startup. 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 int mDisplayId; private int mTaskDisplayAreaFeatureId; private int mWindowingMode; @@ -526,6 +529,8 @@ final class ActivityManagerShellCommand extends ShellCommand { } else if (opt.equals("--clock-type")) { String clock_type = getNextArgRequired(); mClockType = ProfilerInfo.getClockTypeFromString(clock_type); + } else if (opt.equals(PROFILER_OUTPUT_VERSION_FLAG)) { + mProfilerOutputVersion = Integer.parseInt(getNextArgRequired()); } else if (opt.equals("--streaming")) { mStreaming = true; } else if (opt.equals("--attach-agent")) { @@ -578,7 +583,7 @@ final class ActivityManagerShellCommand extends ShellCommand { } else if (opt.equals("--splashscreen-show-icon")) { mShowSplashScreen = true; } else if (opt.equals("--dismiss-keyguard-if-insecure") - || opt.equals("--dismiss-keyguard")) { + || opt.equals("--dismiss-keyguard")) { mDismissKeyguardIfInsecure = true; } else { return false; @@ -684,8 +689,9 @@ final class ActivityManagerShellCommand extends ShellCommand { return 1; } } - profilerInfo = new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, - mStreaming, mAgent, mAttachAgentDuringBind, mClockType); + profilerInfo = + new ProfilerInfo(mProfileFile, fd, mSamplingInterval, mAutoStop, mStreaming, + mAgent, mAttachAgentDuringBind, mClockType, mProfilerOutputVersion); } pw.println("Starting: " + intent); @@ -1028,6 +1034,7 @@ final class ActivityManagerShellCommand extends ShellCommand { mSamplingInterval = 0; mStreaming = false; mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT; + mProfilerOutputVersion = ProfilerInfo.OUTPUT_VERSION_DEFAULT; String process = null; @@ -1042,6 +1049,8 @@ final class ActivityManagerShellCommand extends ShellCommand { } else if (opt.equals("--clock-type")) { String clock_type = getNextArgRequired(); mClockType = ProfilerInfo.getClockTypeFromString(clock_type); + } else if (opt.equals(PROFILER_OUTPUT_VERSION_FLAG)) { + mProfilerOutputVersion = Integer.parseInt(getNextArgRequired()); } else if (opt.equals("--streaming")) { mStreaming = true; } else if (opt.equals("--sampling")) { @@ -1089,7 +1098,7 @@ final class ActivityManagerShellCommand extends ShellCommand { return -1; } profilerInfo = new ProfilerInfo(profileFile, fd, mSamplingInterval, false, mStreaming, - null, false, mClockType); + null, false, mClockType, mProfilerOutputVersion); } if (!mInterface.profileControl(process, userId, start, profilerInfo, profileType)) { @@ -4177,6 +4186,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" Print this help text."); pw.println(" start-activity [-D] [-N] [-W] [-P <FILE>] [--start-profiler <FILE>]"); pw.println(" [--sampling INTERVAL] [--clock-type <TYPE>] [--streaming]"); + pw.println(" [" + PROFILER_OUTPUT_VERSION_FLAG + " NUMBER]"); pw.println(" [-R COUNT] [-S] [--track-allocation]"); pw.println(" [--user <USER_ID> | current] [--suspend] <INTENT>"); pw.println(" Start an Activity. Options are:"); @@ -4192,6 +4202,8 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" The default value is dual. (use with --start-profiler)"); pw.println(" --streaming: stream the profiling output to the specified file"); pw.println(" (use with --start-profiler)"); + pw.println(" " + PROFILER_OUTPUT_VERSION_FLAG + " Specify the version of the"); + pw.println(" profiling output (use with --start-profiler)"); pw.println(" -P <FILE>: like above, but profiling stops when app goes idle"); pw.println(" --attach-agent <agent>: attach the given agent before binding"); pw.println(" --attach-agent-bind <agent>: attach the given agent during binding"); @@ -4283,6 +4295,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to."); pw.println(" profile start [--user <USER_ID> current]"); pw.println(" [--clock-type <TYPE>]"); + pw.println(" [" + PROFILER_OUTPUT_VERSION_FLAG + " VERSION]"); pw.println(" [--sampling INTERVAL | --streaming] <PROCESS> <FILE>"); pw.println(" Start profiler on a process. The given <PROCESS> argument"); pw.println(" may be either a process name or pid. Options are:"); @@ -4292,6 +4305,8 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" --clock-type <TYPE>: use the specified clock to report timestamps."); pw.println(" The type can be one of wall | thread-cpu | dual. The default"); pw.println(" value is dual."); + pw.println(" " + PROFILER_OUTPUT_VERSION_FLAG + "VERSION: specifies the output"); + pw.println(" format version"); pw.println(" --sampling INTERVAL: use sample profiling with INTERVAL microseconds"); pw.println(" between samples."); pw.println(" --streaming: stream the profiling output to the specified file."); diff --git a/services/core/java/com/android/server/am/AppProfiler.java b/services/core/java/com/android/server/am/AppProfiler.java index 9b091b3a9c17..1dab8c72bc9f 100644 --- a/services/core/java/com/android/server/am/AppProfiler.java +++ b/services/core/java/com/android/server/am/AppProfiler.java @@ -2484,8 +2484,8 @@ public class AppProfiler { } } } else if (instr != null && instr.mProfileFile != null) { - profilerInfo = new ProfilerInfo(instr.mProfileFile, null, 0, false, false, - null, false, 0); + profilerInfo = new ProfilerInfo(instr.mProfileFile, null, 0, false, false, null, + false, 0, ProfilerInfo.OUTPUT_VERSION_DEFAULT); } if (mAppAgentMap != null && mAppAgentMap.containsKey(processName)) { // We need to do a debuggable check here. See setAgentApp for why the check is @@ -2495,7 +2495,8 @@ public class AppProfiler { // Do not overwrite already requested agent. if (profilerInfo == null) { profilerInfo = new ProfilerInfo(null, null, 0, false, false, - mAppAgentMap.get(processName), true, 0); + mAppAgentMap.get(processName), true, 0, + ProfilerInfo.OUTPUT_VERSION_DEFAULT); } else if (profilerInfo.agent == null) { profilerInfo = profilerInfo.setAgent(mAppAgentMap.get(processName), true); } @@ -2622,14 +2623,16 @@ public class AppProfiler { if (mProfileData.getProfilerInfo() != null) { pw.println(" mProfileFile=" + mProfileData.getProfilerInfo().profileFile + " mProfileFd=" + mProfileData.getProfilerInfo().profileFd); - pw.println(" mSamplingInterval=" - + mProfileData.getProfilerInfo().samplingInterval + pw.println( + " mSamplingInterval=" + mProfileData.getProfilerInfo().samplingInterval + " mAutoStopProfiler=" + mProfileData.getProfilerInfo().autoStopProfiler + " mStreamingOutput=" + mProfileData.getProfilerInfo().streamingOutput + " mClockType=" - + mProfileData.getProfilerInfo().clockType); + + mProfileData.getProfilerInfo().clockType + + " mProfilerOutputVersion=" + + mProfileData.getProfilerInfo().profilerOutputVersion); pw.println(" mProfileType=" + mProfileType); } } |