media.extractor dumpsys to show recent extractors

Bug: 22775369
Change-Id: Ie68484985567896a00d5c193d1853a8f2e3b3964
diff --git a/services/mediaextractor/MediaExtractorService.cpp b/services/mediaextractor/MediaExtractorService.cpp
index cd20635..a2b35f6 100644
--- a/services/mediaextractor/MediaExtractorService.cpp
+++ b/services/mediaextractor/MediaExtractorService.cpp
@@ -18,12 +18,35 @@
 //#define LOG_NDEBUG 0
 #include <utils/Log.h>
 
+#include <utils/Vector.h>
+
 #include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaExtractor.h>
 #include "MediaExtractorService.h"
 
 namespace android {
 
+typedef struct {
+    String8 mime;
+    String8 name;
+    pid_t owner;
+    wp<MediaExtractor> extractor;
+    String8 toString() {
+        String8 str = name;
+        str.append(" for mime ");
+        str.append(mime);
+        str.append(String8::format(", pid %d: ", owner));
+        if (extractor.promote() == NULL) {
+            str.append("deleted");
+        } else {
+            str.append("active");
+        }
+        return str;
+    }
+} ExtractorInstance;
+
+static Vector<ExtractorInstance> extractors;
+
 sp<IMediaExtractor> MediaExtractorService::makeExtractor(
         const sp<IDataSource> &remoteSource, const char *mime) {
     ALOGV("@@@ MediaExtractorService::makeExtractor for %s", mime);
@@ -36,9 +59,35 @@
             ret.get(),
             ret == NULL ? "" : ret->name());
 
+    if (ret != NULL) {
+        ExtractorInstance ex;
+        ex.mime = mime == NULL ? "NULL" : mime;
+        ex.name = ret->name();
+        ex.owner = IPCThreadState::self()->getCallingPid();
+        ex.extractor = ret;
+
+        if (extractors.size() > 10) {
+            extractors.resize(10);
+        }
+        extractors.push_front(ex);
+    }
+
     return ret;
 }
 
+status_t MediaExtractorService::dump(int fd, const Vector<String16>& args) {
+    String8 out;
+    out.append("Recent extractors, most recent first:\n");
+    for (size_t i = 0; i < extractors.size(); i++) {
+        ExtractorInstance ex = extractors.itemAt(i);
+        out.append("  ");
+        out.append(ex.toString());
+        out.append("\n");
+    }
+    write(fd, out.string(), out.size());
+    return OK;
+}
+
 
 status_t MediaExtractorService::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
         uint32_t flags)
diff --git a/services/mediaextractor/MediaExtractorService.h b/services/mediaextractor/MediaExtractorService.h
index 9c75042..078af0c 100644
--- a/services/mediaextractor/MediaExtractorService.h
+++ b/services/mediaextractor/MediaExtractorService.h
@@ -34,6 +34,7 @@
     static const char*  getServiceName() { return "media.extractor"; }
 
     virtual sp<IMediaExtractor> makeExtractor(const sp<IDataSource> &source, const char *mime);
+    virtual status_t    dump(int fd, const Vector<String16>& args);
 
     virtual status_t    onTransact(uint32_t code, const Parcel& data, Parcel* reply,
                                 uint32_t flags);