summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorDave Burke <daveburke@google.com>2011-08-30 14:39:17 +0100
committerDave Burke <daveburke@google.com>2011-09-02 11:26:59 +0100
commitd681bbb1767bed09415e050ba78975df214bcd68 (patch)
tree2030c617c61bbf7b6cd8c6bafab601a99b1ac83d /media
parentd942202ee0c92608c648735c3ad0f1bab4312420 (diff)
downloadframeworks_av-d681bbb1767bed09415e050ba78975df214bcd68.zip
frameworks_av-d681bbb1767bed09415e050ba78975df214bcd68.tar.gz
frameworks_av-d681bbb1767bed09415e050ba78975df214bcd68.tar.bz2
Require INTERNET permission for network-based content.
Bug #1870981 Change-Id: Ia3ad166390c4d60cea19c3783895b078a2c4c15f
Diffstat (limited to 'media')
-rw-r--r--media/libmedia/IMediaPlayer.cpp71
-rw-r--r--media/libmedia/IMediaPlayerService.cpp104
-rw-r--r--media/libmedia/mediaplayer.cpp34
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp78
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h17
5 files changed, 131 insertions, 173 deletions
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 52885d2..bd89ad8 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -21,14 +21,20 @@
#include <binder/Parcel.h>
#include <media/IMediaPlayer.h>
+#include <media/IStreamSource.h>
+
#include <surfaceflinger/ISurface.h>
#include <surfaceflinger/Surface.h>
#include <gui/ISurfaceTexture.h>
+#include <utils/String8.h>
namespace android {
enum {
DISCONNECT = IBinder::FIRST_CALL_TRANSACTION,
+ SET_DATA_SOURCE_URL,
+ SET_DATA_SOURCE_FD,
+ SET_DATA_SOURCE_STREAM,
SET_VIDEO_SURFACE,
PREPARE_ASYNC,
START,
@@ -68,6 +74,43 @@ public:
remote()->transact(DISCONNECT, data, &reply);
}
+ status_t setDataSource(const char* url,
+ const KeyedVector<String8, String8>* headers)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+ 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(SET_DATA_SOURCE_URL, data, &reply);
+ return reply.readInt32();
+ }
+
+ status_t setDataSource(int fd, int64_t offset, int64_t length) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+ data.writeFileDescriptor(fd);
+ data.writeInt64(offset);
+ data.writeInt64(length);
+ remote()->transact(SET_DATA_SOURCE_FD, data, &reply);
+ return reply.readInt32();
+ }
+
+ status_t setDataSource(const sp<IStreamSource> &source) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+ data.writeStrongBinder(source->asBinder());
+ return reply.readInt32();
+ }
+
// pass the buffered Surface to the media player service
status_t setVideoSurface(const sp<Surface>& surface)
{
@@ -273,6 +316,34 @@ status_t BnMediaPlayer::onTransact(
disconnect();
return NO_ERROR;
} break;
+ case SET_DATA_SOURCE_URL: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ const char* url = data.readCString();
+ 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(url, numHeaders > 0 ? &headers : NULL));
+ return NO_ERROR;
+ } break;
+ case SET_DATA_SOURCE_FD: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ int fd = data.readFileDescriptor();
+ int64_t offset = data.readInt64();
+ int64_t length = data.readInt64();
+ reply->writeInt32(setDataSource(fd, offset, length));
+ return NO_ERROR;
+ }
+ case SET_DATA_SOURCE_STREAM: {
+ CHECK_INTERFACE(IMediaPlayer, data, reply);
+ sp<IStreamSource> source =
+ interface_cast<IStreamSource>(data.readStrongBinder());
+ reply->writeInt32(setDataSource(source));
+ return NO_ERROR;
+ }
case SET_VIDEO_SURFACE: {
CHECK_INTERFACE(IMediaPlayer, data, reply);
sp<Surface> surface = Surface::readFromParcel(data);
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 17a0362..8e4dd04 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -30,9 +30,7 @@
namespace android {
enum {
- CREATE_URL = IBinder::FIRST_CALL_TRANSACTION,
- CREATE_FD,
- CREATE_STREAM,
+ CREATE = IBinder::FIRST_CALL_TRANSACTION,
DECODE_URL,
DECODE_FD,
CREATE_MEDIA_RECORDER,
@@ -60,28 +58,14 @@ public:
}
virtual sp<IMediaPlayer> create(
- pid_t pid, const sp<IMediaPlayerClient>& client,
- const char* url, const KeyedVector<String8, String8> *headers, int audioSessionId) {
+ pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId) {
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));
- }
- }
data.writeInt32(audioSessionId);
- remote()->transact(CREATE_URL, data, &reply);
-
+ remote()->transact(CREATE, data, &reply);
return interface_cast<IMediaPlayer>(reply.readStrongBinder());
}
@@ -94,38 +78,6 @@ public:
return interface_cast<IMediaRecorder>(reply.readStrongBinder());
}
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd,
- int64_t offset, int64_t length, int audioSessionId)
- {
- Parcel data, reply;
- data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
- data.writeInt32(pid);
- data.writeStrongBinder(client->asBinder());
- data.writeFileDescriptor(fd);
- data.writeInt64(offset);
- data.writeInt64(length);
- data.writeInt32(audioSessionId);
-
- remote()->transact(CREATE_FD, data, &reply);
-
- return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
- }
-
- virtual sp<IMediaPlayer> create(
- pid_t pid, const sp<IMediaPlayerClient> &client,
- const sp<IStreamSource> &source, int audioSessionId) {
- Parcel data, reply;
- data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
- data.writeInt32(static_cast<int32_t>(pid));
- data.writeStrongBinder(client->asBinder());
- data.writeStrongBinder(source->asBinder());
- data.writeInt32(static_cast<int32_t>(audioSessionId));
-
- remote()->transact(CREATE_STREAM, data, &reply);
-
- return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
- }
-
virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
{
Parcel data, reply;
@@ -181,62 +133,16 @@ status_t BnMediaPlayerService::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
- case CREATE_URL: {
+ case CREATE: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
pid_t pid = data.readInt32();
sp<IMediaPlayerClient> client =
interface_cast<IMediaPlayerClient>(data.readStrongBinder());
- const char* url = data.readCString();
-
- 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);
- }
- int audioSessionId = data.readInt32();
-
- sp<IMediaPlayer> player = create(
- pid, client, url, numHeaders > 0 ? &headers : NULL, audioSessionId);
-
- reply->writeStrongBinder(player->asBinder());
- return NO_ERROR;
- } break;
- case CREATE_FD: {
- CHECK_INTERFACE(IMediaPlayerService, data, reply);
- pid_t pid = data.readInt32();
- sp<IMediaPlayerClient> client = interface_cast<IMediaPlayerClient>(data.readStrongBinder());
- int fd = dup(data.readFileDescriptor());
- int64_t offset = data.readInt64();
- int64_t length = data.readInt64();
int audioSessionId = data.readInt32();
-
- sp<IMediaPlayer> player = create(pid, client, fd, offset, length, audioSessionId);
+ sp<IMediaPlayer> player = create(pid, client, audioSessionId);
reply->writeStrongBinder(player->asBinder());
return NO_ERROR;
} break;
- case CREATE_STREAM:
- {
- CHECK_INTERFACE(IMediaPlayerService, data, reply);
-
- pid_t pid = static_cast<pid_t>(data.readInt32());
-
- sp<IMediaPlayerClient> client =
- interface_cast<IMediaPlayerClient>(data.readStrongBinder());
-
- sp<IStreamSource> source =
- interface_cast<IStreamSource>(data.readStrongBinder());
-
- int audioSessionId = static_cast<int>(data.readInt32());
-
- sp<IMediaPlayer> player =
- create(pid, client, source, audioSessionId);
-
- reply->writeStrongBinder(player->asBinder());
- return OK;
- break;
- }
case DECODE_URL: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
const char* url = data.readCString();
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 67a66a2..0fc6a8a 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -108,7 +108,7 @@ status_t MediaPlayer::setListener(const sp<MediaPlayerListener>& listener)
}
-status_t MediaPlayer::setDataSource(const sp<IMediaPlayer>& player)
+status_t MediaPlayer::attachNewPlayer(const sp<IMediaPlayer>& player)
{
status_t err = UNKNOWN_ERROR;
sp<IMediaPlayer> p;
@@ -117,7 +117,7 @@ status_t MediaPlayer::setDataSource(const sp<IMediaPlayer>& player)
if ( !( (mCurrentState & MEDIA_PLAYER_IDLE) ||
(mCurrentState == MEDIA_PLAYER_STATE_ERROR ) ) ) {
- LOGE("setDataSource called in state %d", mCurrentState);
+ LOGE("attachNewPlayer called in state %d", mCurrentState);
return INVALID_OPERATION;
}
@@ -147,9 +147,11 @@ status_t MediaPlayer::setDataSource(
if (url != NULL) {
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
- sp<IMediaPlayer> player(
- service->create(getpid(), this, url, headers, mAudioSessionId));
- err = setDataSource(player);
+ sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
+ err = attachNewPlayer(player);
+ if (err == NO_ERROR) {
+ err = mPlayer->setDataSource(url, headers);
+ }
}
}
return err;
@@ -161,8 +163,26 @@ status_t MediaPlayer::setDataSource(int fd, int64_t offset, int64_t length)
status_t err = UNKNOWN_ERROR;
const sp<IMediaPlayerService>& service(getMediaPlayerService());
if (service != 0) {
- sp<IMediaPlayer> player(service->create(getpid(), this, fd, offset, length, mAudioSessionId));
- err = setDataSource(player);
+ sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
+ err = attachNewPlayer(player);
+ if (err == NO_ERROR) {
+ err = mPlayer->setDataSource(fd, offset, length);
+ }
+ }
+ return err;
+}
+
+status_t MediaPlayer::setDataSource(const sp<IStreamSource> &source)
+{
+ LOGV("setDataSource");
+ status_t err = UNKNOWN_ERROR;
+ const sp<IMediaPlayerService>& service(getMediaPlayerService());
+ if (service != 0) {
+ sp<IMediaPlayer> player(service->create(getpid(), this, mAudioSessionId));
+ err = attachNewPlayer(player);
+ if (err == NO_ERROR) {
+ err = mPlayer->setDataSource(source);
+ }
}
return err;
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 2051b3b..0386d4b 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -176,6 +176,16 @@ bool findMetadata(const Metadata::Filter& filter, const int32_t val)
namespace android {
+static bool checkPermission(const char* permissionString) {
+#ifndef HAVE_ANDROID_OS
+ return true;
+#endif
+ if (getpid() == IPCThreadState::self()->getCallingPid()) return true;
+ bool ok = checkCallingPermission(String16(permissionString));
+ if (!ok) LOGE("Request requires %s", permissionString);
+ return ok;
+}
+
// TODO: Temp hack until we can register players
typedef struct {
const char *extension;
@@ -245,31 +255,8 @@ sp<IMediaMetadataRetriever> MediaPlayerService::createMetadataRetriever(pid_t pi
return retriever;
}
-sp<IMediaPlayer> MediaPlayerService::create(
- pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
- const KeyedVector<String8, String8> *headers, int audioSessionId)
-{
- int32_t connId = android_atomic_inc(&mNextConnId);
-
- sp<Client> c = new Client(
- this, pid, connId, client, audioSessionId,
- IPCThreadState::self()->getCallingUid());
-
- LOGV("Create new client(%d) from pid %d, uid %d, url=%s, connId=%d, audioSessionId=%d",
- connId, pid, IPCThreadState::self()->getCallingUid(), url, connId, audioSessionId);
- if (NO_ERROR != c->setDataSource(url, headers))
- {
- c.clear();
- return c;
- }
- wp<Client> w = c;
- Mutex::Autolock lock(mLock);
- mClients.add(w);
- return c;
-}
-
sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,
- int fd, int64_t offset, int64_t length, int audioSessionId)
+ int audioSessionId)
{
int32_t connId = android_atomic_inc(&mNextConnId);
@@ -277,40 +264,14 @@ sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClie
this, pid, connId, client, audioSessionId,
IPCThreadState::self()->getCallingUid());
- LOGV("Create new client(%d) from pid %d, uid %d, fd=%d, offset=%lld, "
- "length=%lld, audioSessionId=%d", connId, pid,
- IPCThreadState::self()->getCallingUid(), fd, offset, length, audioSessionId);
- if (NO_ERROR != c->setDataSource(fd, offset, length)) {
- c.clear();
- } else {
- wp<Client> w = c;
- Mutex::Autolock lock(mLock);
- mClients.add(w);
- }
- ::close(fd);
- return c;
-}
-
-sp<IMediaPlayer> MediaPlayerService::create(
- pid_t pid, const sp<IMediaPlayerClient> &client,
- const sp<IStreamSource> &source, int audioSessionId) {
- int32_t connId = android_atomic_inc(&mNextConnId);
-
- sp<Client> c = new Client(
- this, pid, connId, client, audioSessionId,
- IPCThreadState::self()->getCallingUid());
-
- LOGV("Create new client(%d) from pid %d, audioSessionId=%d",
- connId, pid, audioSessionId);
+ LOGV("Create new client(%d) from pid %d, uid %d, ", connId, pid,
+ IPCThreadState::self()->getCallingUid());
- if (OK != c->setDataSource(source)) {
- c.clear();
- } else {
- wp<Client> w = c;
+ wp<Client> w = c;
+ {
Mutex::Autolock lock(mLock);
mClients.add(w);
}
-
return c;
}
@@ -701,6 +662,14 @@ status_t MediaPlayerService::Client::setDataSource(
if (url == NULL)
return UNKNOWN_ERROR;
+ if ((strncmp(url, "http://", 7) == 0) ||
+ (strncmp(url, "https://", 8) == 0) ||
+ (strncmp(url, "rtsp://", 7) == 0)) {
+ if (!checkPermission("android.permission.INTERNET")) {
+ return PERMISSION_DENIED;
+ }
+ }
+
if (strncmp(url, "content://", 10) == 0) {
// get a filedescriptor for the content Uri and
// pass it to the setDataSource(fd) method
@@ -781,6 +750,7 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64
// now set data source
mStatus = p->setDataSource(fd, offset, length);
if (mStatus == NO_ERROR) mPlayer = p;
+
return mStatus;
}
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index e32b92a..53e625a 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -188,16 +188,7 @@ public:
void removeMediaRecorderClient(wp<MediaRecorderClient> client);
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,
- const KeyedVector<String8, String8> *headers, int audioSessionId);
-
- virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length, int audioSessionId);
-
- virtual sp<IMediaPlayer> create(
- pid_t pid, const sp<IMediaPlayerClient> &client,
- const sp<IStreamSource> &source, int audioSessionId);
+ virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId);
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);
@@ -284,13 +275,13 @@ private:
sp<MediaPlayerBase> createPlayer(player_type playerType);
- status_t setDataSource(
+ virtual status_t setDataSource(
const char *url,
const KeyedVector<String8, String8> *headers);
- status_t setDataSource(int fd, int64_t offset, int64_t length);
+ virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
- status_t setDataSource(const sp<IStreamSource> &source);
+ virtual status_t setDataSource(const sp<IStreamSource> &source);
static void notify(void* cookie, int msg,
int ext1, int ext2, const Parcel *obj);