MediaMetrics: Use libmemunreachable for memory testing

Full testing steps:

// required for unreachable
$ adb shell setenforce 0
// set up debug malloc
$ adb shell setprop libc.debug.malloc.program mediametrics
$ adb shell setprop libc.debug.malloc.options backtrace=8

// kill media metrics
$ adb shell pkill -f media.metrics
// verify media.metrics has restarted with new pid
$ adb shell pgrep -f media.metrics

// now check media metrics heap (largest 100 items) and unreachable memory.
$ adb shell dumpsys media.metrics --heap
$ adb shell dumpsys media.metrics --unreachable

Test: adb shell dumpsys media.metrics --heap
Test: adb shell dumpsys media.metrics --unreachable
Bug: 149850236
Change-Id: I269003485dd6933c399171fbd9d9a152cee50886
diff --git a/services/mediametrics/Android.bp b/services/mediametrics/Android.bp
index ec59ec1..58f3ea8 100644
--- a/services/mediametrics/Android.bp
+++ b/services/mediametrics/Android.bp
@@ -57,6 +57,7 @@
         "liblog",
         "libmediametrics",
         "libmediautils",
+        "libmemunreachable",
         "libprotobuf-cpp-lite",
         "libstatslog",
         "libutils",
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index a6fefd2..d76bc2c 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -26,6 +26,8 @@
 #include <audio_utils/clock.h>                 // clock conversions
 #include <binder/IPCThreadState.h>             // get calling uid
 #include <cutils/properties.h>                 // for property_get
+#include <mediautils/MemoryLeakTrackUtil.h>
+#include <memunreachable/memunreachable.h>
 #include <private/android_filesystem_config.h> // UID
 
 namespace android {
@@ -205,7 +207,11 @@
         return NO_ERROR;
     }
 
-    // crack any parameters
+    static const String16 heapOption("--heap");
+    static const String16 unreachableOption("--unreachable");
+    bool heap = false;
+    bool unreachable = false;
+
     const String16 protoOption("--proto");
     const String16 clearOption("--clear");
     bool clear = false;
@@ -218,6 +224,8 @@
     for (int i = 0; i < n; i++) {
         if (args[i] == clearOption) {
             clear = true;
+        } else if (args[i] == heapOption) {
+            heap = true;
         } else if (args[i] == protoOption) {
             i++;
             if (i < n) {
@@ -252,14 +260,18 @@
             // or dumpsys media.metrics audiotrack codec
 
             result.append("Recognized parameters:\n");
+            result.append("--heap        heap usage (top 100)\n");
             result.append("--help        this help message\n");
             result.append("--proto #     dump using protocol #");
             result.append("--clear       clears out saved records\n");
             result.append("--only X      process records for component X\n");
             result.append("--since X     include records since X\n");
             result.append("             (X is milliseconds since the UNIX epoch)\n");
+            result.append("--unreachable unreachable memory (leaks)\n");
             write(fd, result.string(), result.size());
             return NO_ERROR;
+        } else if (args[i] == unreachableOption) {
+            unreachable = true;
         }
     }
 
@@ -283,8 +295,20 @@
             result.append("-- some lines may be truncated --\n");
         }
     }
-
     write(fd, result.string(), result.size());
+
+    // Check heap and unreachable memory outside of lock.
+    if (heap) {
+        dprintf(fd, "\nDumping heap:\n");
+        std::string s = dumpMemoryAddresses(100 /* limit */);
+        write(fd, s.c_str(), s.size());
+    }
+    if (unreachable) {
+        dprintf(fd, "\nDumping unreachable memory:\n");
+        // TODO - should limit be an argument parameter?
+        std::string s = GetUnreachableMemoryString(true /* contents */, 100 /* limit */);
+        write(fd, s.c_str(), s.size());
+    }
     return NO_ERROR;
 }