Bluetooth native dumpsys logging support (4/5)

Bug: 18508263
Change-Id: Ib9546ff2cf64d2e085e27e691032749e869e0795
diff --git a/jni/com_android_bluetooth_btservice_AdapterService.cpp b/jni/com_android_bluetooth_btservice_AdapterService.cpp
index f780364..d012c79 100644
--- a/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -1214,6 +1214,17 @@
     return result;
 }
 
+static void dumpNative(JNIEnv *env, jobject obj, jobject fdObj)
+{
+    ALOGV("%s()", __FUNCTION__);
+    if (!sBluetoothInterface) return;
+
+    int fd = jniGetFDFromFileDescriptor(env, fdObj);
+    if (fd < 0) return;
+
+    sBluetoothInterface->dump(fd);
+}
+
 static JNINativeMethod sMethods[] = {
     /* name, signature, funcPtr */
     {"classInitNative", "()V", (void *) classInitNative},
@@ -1242,6 +1253,7 @@
     {"configHciSnoopLogNative", "(Z)Z", (void*) configHciSnoopLogNative},
     {"alarmFiredNative", "()V", (void *) alarmFiredNative},
     {"readEnergyInfo", "()I", (void*) readEnergyInfo},
+    {"dumpNative", "(Ljava/io/FileDescriptor;)V", (void*) dumpNative},
 };
 
 int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env)
diff --git a/src/com/android/bluetooth/btservice/AdapterService.java b/src/com/android/bluetooth/btservice/AdapterService.java
index 190be11..7c5af1d 100644
--- a/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/src/com/android/bluetooth/btservice/AdapterService.java
@@ -66,6 +66,7 @@
 import com.android.internal.R;
 
 import java.io.FileDescriptor;
+import java.io.FileWriter;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -1141,12 +1142,10 @@
              return service.reportActivityInfo();
          }
 
-         public String dump() {
+         public void dump(ParcelFileDescriptor fd) {
             AdapterService service = getService();
-            if (service == null) {
-                return "AdapterService is null";
-            }
-            return service.dump();
+            if (service == null) return;
+            service.dump(fd.getFileDescriptor());
          }
     };
 
@@ -1730,16 +1729,6 @@
         return info;
     }
 
-    private String dump() {
-        StringBuilder sb = new StringBuilder();
-        synchronized (mProfiles) {
-            for (ProfileService profile : mProfiles) {
-                profile.dump(sb);
-            }
-        }
-        return sb.toString();
-    }
-
     private static int convertScanModeToHal(int mode) {
         switch (mode) {
             case BluetoothAdapter.SCAN_MODE_NONE:
@@ -1857,6 +1846,36 @@
         }
     }
 
+    private void dump(FileDescriptor fd) {
+        // Collect profile information
+        StringBuilder sb = new StringBuilder();
+        synchronized (mProfiles) {
+            for (ProfileService profile : mProfiles) {
+                profile.dump(sb);
+            }
+        }
+
+        // Dump Java based profiles first
+        FileWriter fw = null;
+        try {
+            fw = new FileWriter(fd);
+            fw.write(sb.toString());
+        } catch (IOException ex) {
+            errorLog("IOException writing profile status!");
+        } finally {
+            if (fw != null) {
+                try {
+                    fw.close();
+                } catch (IOException ex) {
+                    debugLog("IOException closing a file after writing the profile status");
+                }
+            }
+        }
+
+        // Add native logs
+        dumpNative(fd);
+    }
+
     private void debugLog(String msg) {
         if (DBG) Log.d(TAG +"(" +hashCode()+")", msg);
     }
@@ -1911,6 +1930,7 @@
     /*package*/ native boolean configHciSnoopLogNative(boolean enable);
 
     private native void alarmFiredNative();
+    private native void dumpNative(FileDescriptor fd);
 
     protected void finalize() {
         cleanup();
diff --git a/src/com/android/bluetooth/btservice/ProfileService.java b/src/com/android/bluetooth/btservice/ProfileService.java
index 1b70944..24ff774 100644
--- a/src/com/android/bluetooth/btservice/ProfileService.java
+++ b/src/com/android/bluetooth/btservice/ProfileService.java
@@ -161,7 +161,7 @@
 
     // for dumpsys support
     public void dump(StringBuilder sb) {
-        sb.append("Profile: " + mName + "\n");
+        sb.append("\nProfile: " + mName + "\n");
     }
 
     // with indenting for subclasses