Merge "media.extractor dumpsys to show recent extractors" into nyc-dev
am: e385a78e97

* commit 'e385a78e97c55d2298c867335264736c8ef366ed':
  media.extractor dumpsys to show recent extractors
diff --git a/media/libstagefright/include/AACExtractor.h b/media/libstagefright/include/AACExtractor.h
index e231e62..bd4c41c 100644
--- a/media/libstagefright/include/AACExtractor.h
+++ b/media/libstagefright/include/AACExtractor.h
@@ -36,6 +36,7 @@
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
+    virtual const char * name() { return "AACExtractor"; }
 
 protected:
     virtual ~AACExtractor();
diff --git a/media/libstagefright/include/AMRExtractor.h b/media/libstagefright/include/AMRExtractor.h
index 0770397..ba2b674 100644
--- a/media/libstagefright/include/AMRExtractor.h
+++ b/media/libstagefright/include/AMRExtractor.h
@@ -36,6 +36,7 @@
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
+    virtual const char * name() { return "AMRExtractor"; }
 
 protected:
     virtual ~AMRExtractor();
diff --git a/media/libstagefright/include/AVIExtractor.h b/media/libstagefright/include/AVIExtractor.h
index ff5dcb5..3be505c 100644
--- a/media/libstagefright/include/AVIExtractor.h
+++ b/media/libstagefright/include/AVIExtractor.h
@@ -36,6 +36,7 @@
             size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
+    virtual const char * name() { return "AVIExtractor"; }
 
 protected:
     virtual ~AVIExtractor();
diff --git a/media/libstagefright/include/DRMExtractor.h b/media/libstagefright/include/DRMExtractor.h
index a035d8c..3dc7df8 100644
--- a/media/libstagefright/include/DRMExtractor.h
+++ b/media/libstagefright/include/DRMExtractor.h
@@ -38,6 +38,7 @@
     virtual sp<IMediaSource> getTrack(size_t index);
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
     virtual sp<MetaData> getMetaData();
+    virtual const char * name() { return "DRMExtractor"; }
 
 protected:
     virtual ~DRMExtractor();
diff --git a/media/libstagefright/include/FLACExtractor.h b/media/libstagefright/include/FLACExtractor.h
index a6e6c1d..5d030b1 100644
--- a/media/libstagefright/include/FLACExtractor.h
+++ b/media/libstagefright/include/FLACExtractor.h
@@ -36,6 +36,7 @@
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
+    virtual const char * name() { return "FLACExtractor"; }
 
 protected:
     virtual ~FLACExtractor();
diff --git a/media/libstagefright/include/MPEG2PSExtractor.h b/media/libstagefright/include/MPEG2PSExtractor.h
index e815f0e..c8abfb6 100644
--- a/media/libstagefright/include/MPEG2PSExtractor.h
+++ b/media/libstagefright/include/MPEG2PSExtractor.h
@@ -40,6 +40,7 @@
     virtual sp<MetaData> getMetaData();
 
     virtual uint32_t flags() const;
+    virtual const char * name() { return "MPEG2PSExtractor"; }
 
 protected:
     virtual ~MPEG2PSExtractor();
diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h
index 9907572..e5c24ca 100644
--- a/media/libstagefright/include/MPEG2TSExtractor.h
+++ b/media/libstagefright/include/MPEG2TSExtractor.h
@@ -44,6 +44,7 @@
     virtual sp<MetaData> getMetaData();
 
     virtual uint32_t flags() const;
+    virtual const char * name() { return "MPEG2TSExtractor"; }
 
 private:
     friend struct MPEG2TSSource;
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index cff976d..3e8fb7c 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -58,6 +58,7 @@
 
     virtual sp<MetaData> getMetaData();
     virtual uint32_t flags() const;
+    virtual const char * name() { return "MPEG4Extractor"; }
 
     // for DRM
     virtual char* getDrmTrackInfo(size_t trackID, int *len);
diff --git a/media/libstagefright/include/MidiExtractor.h b/media/libstagefright/include/MidiExtractor.h
index 333277b..5a7d90e 100644
--- a/media/libstagefright/include/MidiExtractor.h
+++ b/media/libstagefright/include/MidiExtractor.h
@@ -60,6 +60,7 @@
     virtual sp<MetaData> getTrackMetaData(size_t index, uint32_t flags);
 
     virtual sp<MetaData> getMetaData();
+    virtual const char * name() { return "MidiExtractor"; }
 
 protected:
     virtual ~MidiExtractor();
diff --git a/media/libstagefright/matroska/MatroskaExtractor.h b/media/libstagefright/matroska/MatroskaExtractor.h
index a1d6b00..592e7cf 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.h
+++ b/media/libstagefright/matroska/MatroskaExtractor.h
@@ -46,6 +46,8 @@
 
     virtual uint32_t flags() const;
 
+    virtual const char * name() { return "MatroskaExtractor"; }
+
 protected:
     virtual ~MatroskaExtractor();
 
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);