Loading services/core/java/com/android/server/am/ActivityManagerShellCommand.java +36 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,7 @@ import com.android.server.am.nano.VMCapability; import com.android.server.am.nano.VMInfo; import com.android.server.compat.PlatformCompat; import com.android.server.pm.UserManagerInternal; import com.android.server.utils.AnrTimer; import com.android.server.utils.Slogf; import dalvik.annotation.optimization.NeverCompile; Loading Loading @@ -285,6 +286,8 @@ final class ActivityManagerShellCommand extends ShellCommand { return -1; case "trace-ipc": return runTraceIpc(pw); case "trace-timer": return runTraceTimer(pw); case "profile": return runProfile(pw); case "dumpheap": Loading Loading @@ -1062,6 +1065,23 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } // Update AnrTimer tracing. private int runTraceTimer(PrintWriter pw) throws RemoteException { if (!AnrTimer.traceFeatureEnabled()) return -1; // Delegate all argument parsing to the AnrTimer method. try { final String result = AnrTimer.traceTimers(peekRemainingArgs()); if (result != null) { pw.println(result); } return 0; } catch (IllegalArgumentException e) { getErrPrintWriter().println("Error: bad trace-timer command: " + e); return -1; } } // NOTE: current profiles can only be started on default display (even on automotive builds with // passenger displays), so there's no need to pass a display-id private int runProfile(PrintWriter pw) throws RemoteException { Loading Loading @@ -4352,6 +4372,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" start: start tracing IPC transactions."); pw.println(" stop: stop tracing IPC transactions and dump the results to file."); pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to."); anrTimerHelp(pw); pw.println(" profile start [--user <USER_ID> current]"); pw.println(" [--clock-type <TYPE>]"); pw.println(" [" + PROFILER_OUTPUT_VERSION_FLAG + " VERSION]"); Loading Loading @@ -4605,4 +4626,19 @@ final class ActivityManagerShellCommand extends ShellCommand { Intent.printIntentArgsHelp(pw, ""); } } static void anrTimerHelp(PrintWriter pw) { // Return silently if tracing is not feature-enabled. if (!AnrTimer.traceFeatureEnabled()) return; String h = AnrTimer.traceTimers(new String[]{"help"}); if (h == null) { return; } pw.println(" trace-timer <cmd>"); for (String s : h.split("\n")) { pw.println(" " + s); } } } services/core/java/com/android/server/utils/AnrTimer.java +45 −11 Original line number Diff line number Diff line Loading @@ -130,22 +130,35 @@ public abstract class AnrTimer<V> implements AutoCloseable { } /** * Return true if freezing is enabled. This has no effect if the service is not enabled. * Return true if freezing is feature-enabled. Freezing must still be enabled on a * per-service basis. */ private static boolean anrTimerFreezerEnabled() { private static boolean freezerFeatureEnabled() { return Flags.anrTimerFreezer(); } /** * Return true if tracing is feature-enabled. This has no effect unless tracing is configured. * Note that this does not represent any per-process overrides via an Injector. */ public static boolean traceFeatureEnabled() { return anrTimerServiceEnabled() && Flags.anrTimerTrace(); } /** * This class allows test code to provide instance-specific overrides. */ static class Injector { boolean anrTimerServiceEnabled() { boolean serviceEnabled() { return AnrTimer.anrTimerServiceEnabled(); } boolean anrTimerFreezerEnabled() { return AnrTimer.anrTimerFreezerEnabled(); boolean freezerEnabled() { return AnrTimer.freezerFeatureEnabled(); } boolean traceEnabled() { return AnrTimer.traceFeatureEnabled(); } } Loading Loading @@ -349,7 +362,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { mWhat = what; mLabel = label; mArgs = args; boolean enabled = args.mInjector.anrTimerServiceEnabled() && nativeTimersSupported(); boolean enabled = args.mInjector.serviceEnabled() && nativeTimersSupported(); mFeature = createFeatureSwitch(enabled); } Loading Loading @@ -448,7 +461,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** * The FeatureDisabled class bypasses almost all AnrTimer logic. It is used when the AnrTimer * service is disabled via Flags.anrTimerServiceEnabled. * service is disabled via Flags.anrTimerService(). */ private class FeatureDisabled extends FeatureSwitch { /** Start a timer by sending a message to the client's handler. */ Loading Loading @@ -515,7 +528,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** * The FeatureEnabled class enables the AnrTimer logic. It is used when the AnrTimer service * is enabled via Flags.anrTimerServiceEnabled. * is enabled via Flags.anrTimerService(). */ private class FeatureEnabled extends FeatureSwitch { Loading @@ -533,7 +546,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { FeatureEnabled() { mNative = nativeAnrTimerCreate(mLabel, mArgs.mExtend, mArgs.mFreeze && mArgs.mInjector.anrTimerFreezerEnabled()); mArgs.mFreeze && mArgs.mInjector.freezerEnabled()); if (mNative == 0) throw new IllegalArgumentException("unable to create native timer"); synchronized (sAnrTimerList) { sAnrTimerList.put(mNative, new WeakReference(AnrTimer.this)); Loading @@ -550,7 +563,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { // exist. if (cancel(arg)) mTotalRestarted++; int timerId = nativeAnrTimerStart(mNative, pid, uid, timeoutMs); final int timerId = nativeAnrTimerStart(mNative, pid, uid, timeoutMs); if (timerId > 0) { mTimerIdMap.put(arg, timerId); mTimerArgMap.put(timerId, arg); Loading Loading @@ -895,7 +908,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** Dumpsys output, allowing for overrides. */ @VisibleForTesting static void dump(@NonNull PrintWriter pw, boolean verbose, @NonNull Injector injector) { if (!injector.anrTimerServiceEnabled()) return; if (!injector.serviceEnabled()) return; final IndentingPrintWriter ipw = new IndentingPrintWriter(pw); ipw.println("AnrTimer statistics"); Loading Loading @@ -925,6 +938,18 @@ public abstract class AnrTimer<V> implements AutoCloseable { dump(pw, verbose, sDefaultInjector); } /** * Set a trace specification. The input is a set of strings. On success, the function pushes * the trace specification to all timers, and then returns a response message. On failure, * the function throws IllegalArgumentException and tracing is disabled. * * An empty specification has no effect other than returning the current trace specification. */ @Nullable public static String traceTimers(@Nullable String[] spec) { return nativeAnrTimerTrace(spec); } /** * Return true if the native timers are supported. Native timers are supported if the method * nativeAnrTimerSupported() can be executed and it returns true. Loading Loading @@ -981,6 +1006,15 @@ public abstract class AnrTimer<V> implements AutoCloseable { */ private static native boolean nativeAnrTimerRelease(long service, int timerId); /** * Configure tracing. The input array is a set of words pulled from the command line. All * parsing happens inside the native layer. The function returns a string which is either an * error message (so nothing happened) or the current configuration after applying the config. * Passing an null array or an empty array simply returns the current configuration. * The function returns null if the native layer is not implemented. */ private static native @Nullable String nativeAnrTimerTrace(@Nullable String[] config); /** Retrieve runtime dump information from the native layer. */ private static native String[] nativeAnrTimerDump(long service); } services/core/java/com/android/server/utils/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -17,3 +17,10 @@ flag { bug: "325594551" } flag { name: "anr_timer_trace" namespace: "system_performance" is_fixed_read_only: true description: "When true, start a trace if an ANR timer reaches 50%" bug: "352085328" } services/core/jni/com_android_server_utils_AnrTimer.cpp +434 −73 File changed.Preview size limit exceeded, changes collapsed. Show changes services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -119,7 +119,7 @@ public class AnrTimerTest { */ private class TestInjector extends AnrTimer.Injector { @Override boolean anrTimerServiceEnabled() { boolean serviceEnabled() { return mEnabled; } } Loading Loading
services/core/java/com/android/server/am/ActivityManagerShellCommand.java +36 −0 Original line number Diff line number Diff line Loading @@ -133,6 +133,7 @@ import com.android.server.am.nano.VMCapability; import com.android.server.am.nano.VMInfo; import com.android.server.compat.PlatformCompat; import com.android.server.pm.UserManagerInternal; import com.android.server.utils.AnrTimer; import com.android.server.utils.Slogf; import dalvik.annotation.optimization.NeverCompile; Loading Loading @@ -285,6 +286,8 @@ final class ActivityManagerShellCommand extends ShellCommand { return -1; case "trace-ipc": return runTraceIpc(pw); case "trace-timer": return runTraceTimer(pw); case "profile": return runProfile(pw); case "dumpheap": Loading Loading @@ -1062,6 +1065,23 @@ final class ActivityManagerShellCommand extends ShellCommand { return 0; } // Update AnrTimer tracing. private int runTraceTimer(PrintWriter pw) throws RemoteException { if (!AnrTimer.traceFeatureEnabled()) return -1; // Delegate all argument parsing to the AnrTimer method. try { final String result = AnrTimer.traceTimers(peekRemainingArgs()); if (result != null) { pw.println(result); } return 0; } catch (IllegalArgumentException e) { getErrPrintWriter().println("Error: bad trace-timer command: " + e); return -1; } } // NOTE: current profiles can only be started on default display (even on automotive builds with // passenger displays), so there's no need to pass a display-id private int runProfile(PrintWriter pw) throws RemoteException { Loading Loading @@ -4352,6 +4372,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" start: start tracing IPC transactions."); pw.println(" stop: stop tracing IPC transactions and dump the results to file."); pw.println(" --dump-file <FILE>: Specify the file the trace should be dumped to."); anrTimerHelp(pw); pw.println(" profile start [--user <USER_ID> current]"); pw.println(" [--clock-type <TYPE>]"); pw.println(" [" + PROFILER_OUTPUT_VERSION_FLAG + " VERSION]"); Loading Loading @@ -4605,4 +4626,19 @@ final class ActivityManagerShellCommand extends ShellCommand { Intent.printIntentArgsHelp(pw, ""); } } static void anrTimerHelp(PrintWriter pw) { // Return silently if tracing is not feature-enabled. if (!AnrTimer.traceFeatureEnabled()) return; String h = AnrTimer.traceTimers(new String[]{"help"}); if (h == null) { return; } pw.println(" trace-timer <cmd>"); for (String s : h.split("\n")) { pw.println(" " + s); } } }
services/core/java/com/android/server/utils/AnrTimer.java +45 −11 Original line number Diff line number Diff line Loading @@ -130,22 +130,35 @@ public abstract class AnrTimer<V> implements AutoCloseable { } /** * Return true if freezing is enabled. This has no effect if the service is not enabled. * Return true if freezing is feature-enabled. Freezing must still be enabled on a * per-service basis. */ private static boolean anrTimerFreezerEnabled() { private static boolean freezerFeatureEnabled() { return Flags.anrTimerFreezer(); } /** * Return true if tracing is feature-enabled. This has no effect unless tracing is configured. * Note that this does not represent any per-process overrides via an Injector. */ public static boolean traceFeatureEnabled() { return anrTimerServiceEnabled() && Flags.anrTimerTrace(); } /** * This class allows test code to provide instance-specific overrides. */ static class Injector { boolean anrTimerServiceEnabled() { boolean serviceEnabled() { return AnrTimer.anrTimerServiceEnabled(); } boolean anrTimerFreezerEnabled() { return AnrTimer.anrTimerFreezerEnabled(); boolean freezerEnabled() { return AnrTimer.freezerFeatureEnabled(); } boolean traceEnabled() { return AnrTimer.traceFeatureEnabled(); } } Loading Loading @@ -349,7 +362,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { mWhat = what; mLabel = label; mArgs = args; boolean enabled = args.mInjector.anrTimerServiceEnabled() && nativeTimersSupported(); boolean enabled = args.mInjector.serviceEnabled() && nativeTimersSupported(); mFeature = createFeatureSwitch(enabled); } Loading Loading @@ -448,7 +461,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** * The FeatureDisabled class bypasses almost all AnrTimer logic. It is used when the AnrTimer * service is disabled via Flags.anrTimerServiceEnabled. * service is disabled via Flags.anrTimerService(). */ private class FeatureDisabled extends FeatureSwitch { /** Start a timer by sending a message to the client's handler. */ Loading Loading @@ -515,7 +528,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** * The FeatureEnabled class enables the AnrTimer logic. It is used when the AnrTimer service * is enabled via Flags.anrTimerServiceEnabled. * is enabled via Flags.anrTimerService(). */ private class FeatureEnabled extends FeatureSwitch { Loading @@ -533,7 +546,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { FeatureEnabled() { mNative = nativeAnrTimerCreate(mLabel, mArgs.mExtend, mArgs.mFreeze && mArgs.mInjector.anrTimerFreezerEnabled()); mArgs.mFreeze && mArgs.mInjector.freezerEnabled()); if (mNative == 0) throw new IllegalArgumentException("unable to create native timer"); synchronized (sAnrTimerList) { sAnrTimerList.put(mNative, new WeakReference(AnrTimer.this)); Loading @@ -550,7 +563,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { // exist. if (cancel(arg)) mTotalRestarted++; int timerId = nativeAnrTimerStart(mNative, pid, uid, timeoutMs); final int timerId = nativeAnrTimerStart(mNative, pid, uid, timeoutMs); if (timerId > 0) { mTimerIdMap.put(arg, timerId); mTimerArgMap.put(timerId, arg); Loading Loading @@ -895,7 +908,7 @@ public abstract class AnrTimer<V> implements AutoCloseable { /** Dumpsys output, allowing for overrides. */ @VisibleForTesting static void dump(@NonNull PrintWriter pw, boolean verbose, @NonNull Injector injector) { if (!injector.anrTimerServiceEnabled()) return; if (!injector.serviceEnabled()) return; final IndentingPrintWriter ipw = new IndentingPrintWriter(pw); ipw.println("AnrTimer statistics"); Loading Loading @@ -925,6 +938,18 @@ public abstract class AnrTimer<V> implements AutoCloseable { dump(pw, verbose, sDefaultInjector); } /** * Set a trace specification. The input is a set of strings. On success, the function pushes * the trace specification to all timers, and then returns a response message. On failure, * the function throws IllegalArgumentException and tracing is disabled. * * An empty specification has no effect other than returning the current trace specification. */ @Nullable public static String traceTimers(@Nullable String[] spec) { return nativeAnrTimerTrace(spec); } /** * Return true if the native timers are supported. Native timers are supported if the method * nativeAnrTimerSupported() can be executed and it returns true. Loading Loading @@ -981,6 +1006,15 @@ public abstract class AnrTimer<V> implements AutoCloseable { */ private static native boolean nativeAnrTimerRelease(long service, int timerId); /** * Configure tracing. The input array is a set of words pulled from the command line. All * parsing happens inside the native layer. The function returns a string which is either an * error message (so nothing happened) or the current configuration after applying the config. * Passing an null array or an empty array simply returns the current configuration. * The function returns null if the native layer is not implemented. */ private static native @Nullable String nativeAnrTimerTrace(@Nullable String[] config); /** Retrieve runtime dump information from the native layer. */ private static native String[] nativeAnrTimerDump(long service); }
services/core/java/com/android/server/utils/flags.aconfig +7 −0 Original line number Diff line number Diff line Loading @@ -17,3 +17,10 @@ flag { bug: "325594551" } flag { name: "anr_timer_trace" namespace: "system_performance" is_fixed_read_only: true description: "When true, start a trace if an ANR timer reaches 50%" bug: "352085328" }
services/core/jni/com_android_server_utils_AnrTimer.cpp +434 −73 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/tests/servicestests/src/com/android/server/utils/AnrTimerTest.java +1 −1 Original line number Diff line number Diff line Loading @@ -119,7 +119,7 @@ public class AnrTimerTest { */ private class TestInjector extends AnrTimer.Injector { @Override boolean anrTimerServiceEnabled() { boolean serviceEnabled() { return mEnabled; } } Loading