Convert looper traces to traceview traces

Change-Id: If9238e8b00744118c1c4d2182727569f94deb638
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 720e802b..c61f28a 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -130,19 +130,20 @@
                 if (logging != null) {
                     logging.println(">>>>> Dispatching to " + msg.target + " " +
                             msg.callback + ": " + msg.what);
-                    wallStart = System.currentTimeMillis();
-                    threadStart = SystemClock.currentThreadTimeMillis();
+                    wallStart = SystemClock.currentTimeMicro();
+                    threadStart = SystemClock.currentThreadTimeMicro();
                 }
 
                 msg.target.dispatchMessage(msg);
 
                 if (logging != null) {
-                    long wallTime = System.currentTimeMillis() - wallStart;
-                    long threadTime = SystemClock.currentThreadTimeMillis() - threadStart;
+                    long wallTime = SystemClock.currentTimeMicro() - wallStart;
+                    long threadTime = SystemClock.currentThreadTimeMicro() - threadStart;
 
                     logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
                     if (logging instanceof Profiler) {
-                        ((Profiler) logging).profile(msg, wallStart, wallTime, threadTime);
+                        ((Profiler) logging).profile(msg, wallStart, wallTime,
+                                threadStart, threadTime);
                     }
                 }
 
@@ -247,6 +248,7 @@
      * @hide
      */
     public static interface Profiler {
-        void profile(Message message, long wallStart, long wallTime, long threadTime);
+        void profile(Message message, long wallStart, long wallTime,
+                long threadStart, long threadTime);
     }
 }
diff --git a/core/java/android/os/SystemClock.java b/core/java/android/os/SystemClock.java
index 2dd6749..7291739 100644
--- a/core/java/android/os/SystemClock.java
+++ b/core/java/android/os/SystemClock.java
@@ -157,4 +157,22 @@
      * @return elapsed milliseconds in the thread
      */
     public static native long currentThreadTimeMillis();
+
+    /**
+     * Returns microseconds running in the current thread.
+     * 
+     * @return elapsed microseconds in the thread
+     * 
+     * @hide
+     */
+    public static native long currentThreadTimeMicro();
+
+    /**
+     * Returns current wall time in  microseconds.
+     * 
+     * @return elapsed microseconds in wall time
+     * 
+     * @hide
+     */
+    public static native long currentTimeMicro();
 }
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index b85159b..3798c9d 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -26,6 +26,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.SystemClock;
 import android.util.DisplayMetrics;
 import android.util.Log;
 import android.util.Printer;
@@ -53,6 +54,7 @@
 import java.util.HashMap;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -455,11 +457,19 @@
 
         private static final String LOG_TAG = "LooperProfiler";
 
+        private final long mTraceWallStart;
+        private final long mTraceThreadStart;
+        
         private final ArrayList<Entry> mTraces = new ArrayList<Entry>(512);
         private final File mTraceFile;
 
-        public LooperProfiler(File traceFile) {
+        private final HashMap<String, Short> mTraceNames = new HashMap<String, Short>(32);
+        private short mTraceId = 0;
+
+        LooperProfiler(File traceFile) {
             mTraceFile = traceFile;
+            mTraceWallStart = SystemClock.currentTimeMicro();
+            mTraceThreadStart = SystemClock.currentThreadTimeMicro();            
         }
 
         @Override
@@ -468,17 +478,28 @@
         }
 
         @Override
-        public void profile(Message message, long wallStart, long wallTime, long threadTime) {
+        public void profile(Message message, long wallStart, long wallTime,
+                long threadStart, long threadTime) {
             Entry entry = new Entry();
-            entry.messageId = message.what;
-            entry.name = message.getTarget().getMessageName(message);
+            entry.traceId = getTraceId(message);
             entry.wallStart = wallStart;
             entry.wallTime = wallTime;
+            entry.threadStart = threadStart;
             entry.threadTime = threadTime;
 
             mTraces.add(entry);
         }
 
+        private short getTraceId(Message message) {
+            String name = message.getTarget().getMessageName(message);
+            Short traceId = mTraceNames.get(name);
+            if (traceId == null) {
+                traceId = mTraceId++;
+                mTraceNames.put(name, traceId);
+            }
+            return traceId;
+        }
+
         void save() {
             // Don't block the UI thread
             new Thread(new Runnable() {
@@ -502,6 +523,14 @@
 
             try {
                 out.writeInt(LOOPER_PROFILER_VERSION);
+                out.writeLong(mTraceWallStart);
+                out.writeLong(mTraceThreadStart);
+
+                out.writeInt(mTraceNames.size());
+                for (Map.Entry<String, Short> entry : mTraceNames.entrySet()) {
+                    saveTraceName(entry.getKey(), entry.getValue(), out);
+                }
+
                 out.writeInt(mTraces.size());
                 for (Entry entry : mTraces) {
                     saveTrace(entry, out);
@@ -519,19 +548,24 @@
             }
         }
 
+        private void saveTraceName(String name, short id, DataOutputStream out) throws IOException {
+            out.writeShort(id);
+            out.writeUTF(name);
+        }
+
         private void saveTrace(Entry entry, DataOutputStream out) throws IOException {
-            out.writeInt(entry.messageId);
-            out.writeUTF(entry.name);
+            out.writeShort(entry.traceId);
             out.writeLong(entry.wallStart);
             out.writeLong(entry.wallTime);
+            out.writeLong(entry.threadStart);
             out.writeLong(entry.threadTime);
         }
 
         static class Entry {
-            int messageId;
-            String name;
+            short traceId;
             long wallStart;
             long wallTime;
+            long threadStart;
             long threadTime;
         }
     }
diff --git a/core/jni/android_os_SystemClock.cpp b/core/jni/android_os_SystemClock.cpp
index ffd0c1e..66d58cd 100644
--- a/core/jni/android_os_SystemClock.cpp
+++ b/core/jni/android_os_SystemClock.cpp
@@ -80,6 +80,38 @@
 }
 
 /*
+ * native public static long currentThreadTimeMicro();
+ */
+static jlong android_os_SystemClock_currentThreadTimeMicro(JNIEnv* env,
+        jobject clazz)
+{
+#if defined(HAVE_POSIX_CLOCKS)
+    struct timespec tm;
+
+    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tm);
+
+    return tm.tv_sec * 1000000LL + tm.tv_nsec / 1000;
+#else
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000LL + tv.tv_nsec / 1000;
+#endif
+}
+
+/*
+ * native public static long currentTimeMicro();
+ */
+static jlong android_os_SystemClock_currentTimeMicro(JNIEnv* env,
+        jobject clazz)
+{
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000LL + tv.tv_usec;
+}
+
+/*
  * JNI registration.
  */
 static JNINativeMethod gMethods[] = {
@@ -92,6 +124,10 @@
             (void*) android_os_SystemClock_elapsedRealtime },
     { "currentThreadTimeMillis",      "()J",
             (void*) android_os_SystemClock_currentThreadTimeMillis },
+    { "currentThreadTimeMicro",       "()J",
+            (void*) android_os_SystemClock_currentThreadTimeMicro },
+    { "currentTimeMicro",             "()J",
+            (void*) android_os_SystemClock_currentTimeMicro },
 };
 int register_android_os_SystemClock(JNIEnv* env)
 {