From a8328dd2f945e8357b3a58c76b0a71a4a2463aa1 Mon Sep 17 00:00:00 2001 From: "John \"Juce\" Bruce" Date: Wed, 3 Jun 2015 15:57:00 -0700 Subject: [PATCH] Delete Singleton on Library Unload (This is a merge of http://go/wvgerrit/14531) As an optimization, the Media Server now unloads our library when not in use. This has exposed a bug by which we were never deleting the CDM singleton. Fix is to make WvContentDecryptionModule an Android smart pointer ref base and then make sure all the plugins store a strong pointer to it. The singleton is a weak pointer, so when the last plugin is cleaned up, the CDM will be as well. And on the off chance that the library isn't immediately unloaded, the singleton code will generate a new CDM next time one is needed. Bug: 21153732 Change-Id: Ifaf02fa9afe0a70a8b53e8b92ee0a3d1359ca001 --- .../cdm/include/wv_content_decryption_module.h | 3 ++- libwvdrmengine/include/WVCDMSingleton.h | 4 +++- .../mediacrypto/include/WVCryptoPlugin.h | 5 +++-- libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp | 2 +- libwvdrmengine/mediadrm/include/WVDrmPlugin.h | 5 +++-- libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp | 2 +- libwvdrmengine/src/WVCDMSingleton.cpp | 15 ++++++++++++--- 7 files changed, 25 insertions(+), 11 deletions(-) diff --git a/libwvdrmengine/cdm/include/wv_content_decryption_module.h b/libwvdrmengine/cdm/include/wv_content_decryption_module.h index 182ec088..de877338 100644 --- a/libwvdrmengine/cdm/include/wv_content_decryption_module.h +++ b/libwvdrmengine/cdm/include/wv_content_decryption_module.h @@ -4,6 +4,7 @@ #define CDM_BASE_WV_CONTENT_DECRYPTION_MODULE_H_ #include +#include #include "lock.h" #include "timer.h" @@ -15,7 +16,7 @@ class CdmClientPropertySet; class CdmEngine; class WvCdmEventListener; -class WvContentDecryptionModule : public TimerHandler { +class WvContentDecryptionModule : public android::RefBase, public TimerHandler { public: WvContentDecryptionModule(); virtual ~WvContentDecryptionModule(); diff --git a/libwvdrmengine/include/WVCDMSingleton.h b/libwvdrmengine/include/WVCDMSingleton.h index e82bfc59..ecb49dab 100644 --- a/libwvdrmengine/include/WVCDMSingleton.h +++ b/libwvdrmengine/include/WVCDMSingleton.h @@ -5,11 +5,13 @@ #ifndef WV_CDM_SINGLETON_H_ #define WV_CDM_SINGLETON_H_ +#include "utils/StrongPointer.h" + #include "wv_content_decryption_module.h" namespace wvdrm { -wvcdm::WvContentDecryptionModule* getCDM(); +android::sp getCDM(); } // namespace wvdrm diff --git a/libwvdrmengine/mediacrypto/include/WVCryptoPlugin.h b/libwvdrmengine/mediacrypto/include/WVCryptoPlugin.h index 25beecba..33942a6f 100644 --- a/libwvdrmengine/mediacrypto/include/WVCryptoPlugin.h +++ b/libwvdrmengine/mediacrypto/include/WVCryptoPlugin.h @@ -7,6 +7,7 @@ #include +#include "utils/StrongPointer.h" #include "utils/Vector.h" #include "media/hardware/CryptoAPI.h" @@ -19,7 +20,7 @@ namespace wvdrm { class WVCryptoPlugin : public android::CryptoPlugin { public: WVCryptoPlugin(const void* data, size_t size, - wvcdm::WvContentDecryptionModule* cdm); + const android::sp& cdm); virtual ~WVCryptoPlugin() {} virtual bool requiresSecureDecoderComponent(const char* mime) const; @@ -37,7 +38,7 @@ class WVCryptoPlugin : public android::CryptoPlugin { private: DISALLOW_EVIL_CONSTRUCTORS(WVCryptoPlugin); - wvcdm::WvContentDecryptionModule* const mCDM; + android::sp const mCDM; bool mTestMode; wvcdm::CdmSessionId mSessionId; diff --git a/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp b/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp index df3bc3e8..c39f0551 100644 --- a/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp +++ b/libwvdrmengine/mediacrypto/src/WVCryptoPlugin.cpp @@ -29,7 +29,7 @@ using namespace std; using namespace wvcdm; WVCryptoPlugin::WVCryptoPlugin(const void* data, size_t size, - WvContentDecryptionModule* cdm) + const sp& cdm) : mCDM(cdm), mTestMode(false), mSessionId(configureTestMode(data, size)) {} diff --git a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h index a298d092..b880b442 100644 --- a/libwvdrmengine/mediadrm/include/WVDrmPlugin.h +++ b/libwvdrmengine/mediadrm/include/WVDrmPlugin.h @@ -17,6 +17,7 @@ #include "utils/KeyedVector.h" #include "utils/List.h" #include "utils/String8.h" +#include "utils/StrongPointer.h" #include "utils/Vector.h" #include "wv_cdm_event_listener.h" #include "wv_content_decryption_module.h" @@ -41,7 +42,7 @@ const OEMCrypto_Algorithm kInvalidCrytpoAlgorithm = class WVDrmPlugin : public android::DrmPlugin, public wvcdm::WvCdmEventListener { public: - WVDrmPlugin(WvContentDecryptionModule* cdm, + WVDrmPlugin(const android::sp& cdm, WVGenericCryptoInterface* crypto); virtual ~WVDrmPlugin(); @@ -248,7 +249,7 @@ class WVDrmPlugin : public android::DrmPlugin, std::string mAppId; } mPropertySet; - WvContentDecryptionModule* mCDM; + android::sp const mCDM; WVGenericCryptoInterface* mCrypto; std::string mOrigin; map mCryptoSessions; diff --git a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp index 21f5d0c4..4dac6fed 100644 --- a/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp +++ b/libwvdrmengine/mediadrm/src/WVDrmPlugin.cpp @@ -73,7 +73,7 @@ DrmPlugin::KeyStatusType ConvertFromCdmKeyStatus(CdmKeyStatus keyStatus) { } // namespace -WVDrmPlugin::WVDrmPlugin(WvContentDecryptionModule* cdm, +WVDrmPlugin::WVDrmPlugin(const sp& cdm, WVGenericCryptoInterface* crypto) : mCDM(cdm), mCrypto(crypto), mOrigin(), mCryptoSessions() {} diff --git a/libwvdrmengine/src/WVCDMSingleton.cpp b/libwvdrmengine/src/WVCDMSingleton.cpp index c89aacae..c6d21977 100644 --- a/libwvdrmengine/src/WVCDMSingleton.cpp +++ b/libwvdrmengine/src/WVCDMSingleton.cpp @@ -9,21 +9,30 @@ #include "WVCDMSingleton.h" #include "utils/Mutex.h" +#include "utils/RefBase.h" namespace wvdrm { using wvcdm::WvContentDecryptionModule; using android::Mutex; +using android::sp; +using android::wp; Mutex cdmLock; -WvContentDecryptionModule* cdm = NULL; +// The strong pointers that keep this object alive live in the plugin objects. +// If all the plugins are deleted, the CDM will be deleted, and subsequent +// invocations of this code will construct a new CDM. +wp sCdm; -WvContentDecryptionModule* getCDM() { - Mutex::Autolock lock(cdmLock); +sp getCDM() { + Mutex::Autolock lock(cdmLock); // This function is a critical section. + + sp cdm = sCdm.promote(); if (cdm == NULL) { ALOGD("Instantiating CDM."); cdm = new WvContentDecryptionModule(); + sCdm = cdm; } return cdm;