API Extension: Support for optionally specifying a map of extra request headers when specifying the uri of media data to be played.
related-to-bug: 2393577
Original change by Andrei Popescu <andreip@google.com>
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 81d60dc..405d471 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -197,7 +197,7 @@
static sp<MediaPlayer> newMediaPlayer(const char *file)
{
sp<MediaPlayer> mp = new MediaPlayer();
- if (mp->setDataSource(file) == NO_ERROR) {
+ if (mp->setDataSource(file, NULL /* headers */) == NO_ERROR) {
mp->setAudioStreamType(AudioSystem::ENFORCED_AUDIBLE);
mp->prepare();
} else {
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index 429b335..85f1d5c 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -73,6 +73,8 @@
private static final int ENDED = 201;
private static final int POSTER_FETCHED = 202;
+ private static final String COOKIE = "Cookie";
+
// Timer thread -> UI thread
private static final int TIMEUPDATE = 300;
@@ -165,7 +167,15 @@
mVideoView = new VideoView(proxy.getContext());
mVideoView.setWillNotDraw(false);
mVideoView.setMediaController(new MediaController(proxy.getContext()));
- mVideoView.setVideoURI(Uri.parse(url));
+
+ String cookieValue = CookieManager.getInstance().getCookie(url);
+ Map<String, String> headers = null;
+ if (cookieValue != null) {
+ headers = new HashMap<String, String>();
+ headers.put(COOKIE, cookieValue);
+ }
+
+ mVideoView.setVideoURI(Uri.parse(url), headers);
mVideoView.setOnCompletionListener(proxy);
mVideoView.setOnPreparedListener(proxy);
mVideoView.setOnErrorListener(proxy);
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index 8142a82..906bca1c 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -38,6 +38,7 @@
import android.widget.MediaController.*;
import java.io.IOException;
+import java.util.Map;
/**
* Displays a video file. The VideoView class
@@ -50,6 +51,7 @@
private String TAG = "VideoView";
// settable by the client
private Uri mUri;
+ private Map<String, String> mHeaders;
private int mDuration;
// all possible internal states
@@ -90,12 +92,12 @@
super(context);
initVideoView();
}
-
+
public VideoView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
initVideoView();
}
-
+
public VideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initVideoView();
@@ -122,7 +124,7 @@
//Log.i("@@@@@@@@@@", "setting size: " + width + 'x' + height);
setMeasuredDimension(width, height);
}
-
+
public int resolveAdjustedSize(int desiredSize, int measureSpec) {
int result = desiredSize;
int specMode = MeasureSpec.getMode(measureSpec);
@@ -137,13 +139,13 @@
break;
case MeasureSpec.AT_MOST:
- /* Parent says we can be as big as we want, up to specSize.
- * Don't be larger than specSize, and don't be larger than
+ /* Parent says we can be as big as we want, up to specSize.
+ * Don't be larger than specSize, and don't be larger than
* the max size imposed on ourselves.
*/
result = Math.min(desiredSize, specSize);
break;
-
+
case MeasureSpec.EXACTLY:
// No choice. Do what we are told.
result = specSize;
@@ -151,7 +153,7 @@
}
return result;
}
-
+
private void initVideoView() {
mVideoWidth = 0;
mVideoHeight = 0;
@@ -169,13 +171,21 @@
}
public void setVideoURI(Uri uri) {
+ setVideoURI(uri, null);
+ }
+
+ /**
+ * @hide
+ */
+ public void setVideoURI(Uri uri, Map<String, String> headers) {
mUri = uri;
+ mHeaders = headers;
mSeekWhenPrepared = 0;
openVideo();
requestLayout();
invalidate();
}
-
+
public void stopPlayback() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
@@ -191,7 +201,7 @@
// not ready for playback just yet, will try again later
return;
}
- // Tell the music playback service to pause
+ // Tell the music playback service to pause
// TODO: these constants need to be published somewhere in the framework.
Intent i = new Intent("com.android.music.musicservicecommand");
i.putExtra("command", "pause");
@@ -209,7 +219,7 @@
mMediaPlayer.setOnErrorListener(mErrorListener);
mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener);
mCurrentBufferPercentage = 0;
- mMediaPlayer.setDataSource(mContext, mUri);
+ mMediaPlayer.setDataSource(mContext, mUri, mHeaders);
mMediaPlayer.setDisplay(mSurfaceHolder);
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mMediaPlayer.setScreenOnWhilePlaying(true);
@@ -232,7 +242,7 @@
return;
}
}
-
+
public void setMediaController(MediaController controller) {
if (mMediaController != null) {
mMediaController.hide();
@@ -250,7 +260,7 @@
mMediaController.setEnabled(isInPlaybackState());
}
}
-
+
MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener =
new MediaPlayer.OnVideoSizeChangedListener() {
public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
@@ -261,7 +271,7 @@
}
}
};
-
+
MediaPlayer.OnPreparedListener mPreparedListener = new MediaPlayer.OnPreparedListener() {
public void onPrepared(MediaPlayer mp) {
mCurrentState = STATE_PREPARED;
@@ -490,7 +500,7 @@
}
return false;
}
-
+
@Override
public boolean onTrackballEvent(MotionEvent ev) {
if (isInPlaybackState() && mMediaController != null) {
@@ -498,7 +508,7 @@
}
return false;
}
-
+
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
@@ -519,7 +529,7 @@
mMediaController.hide();
}
return true;
- } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
+ } else if (keyCode == KeyEvent.KEYCODE_MEDIA_STOP
&& mMediaPlayer.isPlaying()) {
pause();
mMediaController.show();
@@ -532,13 +542,13 @@
}
private void toggleMediaControlsVisiblity() {
- if (mMediaController.isShowing()) {
+ if (mMediaController.isShowing()) {
mMediaController.hide();
} else {
mMediaController.show();
}
}
-
+
public void start() {
if (isInPlaybackState()) {
mMediaPlayer.start();
@@ -546,7 +556,7 @@
}
mTargetState = STATE_PLAYING;
}
-
+
public void pause() {
if (isInPlaybackState()) {
if (mMediaPlayer.isPlaying()) {
@@ -556,7 +566,7 @@
}
mTargetState = STATE_PAUSED;
}
-
+
// cache duration as mDuration for faster access
public int getDuration() {
if (isInPlaybackState()) {
@@ -569,14 +579,14 @@
mDuration = -1;
return mDuration;
}
-
+
public int getCurrentPosition() {
if (isInPlaybackState()) {
return mMediaPlayer.getCurrentPosition();
}
return 0;
}
-
+
public void seekTo(int msec) {
if (isInPlaybackState()) {
mMediaPlayer.seekTo(msec);
@@ -584,12 +594,12 @@
} else {
mSeekWhenPrepared = msec;
}
- }
-
+ }
+
public boolean isPlaying() {
return isInPlaybackState() && mMediaPlayer.isPlaying();
}
-
+
public int getBufferPercentage() {
if (mMediaPlayer != null) {
return mCurrentBufferPercentage;
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index d5c1594..31c0991 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -18,7 +18,9 @@
#define ANDROID_IMEDIAPLAYERSERVICE_H
#include <utils/Errors.h> // for status_t
+#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
+#include <utils/String8.h>
#include <binder/IInterface.h>
#include <binder/Parcel.h>
@@ -38,7 +40,7 @@
virtual sp<IMediaRecorder> createMediaRecorder(pid_t pid) = 0;
virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0;
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url) = 0;
+ virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, const KeyedVector<String8, String8> *headers = NULL) = 0;
virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0;
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 588c51a..a5a1bb8 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -21,8 +21,10 @@
#include <sys/types.h>
#include <ui/ISurface.h>
-#include <utils/RefBase.h>
#include <utils/Errors.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/RefBase.h>
#include <media/mediaplayer.h>
#include <media/AudioSystem.h>
@@ -96,7 +98,11 @@
virtual ~MediaPlayerBase() {}
virtual status_t initCheck() = 0;
virtual bool hardwareOutput() = 0;
- 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 status_t setVideoSurface(const sp<ISurface>& surface) = 0;
virtual status_t prepare() = 0;
diff --git a/include/media/PVPlayer.h b/include/media/PVPlayer.h
index 8a66152..df50981 100644
--- a/include/media/PVPlayer.h
+++ b/include/media/PVPlayer.h
@@ -38,7 +38,10 @@
virtual ~PVPlayer();
virtual status_t initCheck();
- 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 status_t setVideoSurface(const sp<ISurface>& surface);
virtual status_t prepare();
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index 87d23f6..c9198d6 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -23,6 +23,9 @@
#include <media/IMediaPlayer.h>
#include <media/IMediaDeathNotifier.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
namespace android {
enum media_event_type {
@@ -130,7 +133,11 @@
~MediaPlayer();
void died();
void disconnect();
- status_t setDataSource(const char *url);
+
+ status_t setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers);
+
status_t setDataSource(int fd, int64_t offset, int64_t length);
status_t setVideoSurface(const sp<Surface>& surface);
status_t setListener(const sp<MediaPlayerListener>& listener);
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 07542ed7..89ee7d3 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -34,6 +34,7 @@
import java.io.FileDescriptor;
import java.io.IOException;
+import java.util.Map;
import java.util.Set;
import java.lang.ref.WeakReference;
@@ -665,6 +666,20 @@
*/
public void setDataSource(Context context, Uri uri)
throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+ setDataSource(context, uri, null);
+ }
+
+ /**
+ * Sets the data source as a content Uri.
+ *
+ * @param context the Context to use when resolving the Uri
+ * @param uri the Content URI of the data you want to play
+ * @param headers the headers to be sent together with the request for the data
+ * @throws IllegalStateException if it is called in an invalid state
+ * @hide pending API council
+ */
+ public void setDataSource(Context context, Uri uri, Map<String, String> headers)
+ throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
String scheme = uri.getScheme();
if(scheme == null || scheme.equals("file")) {
@@ -696,7 +711,7 @@
}
}
Log.d(TAG, "Couldn't open file on client side, trying server side");
- setDataSource(uri.toString());
+ setDataSource(uri.toString(), headers);
return;
}
@@ -709,6 +724,17 @@
public native void setDataSource(String path) throws IOException, IllegalArgumentException, IllegalStateException;
/**
+ * Sets the data source (file-path or http/rtsp URL) to use.
+ *
+ * @param path the path of the file, or the http/rtsp URL of the stream you want to play
+ * @param headers the headers associated with the http request for the stream you want to play
+ * @throws IllegalStateException if it is called in an invalid state
+ * @hide pending API council
+ */
+ public native void setDataSource(String path, Map<String, String> headers)
+ throws IOException, IllegalArgumentException, IllegalStateException;
+
+ /**
* Sets the data source (FileDescriptor) to use. It is the caller's responsibility
* to close the file descriptor. It is safe to do so as soon as this call returns.
*
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 703afd2..27f5668 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -31,6 +31,8 @@
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include "utils/Errors.h" // for status_t
+#include "utils/KeyedVector.h"
+#include "utils/String8.h"
#include "android_util_Binder.h"
#include <binder/Parcel.h>
@@ -156,8 +158,8 @@
}
static void
-android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path)
-{
+android_media_MediaPlayer_setDataSourceAndHeaders(
+ JNIEnv *env, jobject thiz, jstring path, jobject headers) {
sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
if (mp == NULL ) {
jniThrowException(env, "java/lang/IllegalStateException", NULL);
@@ -174,12 +176,96 @@
jniThrowException(env, "java/lang/RuntimeException", "Out of memory");
return;
}
+
+ // headers is a Map<String, String>.
+ // We build a similar KeyedVector out of it.
+ KeyedVector<String8, String8> headersVector;
+ if (headers) {
+ // Get the Map's entry Set.
+ jclass mapClass = env->FindClass("java/util/Map");
+
+ jmethodID entrySet =
+ env->GetMethodID(mapClass, "entrySet", "()Ljava/util/Set;");
+
+ jobject set = env->CallObjectMethod(headers, entrySet);
+ // Obtain an iterator over the Set
+ jclass setClass = env->FindClass("java/util/Set");
+
+ jmethodID iterator =
+ env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
+
+ jobject iter = env->CallObjectMethod(set, iterator);
+ // Get the Iterator method IDs
+ jclass iteratorClass = env->FindClass("java/util/Iterator");
+ jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
+
+ jmethodID next =
+ env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
+
+ // Get the Entry class method IDs
+ jclass entryClass = env->FindClass("java/util/Map$Entry");
+
+ jmethodID getKey =
+ env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
+
+ jmethodID getValue =
+ env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
+
+ // Iterate over the entry Set
+ while (env->CallBooleanMethod(iter, hasNext)) {
+ jobject entry = env->CallObjectMethod(iter, next);
+ jstring key = (jstring) env->CallObjectMethod(entry, getKey);
+ jstring value = (jstring) env->CallObjectMethod(entry, getValue);
+
+ const char* keyStr = env->GetStringUTFChars(key, NULL);
+ if (!keyStr) { // Out of memory
+ jniThrowException(
+ env, "java/lang/RuntimeException", "Out of memory");
+ return;
+ }
+
+ const char* valueStr = env->GetStringUTFChars(value, NULL);
+ if (!valueStr) { // Out of memory
+ jniThrowException(
+ env, "java/lang/RuntimeException", "Out of memory");
+ return;
+ }
+
+ headersVector.add(String8(keyStr), String8(valueStr));
+
+ env->DeleteLocalRef(entry);
+ env->ReleaseStringUTFChars(key, keyStr);
+ env->DeleteLocalRef(key);
+ env->ReleaseStringUTFChars(value, valueStr);
+ env->DeleteLocalRef(value);
+ }
+
+ env->DeleteLocalRef(entryClass);
+ env->DeleteLocalRef(iteratorClass);
+ env->DeleteLocalRef(iter);
+ env->DeleteLocalRef(setClass);
+ env->DeleteLocalRef(set);
+ env->DeleteLocalRef(mapClass);
+ }
+
LOGV("setDataSource: path %s", pathStr);
- status_t opStatus = mp->setDataSource(pathStr);
+ status_t opStatus =
+ mp->setDataSource(
+ String8(pathStr),
+ headers ? &headersVector : NULL);
// Make sure that local ref is released before a potential exception
env->ReleaseStringUTFChars(path, pathStr);
- process_media_player_call( env, thiz, opStatus, "java/io/IOException", "setDataSource failed." );
+
+ process_media_player_call(
+ env, thiz, opStatus, "java/io/IOException",
+ "setDataSource failed." );
+}
+
+static void
+android_media_MediaPlayer_setDataSource(JNIEnv *env, jobject thiz, jstring path)
+{
+ android_media_MediaPlayer_setDataSourceAndHeaders(env, thiz, path, 0);
}
static void
@@ -610,6 +696,7 @@
static JNINativeMethod gMethods[] = {
{"setDataSource", "(Ljava/lang/String;)V", (void *)android_media_MediaPlayer_setDataSource},
+ {"setDataSource", "(Ljava/lang/String;Ljava/util/Map;)V",(void *)android_media_MediaPlayer_setDataSourceAndHeaders},
{"setDataSource", "(Ljava/io/FileDescriptor;JJ)V", (void *)android_media_MediaPlayer_setDataSourceFD},
{"_setVideoSurface", "()V", (void *)android_media_MediaPlayer_setVideoSurface},
{"prepare", "()V", (void *)android_media_MediaPlayer_prepare},
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index cca3e9b..71c5f86 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -56,13 +56,26 @@
return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
}
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url)
- {
+ virtual sp<IMediaPlayer> create(
+ pid_t pid, const sp<IMediaPlayerClient>& client,
+ const char* url, const KeyedVector<String8, String8> *headers) {
Parcel data, reply;
data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
data.writeInt32(pid);
data.writeStrongBinder(client->asBinder());
data.writeCString(url);
+
+ 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(CREATE_URL, data, &reply);
return interface_cast<IMediaPlayer>(reply.readStrongBinder());
}
@@ -142,9 +155,21 @@
case CREATE_URL: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
pid_t pid = data.readInt32();
- sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
+ sp<IMediaPlayerClient> client =
+ interface_cast<IMediaPlayerClient>(data.readStrongBinder());
const char* url = data.readCString();
- sp<IMediaPlayer> player = create(pid, client, url);
+
+ 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);
+ }
+
+ sp<IMediaPlayer> player = create(
+ pid, client, url, numHeaders > 0 ? &headers : NULL);
+
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
} break;
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index c0664f3..cb5ee4b 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -32,6 +32,9 @@
#include <binder/MemoryBase.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+
namespace android {
MediaPlayer::MediaPlayer()
@@ -122,14 +125,16 @@
return err;
}
-status_t MediaPlayer::setDataSource(const char *url)
+status_t MediaPlayer::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers)
{
LOGV("setDataSource(%s)", url);
status_t err = BAD_VALUE;
if (url != NULL) {
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
- sp<IMediaPlayer> player(service->create(getpid(), this, url));
+ sp<IMediaPlayer> player(
+ service->create(getpid(), this, url, headers));
err = setDataSource(player);
}
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 5b061b1..8e61011 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -254,12 +254,14 @@
return retriever;
}
-sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url)
+sp<IMediaPlayer> MediaPlayerService::create(
+ pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
+ const KeyedVector<String8, String8> *headers)
{
int32_t connId = android_atomic_inc(&mNextConnId);
sp<Client> c = new Client(this, pid, connId, client);
LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);
- if (NO_ERROR != c->setDataSource(url))
+ if (NO_ERROR != c->setDataSource(url, headers))
{
c.clear();
return c;
@@ -803,7 +805,8 @@
return p;
}
-status_t MediaPlayerService::Client::setDataSource(const char *url)
+status_t MediaPlayerService::Client::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers)
{
LOGV("setDataSource(%s)", url);
if (url == NULL)
@@ -838,7 +841,7 @@
// now set data source
LOGV(" setDataSource");
- mStatus = p->setDataSource(url);
+ mStatus = p->setDataSource(url, headers);
if (mStatus == NO_ERROR) {
mPlayer = p;
} else {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index d243b96..ffe1ba0 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -23,6 +23,7 @@
#include <utils/List.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
+#include <utils/String8.h>
#include <utils/Vector.h>
#include <ui/SurfaceComposerClient.h>
@@ -181,7 +182,10 @@
virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid);
// House keeping for media player clients
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url);
+ virtual sp<IMediaPlayer> create(
+ pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
+ const KeyedVector<String8, String8> *headers);
+
virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length);
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
virtual sp<IMemory> decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
@@ -219,7 +223,11 @@
Parcel *reply);
sp<MediaPlayerBase> createPlayer(player_type playerType);
- status_t setDataSource(const char *url);
+
+ status_t setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers);
+
status_t setDataSource(int fd, int64_t offset, int64_t length);
static void notify(void* cookie, int msg, int ext1, int ext2);
diff --git a/media/libmediaplayerservice/MidiFile.cpp b/media/libmediaplayerservice/MidiFile.cpp
index e9cbb97..1b0b05f 100644
--- a/media/libmediaplayerservice/MidiFile.cpp
+++ b/media/libmediaplayerservice/MidiFile.cpp
@@ -115,8 +115,8 @@
release();
}
-status_t MidiFile::setDataSource(const char* path)
-{
+status_t MidiFile::setDataSource(
+ const char* path, const KeyedVector<String8, String8> *) {
LOGV("MidiFile::setDataSource url=%s", path);
Mutex::Autolock lock(mMutex);
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index 25d4a1b..4a60ece 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -30,7 +30,10 @@
~MidiFile();
virtual status_t initCheck();
- virtual status_t setDataSource(const char* path);
+
+ virtual status_t setDataSource(
+ const char* path, const KeyedVector<String8, String8> *headers);
+
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual status_t setVideoSurface(const sp<ISurface>& surface) { return UNKNOWN_ERROR; }
virtual status_t prepare();
diff --git a/media/libmediaplayerservice/MidiMetadataRetriever.cpp b/media/libmediaplayerservice/MidiMetadataRetriever.cpp
index 3795b7b..ad95fac 100644
--- a/media/libmediaplayerservice/MidiMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/MidiMetadataRetriever.cpp
@@ -43,7 +43,8 @@
if (mMidiPlayer == 0) {
mMidiPlayer = new MidiFile();
}
- return mMidiPlayer->setDataSource(url);
+ // TODO: support headers in MetadataRetriever interface!
+ return mMidiPlayer->setDataSource(url, NULL /* headers */);
}
status_t MidiMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 5915105..3135d0c 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -28,8 +28,9 @@
return OK;
}
-status_t StagefrightPlayer::setDataSource(const char *url) {
- LOGV("setDataSource('%s')", url);
+status_t StagefrightPlayer::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *) {
+ LOGI("setDataSource('%s')", url);
return mPlayer->setDataSource(url);
}
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index 9d005cb..9e6674a 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -30,7 +30,10 @@
virtual ~StagefrightPlayer();
virtual status_t initCheck();
- 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 status_t setVideoSurface(const sp<ISurface> &surface);
virtual status_t prepare();
diff --git a/media/libmediaplayerservice/TestPlayerStub.cpp b/media/libmediaplayerservice/TestPlayerStub.cpp
index aa49429..169e49a 100644
--- a/media/libmediaplayerservice/TestPlayerStub.cpp
+++ b/media/libmediaplayerservice/TestPlayerStub.cpp
@@ -112,8 +112,8 @@
// Load the dynamic library.
// Create the test player.
// Call setDataSource on the test player with the url in param.
-status_t TestPlayerStub::setDataSource(const char *url)
-{
+status_t TestPlayerStub::setDataSource(
+ const char *url, const KeyedVector<String8, String8> *headers) {
if (!isTestUrl(url) || NULL != mHandle) {
return INVALID_OPERATION;
}
@@ -162,7 +162,7 @@
}
mPlayer = (*mNewPlayer)();
- return mPlayer->setDataSource(mContentUrl);
+ return mPlayer->setDataSource(mContentUrl, headers);
}
// Internal cleanup.
diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h
index 80d53a8..6e6c3cd 100644
--- a/media/libmediaplayerservice/TestPlayerStub.h
+++ b/media/libmediaplayerservice/TestPlayerStub.h
@@ -65,7 +65,8 @@
virtual status_t initCheck();
// @param url Should be a test url. See class comment.
- virtual status_t setDataSource(const char* url);
+ virtual status_t setDataSource(
+ const char* url, const KeyedVector<String8, String8> *headers);
// Test player for a file descriptor source is not supported.
virtual status_t setDataSource(int, int64_t, int64_t) {
diff --git a/media/libmediaplayerservice/VorbisMetadataRetriever.cpp b/media/libmediaplayerservice/VorbisMetadataRetriever.cpp
index e981678..eac74fc 100644
--- a/media/libmediaplayerservice/VorbisMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/VorbisMetadataRetriever.cpp
@@ -39,7 +39,8 @@
if (mVorbisPlayer == 0) {
mVorbisPlayer = new VorbisPlayer();
}
- return mVorbisPlayer->setDataSource(url);
+ // TODO: support headers in MetadataRetriever interface!
+ return mVorbisPlayer->setDataSource(url, NULL /* headers */);
}
status_t VorbisMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length)
diff --git a/media/libmediaplayerservice/VorbisPlayer.cpp b/media/libmediaplayerservice/VorbisPlayer.cpp
index 7f0ef21..8181999 100644
--- a/media/libmediaplayerservice/VorbisPlayer.cpp
+++ b/media/libmediaplayerservice/VorbisPlayer.cpp
@@ -86,9 +86,9 @@
release();
}
-status_t VorbisPlayer::setDataSource(const char* path)
-{
- return setdatasource(path, -1, 0, 0x7ffffffffffffffLL); // intentionally less than LONG_MAX
+status_t VorbisPlayer::setDataSource(
+ const char *uri, const KeyedVector<String8, String8> *headers) {
+ return setdatasource(uri, -1, 0, 0x7ffffffffffffffLL); // intentionally less than LONG_MAX
}
status_t VorbisPlayer::setDataSource(int fd, int64_t offset, int64_t length)
diff --git a/media/libmediaplayerservice/VorbisPlayer.h b/media/libmediaplayerservice/VorbisPlayer.h
index 4024654..4a50835 100644
--- a/media/libmediaplayerservice/VorbisPlayer.h
+++ b/media/libmediaplayerservice/VorbisPlayer.h
@@ -37,7 +37,10 @@
virtual void onFirstRef();
virtual status_t initCheck();
- virtual status_t setDataSource(const char* path);
+
+ virtual status_t setDataSource(
+ const char *uri, const KeyedVector<String8, String8> *headers);
+
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual status_t setVideoSurface(const sp<ISurface>& surface) { return UNKNOWN_ERROR; }
virtual status_t prepare();
diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp
index 77bb5b2..b3cc8b6 100644
--- a/media/tests/players/invoke_mock_media_player.cpp
+++ b/media/tests/players/invoke_mock_media_player.cpp
@@ -35,6 +35,8 @@
using android::player_type;
using android::sp;
using android::status_t;
+using android::String8;
+using android::KeyedVector;
// This file contains a test player that is loaded via the
// TestPlayerStub class. The player contains various implementation
@@ -53,7 +55,9 @@
virtual status_t initCheck() {return OK;}
virtual bool hardwareOutput() {return true;}
- virtual status_t setDataSource(const char *url) {
+ virtual status_t setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *) {
LOGV("setDataSource %s", url);
mTest = TEST_UNKNOWN;
if (strncmp(url, kPing, strlen(kPing)) == 0) {