Resolve codes to method names for binder call stats.

Test: unit test

Change-Id: Ie2178e6f9ebb900251d7c9ab20587d3c01acda83
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 20eab92..6177923 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.os;
 
+import android.annotation.Nullable;
 import android.os.Binder;
 import android.os.SystemClock;
 import android.os.UserHandle;
@@ -75,10 +76,10 @@
     }
 
     public CallSession callStarted(Binder binder, int code) {
-        return callStarted(binder.getClass().getName(), code);
+        return callStarted(binder.getClass().getName(), code, binder.getTransactionName(code));
     }
 
-    private CallSession callStarted(String className, int code) {
+    private CallSession callStarted(String className, int code, @Nullable String methodName) {
         if (!mEnabled) {
           return NOT_ENABLED;
         }
@@ -90,6 +91,7 @@
 
         s.callStat.className = className;
         s.callStat.msg = code;
+        s.callStat.methodName = methodName;
         s.exceptionThrown = false;
         s.cpuTimeStarted = -1;
         s.timeStarted = -1;
@@ -169,6 +171,7 @@
                 callStat = s.sampledCallStat;
             }
             callStat.callCount++;
+            callStat.methodName = s.callStat.methodName;
             if (s.cpuTimeStarted >= 0) {
                 callStat.cpuTimeMicros += duration;
                 callStat.maxCpuTimeMicros = Math.max(callStat.maxCpuTimeMicros, duration);
@@ -250,6 +253,7 @@
                     sb.setLength(0);
                     sb.append("    ")
                             .append(uidToString(uidEntry.uid, appIdToPkgNameMap))
+                            .append(",").append(e)
                             .append(',').append(e.cpuTimeMicros)
                             .append(',').append(e.maxCpuTimeMicros)
                             .append(',').append(e.latencyMicros)
@@ -372,6 +376,9 @@
     public static class CallStat {
         public String className;
         public int msg;
+        // Method name might be null when we cannot resolve the transaction code. For instance, if
+        // the binder was not generated by AIDL.
+        public @Nullable String methodName;
         public long cpuTimeMicros;
         public long maxCpuTimeMicros;
         public long latencyMicros;
@@ -410,7 +417,7 @@
 
         @Override
         public String toString() {
-            return className + "/" + msg;
+            return className + "#" + (methodName == null ? msg : methodName);
         }
     }
 
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 914fb74..3d34880 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -226,6 +226,26 @@
     }
 
     @Test
+    public void testTransactionCodeResolved() {
+        TestBinderCallsStats bcs = new TestBinderCallsStats();
+        bcs.setDetailedTracking(true);
+        Binder binder = new Binder() {
+            @Override
+            public String getTransactionName(int code) {
+              return "resolved";
+            }
+        };
+        BinderCallsStats.CallSession callSession = bcs.callStarted(binder, 1);
+        bcs.time += 10;
+        bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE);
+
+        List<BinderCallsStats.CallStat> callStatsList =
+                bcs.getUidEntries().get(TEST_UID).getCallStatsList();
+        assertEquals(1, callStatsList.get(0).msg);
+        assertEquals("resolved", callStatsList.get(0).methodName);
+    }
+
+    @Test
     public void testParcelSize() {
         TestBinderCallsStats bcs = new TestBinderCallsStats();
         bcs.setDetailedTracking(true);