NdkMediaExtractor: setDataSourceWithHeaders API

Bug: 109928575
Change-Id: I90e9f6c9d6408f5c577ba75c9792bed589cee304
diff --git a/media/ndk/NdkMediaExtractor.cpp b/media/ndk/NdkMediaExtractor.cpp
index b5e60a4..fa1292e 100644
--- a/media/ndk/NdkMediaExtractor.cpp
+++ b/media/ndk/NdkMediaExtractor.cpp
@@ -84,8 +84,17 @@
 
 EXPORT
 media_status_t AMediaExtractor_setDataSource(AMediaExtractor *mData, const char *location) {
-    ALOGV("setDataSource(%s)", location);
-    // TODO: add header support
+    return AMediaExtractor_setDataSourceWithHeaders(mData, location, 0, NULL, NULL);
+}
+
+EXPORT
+media_status_t AMediaExtractor_setDataSourceWithHeaders(AMediaExtractor *mData,
+        const char *uri,
+        int numheaders,
+        const char * const *keys,
+        const char * const *values) {
+
+    ALOGV("setDataSource(%s)", uri);
 
     JNIEnv *env = AndroidRuntime::getJNIEnv();
     jobject service = NULL;
@@ -109,7 +118,7 @@
         return AMEDIA_ERROR_UNSUPPORTED;
     }
 
-    jstring jloc = env->NewStringUTF(location);
+    jstring jloc = env->NewStringUTF(uri);
 
     service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, jloc);
     env->DeleteLocalRef(jloc);
@@ -120,7 +129,15 @@
         httpService = interface_cast<IMediaHTTPService>(binder);
     }
 
-    status_t err = mData->mImpl->setDataSource(httpService, location, NULL);
+    KeyedVector<String8, String8> headers;
+    for (int i = 0; i < numheaders; ++i) {
+        String8 key8(keys[i]);
+        String8 value8(values[i]);
+        headers.add(key8, value8);
+    }
+
+    status_t err;
+    err = mData->mImpl->setDataSource(httpService, uri, numheaders > 0 ? &headers : NULL);
     env->ExceptionClear();
     return translate_error(err);
 }
diff --git a/media/ndk/include/media/NdkMediaExtractor.h b/media/ndk/include/media/NdkMediaExtractor.h
index 6a1796f..413bc1a 100644
--- a/media/ndk/include/media/NdkMediaExtractor.h
+++ b/media/ndk/include/media/NdkMediaExtractor.h
@@ -72,7 +72,27 @@
  */
 media_status_t AMediaExtractor_setDataSource(AMediaExtractor*,
         const char *location) __INTRODUCED_IN(21);
-        // TODO support headers
+
+#if __ANDROID_API__ >= 29
+/**
+ * Set the |uri| from which the extractor will read,
+ * plus additional http headers when initiating the request.
+ *
+ * Headers will contain corresponding items from |keys| & |values|
+ * from indices 0 (inclusive) to numheaders-1 (inclusive):
+ *
+ * keys[0]:values[0]
+ * ...
+ * keys[numheaders - 1]:values[numheaders - 1]
+ *
+ */
+media_status_t AMediaExtractor_setDataSourceWithHeaders(AMediaExtractor*,
+        const char *uri,
+        int numheaders,
+        const char * const *keys,
+        const char * const *values) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
 
 #if __ANDROID_API__ >= 28
 
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index d828d6a..34e8a4e 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -184,6 +184,7 @@
     AMediaExtractor_setDataSource;
     AMediaExtractor_setDataSourceCustom; # introduced=28
     AMediaExtractor_setDataSourceFd;
+    AMediaExtractor_setDataSourceWithHeaders; # introduced=29
     AMediaExtractor_unselectTrack;
     AMediaFormat_delete;
     AMediaFormat_getBuffer;