Support passing headers to MediaMetadataRetriever's setDataSource API

Change-Id: Ib1a5c08fc5034cac05034db27007a35c9b660b26
related-to-bug: 3506316
diff --git a/include/media/IMediaMetadataRetriever.h b/include/media/IMediaMetadataRetriever.h
index 8e3cdbb..1c1c268 100644
--- a/include/media/IMediaMetadataRetriever.h
+++ b/include/media/IMediaMetadataRetriever.h
@@ -18,10 +18,11 @@
 #ifndef ANDROID_IMEDIAMETADATARETRIEVER_H
 #define ANDROID_IMEDIAMETADATARETRIEVER_H
 
-#include <utils/RefBase.h>
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
 #include <binder/IMemory.h>
+#include <utils/KeyedVector.h>
+#include <utils/RefBase.h>
 
 namespace android {
 
@@ -30,7 +31,11 @@
 public:
     DECLARE_META_INTERFACE(MediaMetadataRetriever);
     virtual void            disconnect() = 0;
-    virtual status_t        setDataSource(const char* srcUrl) = 0;
+
+    virtual status_t        setDataSource(
+            const char *srcUrl,
+            const KeyedVector<String8, String8> *headers = NULL) = 0;
+
     virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0;
     virtual sp<IMemory>     getFrameAtTime(int64_t timeUs, int option) = 0;
     virtual sp<IMemory>     extractAlbumArt() = 0;
diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h
index 0449122..27b7e4d 100644
--- a/include/media/MediaMetadataRetrieverInterface.h
+++ b/include/media/MediaMetadataRetrieverInterface.h
@@ -30,7 +30,11 @@
 public:
                         MediaMetadataRetrieverBase() {}
     virtual             ~MediaMetadataRetrieverBase() {}
-    virtual status_t    setDataSource(const char *url) = 0;
+
+    virtual status_t    setDataSource(
+            const char *url,
+            const KeyedVector<String8, String8> *headers = NULL) = 0;
+
     virtual status_t    setDataSource(int fd, int64_t offset, int64_t length) = 0;
     virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0;
     virtual MediaAlbumArt* extractAlbumArt() = 0;
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index a5cb949..3e343e0 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -62,7 +62,11 @@
     MediaMetadataRetriever();
     ~MediaMetadataRetriever();
     void disconnect();
-    status_t setDataSource(const char* dataSourceUrl);
+
+    status_t setDataSource(
+            const char *dataSourceUrl,
+            const KeyedVector<String8, String8> *headers = NULL);
+
     status_t setDataSource(int fd, int64_t offset, int64_t length);
     sp<IMemory> getFrameAtTime(int64_t timeUs, int option);
     sp<IMemory> extractAlbumArt();
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index d5298c9..ebe821f 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -20,6 +20,7 @@
 #include <binder/Parcel.h>
 #include <SkBitmap.h>
 #include <media/IMediaMetadataRetriever.h>
+#include <utils/String8.h>
 
 // The binder is supposed to propagate the scheduler group across
 // the binder interface so that remote calls are executed with
@@ -102,11 +103,24 @@
         remote()->transact(DISCONNECT, data, &reply);
     }
 
-    status_t setDataSource(const char* srcUrl)
+    status_t setDataSource(
+            const char *srcUrl, const KeyedVector<String8, String8> *headers)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
         data.writeCString(srcUrl);
+
+        if (headers == NULL) {
+            data.writeInt32(0);
+        } else {
+            // serialize the headers
+            data.writeInt32(headers->size());
+            for (size_t i = 0; i < headers->size(); ++i) {
+                data.writeString8(headers->keyAt(i));
+                data.writeString8(headers->valueAt(i));
+            }
+        }
+
         remote()->transact(SET_DATA_SOURCE_URL, data, &reply);
         return reply.readInt32();
     }
@@ -188,7 +202,18 @@
         case SET_DATA_SOURCE_URL: {
             CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
             const char* srcUrl = data.readCString();
-            reply->writeInt32(setDataSource(srcUrl));
+
+            KeyedVector<String8, String8> headers;
+            int32_t numHeaders = data.readInt32();
+            for (int i = 0; i < numHeaders; ++i) {
+                String8 key = data.readString8();
+                String8 value = data.readString8();
+                headers.add(key, value);
+            }
+
+            reply->writeInt32(
+                    setDataSource(srcUrl, numHeaders > 0 ? &headers : NULL));
+
             return NO_ERROR;
         } break;
         case SET_DATA_SOURCE_FD: {
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 8dfcb3b..cee06ab 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -92,7 +92,8 @@
     }
 }
 
-status_t MediaMetadataRetriever::setDataSource(const char* srcUrl)
+status_t MediaMetadataRetriever::setDataSource(
+        const char *srcUrl, const KeyedVector<String8, String8> *headers)
 {
     LOGV("setDataSource");
     Mutex::Autolock _l(mLock);
@@ -105,7 +106,7 @@
         return UNKNOWN_ERROR;
     }
     LOGV("data source (%s)", srcUrl);
-    return mRetriever->setDataSource(srcUrl);
+    return mRetriever->setDataSource(srcUrl, headers);
 }
 
 status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 5fcf2a7..8f776b4 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -120,7 +120,8 @@
     return p;
 }
 
-status_t MetadataRetrieverClient::setDataSource(const char *url)
+status_t MetadataRetrieverClient::setDataSource(
+        const char *url, const KeyedVector<String8, String8> *headers)
 {
     LOGV("setDataSource(%s)", url);
     Mutex::Autolock lock(mLock);
@@ -131,7 +132,7 @@
     LOGV("player type = %d", playerType);
     sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
     if (p == NULL) return NO_INIT;
-    status_t ret = p->setDataSource(url);
+    status_t ret = p->setDataSource(url, headers);
     if (ret == NO_ERROR) mRetriever = p;
     return ret;
 }
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h
index b834715..f08f933 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.h
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.h
@@ -41,7 +41,10 @@
     // Implements IMediaMetadataRetriever interface
     // These methods are called in IMediaMetadataRetriever.cpp?
     virtual void                    disconnect();
-    virtual status_t                setDataSource(const char *url);
+
+    virtual status_t                setDataSource(
+            const char *url, const KeyedVector<String8, String8> *headers);
+
     virtual status_t                setDataSource(int fd, int64_t offset, int64_t length);
     virtual sp<IMemory>             getFrameAtTime(int64_t timeUs, int option);
     virtual sp<IMemory>             extractAlbumArt();
diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.cpp b/media/libmediaplayerservice/MidiMetadataRetriever.cpp
index ad95fac..aaf2d18 100644
--- a/media/libmediaplayerservice/MidiMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/MidiMetadataRetriever.cpp
@@ -35,7 +35,8 @@
     mMetadataValues[0][0] = '\0';
 }
 
-status_t MidiMetadataRetriever::setDataSource(const char *url)
+status_t MidiMetadataRetriever::setDataSource(
+        const char *url, const KeyedVector<String8, String8> *headers)
 {
     LOGV("setDataSource: %s", url? url: "NULL pointer");
     Mutex::Autolock lock(mLock);
@@ -43,8 +44,7 @@
     if (mMidiPlayer == 0) {
         mMidiPlayer = new MidiFile();
     }
-    // TODO: support headers in MetadataRetriever interface!
-    return mMidiPlayer->setDataSource(url, NULL /* headers */);
+    return mMidiPlayer->setDataSource(url, headers);
 }
 
 status_t MidiMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.h b/media/libmediaplayerservice/MidiMetadataRetriever.h
index 73ff347..4cee42d 100644
--- a/media/libmediaplayerservice/MidiMetadataRetriever.h
+++ b/media/libmediaplayerservice/MidiMetadataRetriever.h
@@ -31,7 +31,9 @@
                                    MidiMetadataRetriever() {}
                                    ~MidiMetadataRetriever() {}
 
-    virtual status_t                setDataSource(const char *url);
+    virtual status_t                setDataSource(
+            const char *url, const KeyedVector<String8, String8> *headers);
+
     virtual status_t                setDataSource(int fd, int64_t offset, int64_t length);
     virtual const char*             extractMetadata(int keyCode);
 
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index c371cd0..f58726e 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -48,7 +48,8 @@
     mClient.disconnect();
 }
 
-status_t StagefrightMetadataRetriever::setDataSource(const char *uri) {
+status_t StagefrightMetadataRetriever::setDataSource(
+        const char *uri, const KeyedVector<String8, String8> *headers) {
     LOGV("setDataSource(%s)", uri);
 
     mParsedMetaData = false;
@@ -56,7 +57,7 @@
     delete mAlbumArt;
     mAlbumArt = NULL;
 
-    mSource = DataSource::CreateFromURI(uri);
+    mSource = DataSource::CreateFromURI(uri, headers);
 
     if (mSource == NULL) {
         return UNKNOWN_ERROR;
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index 07b1ec8..b02ed0e 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -32,7 +32,10 @@
     StagefrightMetadataRetriever();
     virtual ~StagefrightMetadataRetriever();
 
-    virtual status_t setDataSource(const char *url);
+    virtual status_t setDataSource(
+            const char *url,
+            const KeyedVector<String8, String8> *headers);
+
     virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
 
     virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option);