am a3a75d95: am b9314021: atrace: enable running on user builds

* commit 'a3a75d956e502f924dc29f4f29c7d46f0f8e4e56':
  atrace: enable running on user builds
diff --git a/atrace/Android.mk b/atrace/Android.mk
index 1de8e95..12526d0 100644
--- a/atrace/Android.mk
+++ b/atrace/Android.mk
@@ -10,8 +10,8 @@
 
 LOCAL_MODULE:= atrace
 
-LOCAL_MODULE_TAGS:= debug
+LOCAL_MODULE_TAGS:= optional
 
-LOCAL_STATIC_LIBRARIES := libz
+LOCAL_SHARED_LIBRARIES := libz
 
 include $(BUILD_EXECUTABLE)
diff --git a/atrace/atrace.c b/atrace/atrace.c
index a0d4250..d81cb5c 100644
--- a/atrace/atrace.c
+++ b/atrace/atrace.c
@@ -55,6 +55,9 @@
 static const char* k_schedSwitchEnablePath =
     "/sys/kernel/debug/tracing/events/sched/sched_switch/enable";
 
+static const char* k_schedWakeupEnablePath =
+    "/sys/kernel/debug/tracing/events/sched/sched_wakeup/enable";
+
 static const char* k_cpuFreqEnablePath =
     "/sys/kernel/debug/tracing/events/power/cpu_frequency/enable";
 
@@ -132,7 +135,10 @@
 // Enable or disable tracing of the kernel scheduler switching.
 static bool setSchedSwitchTracingEnable(bool enable)
 {
-    return setKernelOptionEnable(k_schedSwitchEnablePath, enable);
+    bool ok = true;
+    ok &= setKernelOptionEnable(k_schedSwitchEnablePath, enable);
+    ok &= setKernelOptionEnable(k_schedWakeupEnablePath, enable);
+    return ok;
 }
 
 // Enable or disable tracing of the CPU clock frequency.
@@ -212,11 +218,11 @@
 }
 
 // Enable tracing in the kernel.
-static bool startTrace()
+static bool startTrace(bool isRoot)
 {
     bool ok = true;
 
-    // Set up the tracing options.
+    // Set up the tracing options that don't require root.
     ok &= setTraceOverwriteEnable(g_traceOverwrite);
     ok &= setSchedSwitchTracingEnable(g_traceSchedSwitch);
     ok &= setCpuFrequencyTracingEnable(g_traceCpuFrequency);
@@ -224,11 +230,17 @@
     if (fileExists(k_governorLoadEnablePath) || g_traceGovernorLoad) {
         ok &= setGovernorLoadTracingEnable(g_traceGovernorLoad);
     }
-    ok &= setWorkqueueTracingEnabled(g_traceWorkqueue);
-    ok &= setDiskTracingEnabled(g_traceDisk);
     ok &= setTraceBufferSizeKB(g_traceBufferSizeKB);
     ok &= setGlobalClockEnable(true);
 
+    // Set up the tracing options that do require root.  The options that
+    // require root should have errored out earlier if we're not running as
+    // root.
+    if (isRoot) {
+        ok &= setWorkqueueTracingEnabled(g_traceWorkqueue);
+        ok &= setDiskTracingEnabled(g_traceDisk);
+    }
+
     // Enable tracing.
     ok &= setTracingEnabled(true);
 
@@ -240,7 +252,7 @@
 }
 
 // Disable tracing in the kernel.
-static void stopTrace()
+static void stopTrace(bool isRoot)
 {
     // Disable tracing.
     setTracingEnabled(false);
@@ -252,9 +264,13 @@
     if (fileExists(k_governorLoadEnablePath)) {
         setGovernorLoadTracingEnable(false);
     }
-    setWorkqueueTracingEnabled(false);
     setGlobalClockEnable(false);
 
+    if (isRoot) {
+        setWorkqueueTracingEnabled(false);
+        setDiskTracingEnabled(false);
+    }
+
     // Note that we can't reset the trace buffer size here because that would
     // clear the trace before we've read it.
 }
@@ -389,16 +405,13 @@
 
 int main(int argc, char **argv)
 {
+    bool isRoot = (getuid() == 0);
+
     if (argc == 2 && 0 == strcmp(argv[1], "--help")) {
         showHelp(argv[0]);
         exit(0);
     }
 
-    if (getuid() != 0) {
-        fprintf(stderr, "error: %s must be run as root.", argv[0]);
-        exit(1);
-    }
-
     for (;;) {
         int ret;
 
@@ -426,6 +439,10 @@
             break;
 
             case 'd':
+                if (!isRoot) {
+                    fprintf(stderr, "error: tracing disk activity requires root privileges\n");
+                    exit(1);
+                }
                 g_traceDisk = true;
             break;
 
@@ -442,6 +459,10 @@
             break;
 
             case 'w':
+                if (!isRoot) {
+                    fprintf(stderr, "error: tracing kernel work queues requires root privileges\n");
+                    exit(1);
+                }
                 g_traceWorkqueue = true;
             break;
 
@@ -459,7 +480,7 @@
 
     registerSigHandler();
 
-    bool ok = startTrace();
+    bool ok = startTrace(isRoot);
 
     if (ok) {
         printf("capturing trace...");
@@ -486,7 +507,7 @@
     }
 
     // Stop the trace and restore the default settings.
-    stopTrace();
+    stopTrace(isRoot);
 
     if (ok) {
         if (!g_traceAborted) {