diff options
-rw-r--r-- | media/libmedia/IMediaPlayer.cpp | 41 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 40 |
2 files changed, 73 insertions, 8 deletions
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 20bc23d4f7..eaa2e6363b 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -20,6 +20,7 @@ #include <sys/types.h> #include <android/IDataSource.h> +#include <binder/IPCThreadState.h> #include <binder/Parcel.h> #include <gui/IGraphicBufferProducer.h> #include <media/AudioResamplerPublic.h> @@ -82,10 +83,36 @@ enum { }; // ModDrm helpers -static void readVector(const Parcel& reply, Vector<uint8_t>& vector) { - uint32_t size = reply.readUint32(); - vector.insertAt((size_t)0, size); - reply.read(vector.editArray(), size); +static status_t readVector(const Parcel& reply, Vector<uint8_t>& vector) { + uint32_t size = 0; + status_t status = reply.readUint32(&size); + if (status == OK) { + status = size <= reply.dataAvail() ? OK : BAD_VALUE; + } + if (status == OK) { + status = vector.insertAt((size_t) 0, size) >= 0 ? OK : NO_MEMORY; + } + if (status == OK) { + status = reply.read(vector.editArray(), size); + } + if (status != OK) { + char errorMsg[100]; + char buganizerId[] = "173720767"; + snprintf(errorMsg, + sizeof(errorMsg), + "%s: failed to read array. Size: %d, status: %d.", + __func__, + size, + status); + android_errorWriteWithInfoLog( + /* safetyNet tag= */ 0x534e4554, + buganizerId, + IPCThreadState::self()->getCallingUid(), + errorMsg, + strlen(errorMsg)); + ALOGE("%s (b/%s)", errorMsg, buganizerId); + } + return status; } static void writeVector(Parcel& data, Vector<uint8_t> const& vector) { @@ -961,8 +988,10 @@ status_t BnMediaPlayer::onTransact( uint8_t uuid[16]; data.read(uuid, sizeof(uuid)); Vector<uint8_t> drmSessionId; - readVector(data, drmSessionId); - + status_t status = readVector(data, drmSessionId); + if (status != OK) { + return status; + } uint32_t result = prepareDrm(uuid, drmSessionId); reply->writeInt32(result); return OK; diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp index 4d617ae02e..553f59a41f 100644 --- a/media/libstagefright/MediaCodec.cpp +++ b/media/libstagefright/MediaCodec.cpp @@ -19,6 +19,8 @@ #define LOG_TAG "MediaCodec" #include <utils/Log.h> +#include <set> + #include <inttypes.h> #include <stdlib.h> @@ -201,6 +203,10 @@ struct MediaCodec::ResourceManagerServiceProxy : public RefBase { // implements DeathRecipient static void BinderDiedCallback(void* cookie); void binderDied(); + static Mutex sLockCookies; + static std::set<void*> sCookies; + static void addCookie(void* cookie); + static void removeCookie(void* cookie); void addResource(const MediaResourceParcel &resource); void removeResource(const MediaResourceParcel &resource); @@ -227,8 +233,15 @@ MediaCodec::ResourceManagerServiceProxy::ResourceManagerServiceProxy( } MediaCodec::ResourceManagerServiceProxy::~ResourceManagerServiceProxy() { + + // remove the cookie, so any in-flight death notification will get dropped + // by our handler. + removeCookie(this); + + Mutex::Autolock _l(mLock); if (mService != nullptr) { AIBinder_unlinkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this); + mService = nullptr; } } @@ -240,6 +253,10 @@ void MediaCodec::ResourceManagerServiceProxy::init() { return; } + // so our handler will process the death notifications + addCookie(this); + + // after this, require mLock whenever using mService AIBinder_linkToDeath(mService->asBinder().get(), mDeathRecipient.get(), this); // Kill clients pending removal. @@ -247,9 +264,28 @@ void MediaCodec::ResourceManagerServiceProxy::init() { } //static +Mutex MediaCodec::ResourceManagerServiceProxy::sLockCookies; +std::set<void*> MediaCodec::ResourceManagerServiceProxy::sCookies; + +//static +void MediaCodec::ResourceManagerServiceProxy::addCookie(void* cookie) { + Mutex::Autolock _l(sLockCookies); + sCookies.insert(cookie); +} + +//static +void MediaCodec::ResourceManagerServiceProxy::removeCookie(void* cookie) { + Mutex::Autolock _l(sLockCookies); + sCookies.erase(cookie); +} + +//static void MediaCodec::ResourceManagerServiceProxy::BinderDiedCallback(void* cookie) { - auto thiz = static_cast<ResourceManagerServiceProxy*>(cookie); - thiz->binderDied(); + Mutex::Autolock _l(sLockCookies); + if (sCookies.find(cookie) != sCookies.end()) { + auto thiz = static_cast<ResourceManagerServiceProxy*>(cookie); + thiz->binderDied(); + } } void MediaCodec::ResourceManagerServiceProxy::binderDied() { |