Loading core/java/android/app/ActivityThread.java +32 −9 Original line number Diff line number Diff line Loading @@ -6859,21 +6859,44 @@ public final class ActivityThread extends ClientTransactionHandler final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { if (start) { try { switch (profileType) { case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD: if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) { Slog.w(TAG, "Low overhead tracing feature is not enabled"); break; } VMDebug.startLowOverheadTrace(); break; default: try { mProfiler.setProfiler(profilerInfo); mProfiler.startProfiling(); break; } } catch (RuntimeException e) { Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile + " -- can the process access this path?"); } finally { profilerInfo.closeFd(); } } } else { switch (profileType) { case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD: if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) { if (profilerInfo != null) { profilerInfo.closeFd(); } Slog.w(TAG, "Low overhead tracing feature is not enabled"); break; } if (profilerInfo != null) { FileDescriptor fd = profilerInfo.profileFd.getFileDescriptor(); VMDebug.TraceDestination dst = VMDebug.TraceDestination.fromFileDescriptor(fd); VMDebug.dumpLowOverheadTrace(dst); } VMDebug.stopLowOverheadTrace(); break; default: mProfiler.stopProfiling(); break; Loading core/java/android/app/ProfilerInfo.java +6 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,12 @@ import java.util.Objects; * {@hide} */ public class ProfilerInfo implements Parcelable { // Regular profiling which provides different modes of profiling at some performance cost. public static final int PROFILE_TYPE_REGULAR = 0; // Low overhead profiling that captures a simple sliding window of past events. public static final int PROFILE_TYPE_LOW_OVERHEAD = 1; // 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 Loading services/core/java/com/android/server/am/ActivityManagerService.java +7 −4 Original line number Diff line number Diff line Loading @@ -7609,7 +7609,7 @@ public class ActivityManagerService extends IActivityManager.Stub } void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo, ApplicationInfo sdkSandboxClientApp) { ApplicationInfo sdkSandboxClientApp, int profileType) { synchronized (mAppProfiler.mProfilerLock) { if (!Build.IS_DEBUGGABLE) { boolean isAppDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; Loading @@ -7625,7 +7625,7 @@ public class ActivityManagerService extends IActivityManager.Stub + "and not profileable by shell: " + app.packageName); } } mAppProfiler.setProfileAppLPf(processName, profilerInfo); mAppProfiler.setProfileAppLPf(processName, profilerInfo, profileType); } } Loading Loading @@ -17883,7 +17883,8 @@ public class ActivityManagerService extends IActivityManager.Stub + android.Manifest.permission.SET_ACTIVITY_WATCHER); } if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { if (start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR && (profilerInfo == null || profilerInfo.profileFd == null)) { throw new IllegalArgumentException("null profile info or fd"); } Loading Loading @@ -19499,7 +19500,9 @@ public class ActivityManagerService extends IActivityManager.Stub } if (profilerInfo != null) { setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null); // We only support normal method tracing along with app startup for now. setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null, /*profileType= */ ProfilerInfo.PROFILE_TYPE_REGULAR); } wmLock.notify(); } services/core/java/com/android/server/am/ActivityManagerShellCommand.java +19 −2 Original line number Diff line number Diff line Loading @@ -1081,7 +1081,7 @@ final class ActivityManagerShellCommand extends ShellCommand { String profileFile = null; boolean start = false; int userId = UserHandle.USER_CURRENT; int profileType = 0; int profileType = ProfilerInfo.PROFILE_TYPE_REGULAR; mSamplingInterval = 0; mStreaming = false; mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT; Loading Loading @@ -1123,6 +1123,18 @@ final class ActivityManagerShellCommand extends ShellCommand { } } process = getNextArgRequired(); } else if ("lowoverhead".equals(cmd)) { // This is an experimental low overhead profiling. profileType = ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD; cmd = getNextArgRequired(); if ("start".equals(cmd)) { start = true; } else if ("stop".equals(cmd)) { start = false; } else { throw new IllegalArgumentException("Profile command not valid"); } process = getNextArgRequired(); } else { // Compatibility with old syntax: process is specified first. process = cmd; Loading @@ -1142,7 +1154,12 @@ final class ActivityManagerShellCommand extends ShellCommand { ParcelFileDescriptor fd = null; ProfilerInfo profilerInfo = null; if (start) { // 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)) { profileFile = getNextArgRequired(); fd = openFileForSystem(profileFile, "w"); if (fd == null) { Loading services/core/java/com/android/server/am/AppProfiler.java +47 −28 Original line number Diff line number Diff line Loading @@ -1990,7 +1990,7 @@ public class AppProfiler { } @GuardedBy("mProfilerLock") private void stopProfilerLPf(ProcessRecord proc, int profileType) { private void stopProfilerLPf(ProcessRecord proc, ProfilerInfo profilerInfo, int profileType) { if (proc == null || proc == mProfileData.getProfileProc()) { proc = mProfileData.getProfileProc(); profileType = mProfileType; Loading @@ -2004,7 +2004,7 @@ public class AppProfiler { return; } try { thread.profilerControl(false, null, profileType); thread.profilerControl(false, profilerInfo, profileType); } catch (RemoteException e) { throw new IllegalStateException("Process disappeared"); } Loading Loading @@ -2039,19 +2039,27 @@ public class AppProfiler { ProfilerInfo profilerInfo, int profileType) { try { if (start) { stopProfilerLPf(null, 0); boolean needsFile = (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR); stopProfilerLPf(null, null, 0); mService.setProfileApp(proc.info, proc.processName, profilerInfo, proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null); proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null, profileType); mProfileData.setProfileProc(proc); mProfileType = profileType; ParcelFileDescriptor fd = profilerInfo.profileFd; ParcelFileDescriptor fd = null; if (needsFile) { fd = profilerInfo.profileFd; try { fd = fd.dup(); } catch (IOException e) { fd = null; } profilerInfo.profileFd = fd; } proc.mProfile.getThread().profilerControl(start, profilerInfo, profileType); if (needsFile) { fd = null; try { mProfileData.getProfilerInfo().profileFd.close(); Loading @@ -2066,14 +2074,23 @@ public class AppProfiler { // whole ProfilerInfo instance is passed down! profilerInfo = null; } } } else { stopProfilerLPf(proc, profileType); boolean mayNeedFile = (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD); if (profilerInfo != null && profilerInfo.profileFd != null) { ParcelFileDescriptor fd = profilerInfo.profileFd; try { profilerInfo.profileFd.close(); if (mayNeedFile) { fd = fd.dup(); } else { fd.close(); } } catch (IOException e) { fd = null; } profilerInfo.profileFd = fd; } stopProfilerLPf(proc, profilerInfo, profileType); } return true; Loading @@ -2090,7 +2107,7 @@ public class AppProfiler { } @GuardedBy("mProfilerLock") void setProfileAppLPf(String processName, ProfilerInfo profilerInfo) { void setProfileAppLPf(String processName, ProfilerInfo profilerInfo, int profileType) { mProfileData.setProfileApp(processName); if (mProfileData.getProfilerInfo() != null) { Loading @@ -2101,8 +2118,10 @@ public class AppProfiler { } } } if (profilerInfo != null) { mProfileData.setProfilerInfo(new ProfilerInfo(profilerInfo)); mProfileType = 0; } mProfileType = profileType; } @GuardedBy("mProfilerLock") Loading Loading
core/java/android/app/ActivityThread.java +32 −9 Original line number Diff line number Diff line Loading @@ -6859,21 +6859,44 @@ public final class ActivityThread extends ClientTransactionHandler final void handleProfilerControl(boolean start, ProfilerInfo profilerInfo, int profileType) { if (start) { try { switch (profileType) { case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD: if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) { Slog.w(TAG, "Low overhead tracing feature is not enabled"); break; } VMDebug.startLowOverheadTrace(); break; default: try { mProfiler.setProfiler(profilerInfo); mProfiler.startProfiling(); break; } } catch (RuntimeException e) { Slog.w(TAG, "Profiling failed on path " + profilerInfo.profileFile + " -- can the process access this path?"); } finally { profilerInfo.closeFd(); } } } else { switch (profileType) { case ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD: if (!com.android.art.flags.Flags.alwaysEnableProfileCode()) { if (profilerInfo != null) { profilerInfo.closeFd(); } Slog.w(TAG, "Low overhead tracing feature is not enabled"); break; } if (profilerInfo != null) { FileDescriptor fd = profilerInfo.profileFd.getFileDescriptor(); VMDebug.TraceDestination dst = VMDebug.TraceDestination.fromFileDescriptor(fd); VMDebug.dumpLowOverheadTrace(dst); } VMDebug.stopLowOverheadTrace(); break; default: mProfiler.stopProfiling(); break; Loading
core/java/android/app/ProfilerInfo.java +6 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,12 @@ import java.util.Objects; * {@hide} */ public class ProfilerInfo implements Parcelable { // Regular profiling which provides different modes of profiling at some performance cost. public static final int PROFILE_TYPE_REGULAR = 0; // Low overhead profiling that captures a simple sliding window of past events. public static final int PROFILE_TYPE_LOW_OVERHEAD = 1; // 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 Loading
services/core/java/com/android/server/am/ActivityManagerService.java +7 −4 Original line number Diff line number Diff line Loading @@ -7609,7 +7609,7 @@ public class ActivityManagerService extends IActivityManager.Stub } void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo, ApplicationInfo sdkSandboxClientApp) { ApplicationInfo sdkSandboxClientApp, int profileType) { synchronized (mAppProfiler.mProfilerLock) { if (!Build.IS_DEBUGGABLE) { boolean isAppDebuggable = (app.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0; Loading @@ -7625,7 +7625,7 @@ public class ActivityManagerService extends IActivityManager.Stub + "and not profileable by shell: " + app.packageName); } } mAppProfiler.setProfileAppLPf(processName, profilerInfo); mAppProfiler.setProfileAppLPf(processName, profilerInfo, profileType); } } Loading Loading @@ -17883,7 +17883,8 @@ public class ActivityManagerService extends IActivityManager.Stub + android.Manifest.permission.SET_ACTIVITY_WATCHER); } if (start && (profilerInfo == null || profilerInfo.profileFd == null)) { if (start && profileType == ProfilerInfo.PROFILE_TYPE_REGULAR && (profilerInfo == null || profilerInfo.profileFd == null)) { throw new IllegalArgumentException("null profile info or fd"); } Loading Loading @@ -19499,7 +19500,9 @@ public class ActivityManagerService extends IActivityManager.Stub } if (profilerInfo != null) { setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null); // We only support normal method tracing along with app startup for now. setProfileApp(aInfo.applicationInfo, aInfo.processName, profilerInfo, null, /*profileType= */ ProfilerInfo.PROFILE_TYPE_REGULAR); } wmLock.notify(); }
services/core/java/com/android/server/am/ActivityManagerShellCommand.java +19 −2 Original line number Diff line number Diff line Loading @@ -1081,7 +1081,7 @@ final class ActivityManagerShellCommand extends ShellCommand { String profileFile = null; boolean start = false; int userId = UserHandle.USER_CURRENT; int profileType = 0; int profileType = ProfilerInfo.PROFILE_TYPE_REGULAR; mSamplingInterval = 0; mStreaming = false; mClockType = ProfilerInfo.CLOCK_TYPE_DEFAULT; Loading Loading @@ -1123,6 +1123,18 @@ final class ActivityManagerShellCommand extends ShellCommand { } } process = getNextArgRequired(); } else if ("lowoverhead".equals(cmd)) { // This is an experimental low overhead profiling. profileType = ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD; cmd = getNextArgRequired(); if ("start".equals(cmd)) { start = true; } else if ("stop".equals(cmd)) { start = false; } else { throw new IllegalArgumentException("Profile command not valid"); } process = getNextArgRequired(); } else { // Compatibility with old syntax: process is specified first. process = cmd; Loading @@ -1142,7 +1154,12 @@ final class ActivityManagerShellCommand extends ShellCommand { ParcelFileDescriptor fd = null; ProfilerInfo profilerInfo = null; if (start) { // 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)) { profileFile = getNextArgRequired(); fd = openFileForSystem(profileFile, "w"); if (fd == null) { Loading
services/core/java/com/android/server/am/AppProfiler.java +47 −28 Original line number Diff line number Diff line Loading @@ -1990,7 +1990,7 @@ public class AppProfiler { } @GuardedBy("mProfilerLock") private void stopProfilerLPf(ProcessRecord proc, int profileType) { private void stopProfilerLPf(ProcessRecord proc, ProfilerInfo profilerInfo, int profileType) { if (proc == null || proc == mProfileData.getProfileProc()) { proc = mProfileData.getProfileProc(); profileType = mProfileType; Loading @@ -2004,7 +2004,7 @@ public class AppProfiler { return; } try { thread.profilerControl(false, null, profileType); thread.profilerControl(false, profilerInfo, profileType); } catch (RemoteException e) { throw new IllegalStateException("Process disappeared"); } Loading Loading @@ -2039,19 +2039,27 @@ public class AppProfiler { ProfilerInfo profilerInfo, int profileType) { try { if (start) { stopProfilerLPf(null, 0); boolean needsFile = (profileType == ProfilerInfo.PROFILE_TYPE_REGULAR); stopProfilerLPf(null, null, 0); mService.setProfileApp(proc.info, proc.processName, profilerInfo, proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null); proc.isSdkSandbox ? proc.getClientInfoForSdkSandbox() : null, profileType); mProfileData.setProfileProc(proc); mProfileType = profileType; ParcelFileDescriptor fd = profilerInfo.profileFd; ParcelFileDescriptor fd = null; if (needsFile) { fd = profilerInfo.profileFd; try { fd = fd.dup(); } catch (IOException e) { fd = null; } profilerInfo.profileFd = fd; } proc.mProfile.getThread().profilerControl(start, profilerInfo, profileType); if (needsFile) { fd = null; try { mProfileData.getProfilerInfo().profileFd.close(); Loading @@ -2066,14 +2074,23 @@ public class AppProfiler { // whole ProfilerInfo instance is passed down! profilerInfo = null; } } } else { stopProfilerLPf(proc, profileType); boolean mayNeedFile = (profileType == ProfilerInfo.PROFILE_TYPE_LOW_OVERHEAD); if (profilerInfo != null && profilerInfo.profileFd != null) { ParcelFileDescriptor fd = profilerInfo.profileFd; try { profilerInfo.profileFd.close(); if (mayNeedFile) { fd = fd.dup(); } else { fd.close(); } } catch (IOException e) { fd = null; } profilerInfo.profileFd = fd; } stopProfilerLPf(proc, profilerInfo, profileType); } return true; Loading @@ -2090,7 +2107,7 @@ public class AppProfiler { } @GuardedBy("mProfilerLock") void setProfileAppLPf(String processName, ProfilerInfo profilerInfo) { void setProfileAppLPf(String processName, ProfilerInfo profilerInfo, int profileType) { mProfileData.setProfileApp(processName); if (mProfileData.getProfilerInfo() != null) { Loading @@ -2101,8 +2118,10 @@ public class AppProfiler { } } } if (profilerInfo != null) { mProfileData.setProfilerInfo(new ProfilerInfo(profilerInfo)); mProfileType = 0; } mProfileType = profileType; } @GuardedBy("mProfilerLock") Loading