OSDN Git Service

Require INTERNET permission for network-based content.
authorDave Burke <daveburke@google.com>
Tue, 30 Aug 2011 13:39:17 +0000 (14:39 +0100)
committerDave Burke <daveburke@google.com>
Fri, 2 Sep 2011 10:26:59 +0000 (11:26 +0100)
Bug #1870981

Change-Id: Ia3ad166390c4d60cea19c3783895b078a2c4c15f

cmds/stagefright/stream.cpp
include/media/IMediaPlayer.h
include/media/IMediaPlayerService.h
include/media/mediaplayer.h
media/libmedia/IMediaPlayer.cpp
media/libmedia/IMediaPlayerService.cpp
media/libmedia/mediaplayer.cpp
media/libmediaplayerservice/MediaPlayerService.cpp
media/libmediaplayerservice/MediaPlayerService.h

index aa3bc03..b13236a 100644 (file)
@@ -357,9 +357,9 @@ int main(int argc, char **argv) {
     }
 
     sp<IMediaPlayer> player =
-        service->create(getpid(), client, source, 0);
+        service->create(getpid(), client, 0);
 
-    if (player != NULL) {
+    if (player != NULL && player->setDataSource(source) == NO_ERROR) {
         player->setVideoSurface(surface);
         player->start();
 
index d552b2e..0e2cdf7 100644 (file)
 #include <utils/RefBase.h>
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
+#include <utils/KeyedVector.h>
 
 namespace android {
 
 class Parcel;
 class Surface;
+class IStreamSource;
 class ISurfaceTexture;
 
 class IMediaPlayer: public IInterface
@@ -34,6 +36,10 @@ public:
 
     virtual void            disconnect() = 0;
 
+    virtual status_t        setDataSource(const char *url,
+                                    const KeyedVector<String8, String8>* headers) = 0;
+    virtual status_t        setDataSource(int fd, int64_t offset, int64_t length) = 0;
+    virtual status_t        setDataSource(const sp<IStreamSource>& source) = 0;
     virtual status_t        setVideoSurface(const sp<Surface>& surface) = 0;
     virtual status_t        setVideoSurfaceTexture(
                                     const sp<ISurfaceTexture>& surfaceTexture) = 0;
index 7956788..93bbe13 100644 (file)
@@ -39,17 +39,9 @@ class IMediaPlayerService: public IInterface
 public:
     DECLARE_META_INTERFACE(MediaPlayerService);
 
-    virtual sp<IMediaRecorder>  createMediaRecorder(pid_t pid) = 0;
+    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, const KeyedVector<String8, String8> *headers = NULL,
-            int audioSessionId = 0) = 0;
-    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client,
-            int fd, int64_t offset, int64_t length, int audioSessionId) = 0;
-
-    virtual sp<IMediaPlayer> create(
-            pid_t pid, const sp<IMediaPlayerClient> &client,
-            const sp<IStreamSource> &source, int audioSessionId) = 0;
+    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int audioSessionId = 0) = 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;
index 1a67671..e98d55c 100644 (file)
@@ -21,6 +21,7 @@
 #include <media/IMediaPlayerClient.h>
 #include <media/IMediaPlayer.h>
 #include <media/IMediaDeathNotifier.h>
+#include <media/IStreamSource.h>
 
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
@@ -168,6 +169,7 @@ public:
                     const KeyedVector<String8, String8> *headers);
 
             status_t        setDataSource(int fd, int64_t offset, int64_t length);
+            status_t        setDataSource(const sp<IStreamSource> &source);
             status_t        setVideoSurface(const sp<Surface>& surface);
             status_t        setVideoSurfaceTexture(
                                     const sp<ISurfaceTexture>& surfaceTexture);
@@ -206,7 +208,7 @@ private:
             status_t        seekTo_l(int msec);
             status_t        prepareAsync_l();
             status_t        getDuration_l(int *msec);
-            status_t        setDataSource(const sp<IMediaPlayer>& player);
+            status_t        attachNewPlayer(const sp<IMediaPlayer>& player);
             void            disconnectNativeWindow();
             status_t        reset_l();
 
index 52885d2..bd89ad8 100644 (file)
 #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);
index 17a0362..8e4dd04 100644 (file)
@@ -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();
index 67a66a2..0fc6a8a 100644 (file)
@@ -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;
 }
index 2051b3b..0386d4b 100644 (file)
@@ -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;
 }
 
index e32b92a..53e625a 100644 (file)
@@ -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);