diff options
-rw-r--r-- | drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp | 1 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/default/include/DrmPlugin.h | 2 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/hidl/Android.bp | 2 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp | 13 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp | 7 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h | 3 | ||||
-rw-r--r-- | drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h | 6 | ||||
-rw-r--r-- | media/libmedia/IMediaPlayer.cpp | 41 | ||||
-rw-r--r-- | media/libstagefright/MediaCodec.cpp | 40 |
9 files changed, 102 insertions, 13 deletions
diff --git a/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp index 6ac3510c7c..089eb1cdc9 100644 --- a/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/default/DrmPlugin.cpp @@ -207,6 +207,7 @@ status_t DrmPlugin::queryKeyStatus( } infoMap.clear(); + android::Mutex::Autolock lock(mPlayPolicyLock); for (size_t i = 0; i < mPlayPolicy.size(); ++i) { infoMap.add(mPlayPolicy.keyAt(i), mPlayPolicy.valueAt(i)); } diff --git a/drm/mediadrm/plugins/clearkey/default/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/default/include/DrmPlugin.h index aa9b59ddbb..95f15caffe 100644 --- a/drm/mediadrm/plugins/clearkey/default/include/DrmPlugin.h +++ b/drm/mediadrm/plugins/clearkey/default/include/DrmPlugin.h @@ -262,7 +262,7 @@ private: void initProperties(); void setPlayPolicy(); - android::Mutex mPlayPolicyLock; + mutable android::Mutex mPlayPolicyLock; android::KeyedVector<String8, String8> mPlayPolicy; android::KeyedVector<String8, String8> mStringProperties; android::KeyedVector<String8, Vector<uint8_t>> mByteArrayProperties; diff --git a/drm/mediadrm/plugins/clearkey/hidl/Android.bp b/drm/mediadrm/plugins/clearkey/hidl/Android.bp index a194416c7f..c6afa60f96 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/Android.bp +++ b/drm/mediadrm/plugins/clearkey/hidl/Android.bp @@ -37,7 +37,7 @@ cc_defaults { relative_install_path: "hw", - cflags: ["-Wall", "-Werror"], + cflags: ["-Wall", "-Werror", "-Wthread-safety"], shared_libs: [ "android.hardware.drm@1.0", diff --git a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp index a77759eaef..6f69110d50 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/DrmPlugin.cpp @@ -220,6 +220,7 @@ Status_V1_2 DrmPlugin::getKeyRequestCommon(const hidl_vec<uint8_t>& scope, if (requestString.find(kOfflineLicense) != std::string::npos) { std::string emptyResponse; std::string keySetIdString(keySetId.begin(), keySetId.end()); + Mutex::Autolock lock(mFileHandleLock); if (!mFileHandle.StoreLicense(keySetIdString, DeviceFiles::kLicenseStateReleasing, emptyResponse)) { @@ -335,6 +336,7 @@ bool DrmPlugin::makeKeySetId(std::string* keySetId) { } *keySetId = kKeySetIdPrefix + ByteArrayToHexString( reinterpret_cast<const uint8_t*>(randomData.data()), randomData.size()); + Mutex::Autolock lock(mFileHandleLock); if (mFileHandle.LicenseExists(*keySetId)) { // collision, regenerate ALOGV("Retry generating KeySetId"); @@ -392,6 +394,7 @@ Return<void> DrmPlugin::provideKeyResponse( if (status == Status::OK) { if (isOfflineLicense) { if (isRelease) { + Mutex::Autolock lock(mFileHandleLock); mFileHandle.DeleteLicense(keySetId); mSessionLibrary->destroySession(session); } else { @@ -400,6 +403,7 @@ Return<void> DrmPlugin::provideKeyResponse( return Void(); } + Mutex::Autolock lock(mFileHandleLock); bool ok = mFileHandle.StoreLicense( keySetId, DeviceFiles::kLicenseStateActive, @@ -454,6 +458,7 @@ Return<Status> DrmPlugin::restoreKeys( DeviceFiles::LicenseState licenseState; std::string offlineLicense; Status status = Status::OK; + Mutex::Autolock lock(mFileHandleLock); if (!mFileHandle.RetrieveLicense(std::string(keySetId.begin(), keySetId.end()), &licenseState, &offlineLicense)) { ALOGE("Failed to restore offline license"); @@ -576,7 +581,6 @@ Return<Status> DrmPlugin::setPropertyByteArray( Return<void> DrmPlugin::queryKeyStatus( const hidl_vec<uint8_t>& sessionId, queryKeyStatus_cb _hidl_cb) { - if (sessionId.size() == 0) { // Returns empty key status KeyValue pair _hidl_cb(Status::BAD_VALUE, hidl_vec<KeyValue>()); @@ -586,12 +590,14 @@ Return<void> DrmPlugin::queryKeyStatus( std::vector<KeyValue> infoMapVec; infoMapVec.clear(); + mPlayPolicyLock.lock(); KeyValue keyValuePair; for (size_t i = 0; i < mPlayPolicy.size(); ++i) { keyValuePair.key = mPlayPolicy[i].key; keyValuePair.value = mPlayPolicy[i].value; infoMapVec.push_back(keyValuePair); } + mPlayPolicyLock.unlock(); _hidl_cb(Status::OK, toHidlVec(infoMapVec)); return Void(); } @@ -704,6 +710,8 @@ Return<void> DrmPlugin::getMetrics(getMetrics_cb _hidl_cb) { } Return<void> DrmPlugin::getOfflineLicenseKeySetIds(getOfflineLicenseKeySetIds_cb _hidl_cb) { + Mutex::Autolock lock(mFileHandleLock); + std::vector<std::string> licenseNames = mFileHandle.ListLicenses(); std::vector<KeySetId> keySetIds; if (mMockError != Status_V1_2::OK) { @@ -724,6 +732,7 @@ Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) { return toStatus_1_0(mMockError); } std::string licenseName(keySetId.begin(), keySetId.end()); + Mutex::Autolock lock(mFileHandleLock); if (mFileHandle.DeleteLicense(licenseName)) { return Status::OK; } @@ -732,6 +741,8 @@ Return<Status> DrmPlugin::removeOfflineLicense(const KeySetId& keySetId) { Return<void> DrmPlugin::getOfflineLicenseState(const KeySetId& keySetId, getOfflineLicenseState_cb _hidl_cb) { + Mutex::Autolock lock(mFileHandleLock); + std::string licenseName(keySetId.begin(), keySetId.end()); DeviceFiles::LicenseState state; std::string license; diff --git a/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp index 2dcd00fb27..d29acac30a 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp +++ b/drm/mediadrm/plugins/clearkey/hidl/MemoryFileSystem.cpp @@ -24,11 +24,13 @@ std::string MemoryFileSystem::GetFileName(const std::string& path) { } bool MemoryFileSystem::FileExists(const std::string& fileName) const { + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(fileName); return result != mMemoryFileSystem.end(); } ssize_t MemoryFileSystem::GetFileSize(const std::string& fileName) const { + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(fileName); if (result != mMemoryFileSystem.end()) { return static_cast<ssize_t>(result->second.getFileSize()); @@ -40,6 +42,7 @@ ssize_t MemoryFileSystem::GetFileSize(const std::string& fileName) const { std::vector<std::string> MemoryFileSystem::ListFiles() const { std::vector<std::string> list; + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); for (const auto& filename : mMemoryFileSystem) { list.push_back(filename.first); } @@ -48,6 +51,7 @@ std::vector<std::string> MemoryFileSystem::ListFiles() const { size_t MemoryFileSystem::Read(const std::string& path, std::string* buffer) { std::string key = GetFileName(path); + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(key); if (result != mMemoryFileSystem.end()) { std::string serializedHashFile = result->second.getContent(); @@ -61,6 +65,7 @@ size_t MemoryFileSystem::Read(const std::string& path, std::string* buffer) { size_t MemoryFileSystem::Write(const std::string& path, const MemoryFile& memoryFile) { std::string key = GetFileName(path); + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(key); if (result != mMemoryFileSystem.end()) { mMemoryFileSystem.erase(key); @@ -70,6 +75,7 @@ size_t MemoryFileSystem::Write(const std::string& path, const MemoryFile& memory } bool MemoryFileSystem::RemoveFile(const std::string& fileName) { + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); auto result = mMemoryFileSystem.find(fileName); if (result != mMemoryFileSystem.end()) { mMemoryFileSystem.erase(result); @@ -81,6 +87,7 @@ bool MemoryFileSystem::RemoveFile(const std::string& fileName) { } bool MemoryFileSystem::RemoveAllFiles() { + std::lock_guard<std::mutex> lock(mMemoryFileSystemLock); mMemoryFileSystem.clear(); return mMemoryFileSystem.empty(); } diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h index 076beb8a0d..894985bd1b 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h +++ b/drm/mediadrm/plugins/clearkey/hidl/include/DrmPlugin.h @@ -416,7 +416,8 @@ private: mMockError = Status_V1_2::OK; } - DeviceFiles mFileHandle; + DeviceFiles mFileHandle GUARDED_BY(mFileHandleLock); + Mutex mFileHandleLock; Mutex mSecureStopLock; CLEARKEY_DISALLOW_COPY_AND_ASSIGN_AND_NEW(DrmPlugin); diff --git a/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h b/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h index bcd9fd631a..6ac0e2c4bb 100644 --- a/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h +++ b/drm/mediadrm/plugins/clearkey/hidl/include/MemoryFileSystem.h @@ -5,7 +5,9 @@ #ifndef CLEARKEY_MEMORY_FILE_SYSTEM_H_ #define CLEARKEY_MEMORY_FILE_SYSTEM_H_ +#include <android-base/thread_annotations.h> #include <map> +#include <mutex> #include <string> #include "ClearKeyTypes.h" @@ -49,10 +51,12 @@ class MemoryFileSystem { size_t Write(const std::string& pathName, const MemoryFile& memoryFile); private: + mutable std::mutex mMemoryFileSystemLock; + // License file name is made up of a unique keySetId, therefore, // the filename can be used as the key to locate licenses in the // memory file system. - std::map<std::string, MemoryFile> mMemoryFileSystem; + std::map<std::string, MemoryFile> mMemoryFileSystem GUARDED_BY(mMemoryFileSystemLock); std::string GetFileName(const std::string& path); 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 94c0b841fa..40d8ba25e4 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,13 +253,36 @@ 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); } //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() { |