From e96c64a0d21d1ab2c9ba9726766fd8432462888a Mon Sep 17 00:00:00 2001 From: Sungtak Lee Date: Tue, 7 Aug 2018 18:01:50 -0700 Subject: [PATCH 1/9] NuPlayer2CCDecoder: Add bound check before memcpy Test: none Bug: 111874331 Change-Id: I6764802e8e8afd7e970ee433741f73a9b3d366dd (cherry picked from commit 71920217d6017a5112ecd73abc4e68c16d680458) --- .../nuplayer2/NuPlayer2CCDecoder.cpp | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp index e48e388234..e2159659f5 100644 --- a/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp +++ b/media/libmediaplayer2/nuplayer2/NuPlayer2CCDecoder.cpp @@ -372,10 +372,16 @@ bool NuPlayer2::CCDecoder::parseMPEGCCData(int64_t timeUs, const uint8_t *data, timeUs, mDTVCCPacket->data(), mDTVCCPacket->size()); mDTVCCPacket->setRange(0, 0); } + if (mDTVCCPacket->size() + 2 > mDTVCCPacket->capacity()) { + return false; + } memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2); mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2); br.skipBits(16); } else if (mDTVCCPacket->size() > 0 && cc_type == 2) { + if (mDTVCCPacket->size() + 2 > mDTVCCPacket->capacity()) { + return false; + } memcpy(mDTVCCPacket->data() + mDTVCCPacket->size(), br.data(), 2); mDTVCCPacket->setRange(0, mDTVCCPacket->size() + 2); br.skipBits(16); @@ -403,6 +409,9 @@ bool NuPlayer2::CCDecoder::parseMPEGCCData(int64_t timeUs, const uint8_t *data, line21CCBuf = new ABuffer((cc_count - i) * sizeof(CCData)); line21CCBuf->setRange(0, 0); } + if (line21CCBuf->size() + sizeof(cc) > line21CCBuf->capacity()) { + return false; + } memcpy(line21CCBuf->data() + line21CCBuf->size(), &cc, sizeof(cc)); line21CCBuf->setRange(0, line21CCBuf->size() + sizeof(CCData)); } @@ -464,6 +473,9 @@ bool NuPlayer2::CCDecoder::parseDTVCCPacket(int64_t timeUs, const uint8_t *data, size_t trackIndex = getTrackIndex(kTrackTypeCEA708, service_number, &trackAdded); if (mSelectedTrack == (ssize_t)trackIndex) { sp ccPacket = new ABuffer(block_size); + if (ccPacket->capacity() == 0) { + return false; + } memcpy(ccPacket->data(), br.data(), block_size); mCCMap.add(timeUs, ccPacket); } @@ -527,10 +539,12 @@ void NuPlayer2::CCDecoder::display(int64_t timeUs) { ccBuf = new ABuffer(size); ccBuf->setRange(0, 0); - for (ssize_t i = 0; i <= index; ++i) { - sp buf = mCCMap.valueAt(i); - memcpy(ccBuf->data() + ccBuf->size(), buf->data(), buf->size()); - ccBuf->setRange(0, ccBuf->size() + buf->size()); + if (ccBuf->capacity() > 0) { + for (ssize_t i = 0; i <= index; ++i) { + sp buf = mCCMap.valueAt(i); + memcpy(ccBuf->data() + ccBuf->size(), buf->data(), buf->size()); + ccBuf->setRange(0, ccBuf->size() + buf->size()); + } } } From c927af1287e3b90d77e40aae26f4a3b61de3ac09 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Fri, 24 Aug 2018 14:49:33 -0700 Subject: [PATCH 2/9] Fix race condition for cas sessions -- DO NOT MERGE Change the session to shared_ptr and use atomic_load/store. Test: POC; CTS MediaCasTest; CTS MediaDrmClearkeyTest# testClearKeyPlaybackMpeg2ts bug: 113027383 Change-Id: I75f4cb33a022f28d45918442d64c5c46df2640ef --- .../plugins/clearkey/ClearKeyCasPlugin.cpp | 24 ++++++++++--------- .../plugins/clearkey/ClearKeyCasPlugin.h | 2 +- .../clearkey/ClearKeySessionLibrary.cpp | 8 +++---- .../plugins/clearkey/ClearKeySessionLibrary.h | 10 ++++---- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp index 4ed5fce8ad..757219484c 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp +++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp @@ -118,9 +118,9 @@ status_t ClearKeyCasPlugin::openSession(CasSessionId* sessionId) { status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) { ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_DRM_SESSION_NOT_OPENED; } @@ -132,9 +132,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData( const CasSessionId &sessionId, const CasData & /*data*/) { ALOGV("setSessionPrivateData: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_DRM_SESSION_NOT_OPENED; } return OK; @@ -143,9 +143,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData( status_t ClearKeyCasPlugin::processEcm( const CasSessionId &sessionId, const CasEcm& ecm) { ALOGV("processEcm: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_DRM_SESSION_NOT_OPENED; } @@ -415,15 +415,15 @@ status_t ClearKeyDescramblerPlugin::setMediaCasSession( const CasSessionId &sessionId) { ALOGV("setMediaCasSession: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { ALOGE("ClearKeyDescramblerPlugin: session not found"); return ERROR_DRM_SESSION_NOT_OPENED; } - mCASSession = session; + std::atomic_store(&mCASSession, session); return OK; } @@ -444,12 +444,14 @@ ssize_t ClearKeyDescramblerPlugin::descramble( subSamplesToString(subSamples, numSubSamples).string(), srcPtr, dstPtr, srcOffset, dstOffset); - if (mCASSession == NULL) { + std::shared_ptr session = std::atomic_load(&mCASSession); + + if (session.get() == nullptr) { ALOGE("Uninitialized CAS session!"); return ERROR_DRM_DECRYPT_UNIT_NOT_INITIALIZED; } - return mCASSession->decrypt( + return session->decrypt( secure, scramblingControl, numSubSamples, subSamples, (uint8_t*)srcPtr + srcOffset, diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h index b7134e4038..8a9ea83686 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h +++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h @@ -120,7 +120,7 @@ public: AString *errorDetailMsg) override; private: - sp mCASSession; + std::shared_ptr mCASSession; String8 subSamplesToString( SubSample const *subSamples, diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp index faea00816c..9fd2d4de9d 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp +++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp @@ -56,7 +56,7 @@ status_t ClearKeySessionLibrary::addSession( Mutex::Autolock lock(mSessionsLock); - sp session = new ClearKeyCasSession(plugin); + std::shared_ptr session(new ClearKeyCasSession(plugin)); uint8_t *byteArray = (uint8_t *) &mNextSessionId; sessionId->push_back(byteArray[3]); @@ -69,7 +69,7 @@ status_t ClearKeySessionLibrary::addSession( return OK; } -sp ClearKeySessionLibrary::findSession( +std::shared_ptr ClearKeySessionLibrary::findSession( const CasSessionId& sessionId) { Mutex::Autolock lock(mSessionsLock); @@ -88,7 +88,7 @@ void ClearKeySessionLibrary::destroySession(const CasSessionId& sessionId) { return; } - sp session = mIDToSessionMap.valueAt(index); + std::shared_ptr session = mIDToSessionMap.valueAt(index); mIDToSessionMap.removeItemsAt(index); } @@ -96,7 +96,7 @@ void ClearKeySessionLibrary::destroyPlugin(CasPlugin *plugin) { Mutex::Autolock lock(mSessionsLock); for (ssize_t index = mIDToSessionMap.size() - 1; index >= 0; index--) { - sp session = mIDToSessionMap.valueAt(index); + std::shared_ptr session = mIDToSessionMap.valueAt(index); if (session->getPlugin() == plugin) { mIDToSessionMap.removeItemsAt(index); } diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h index 01f5f477e2..a537e63bc0 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h +++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h @@ -32,6 +32,10 @@ class KeyFetcher; class ClearKeyCasSession : public RefBase { public: + explicit ClearKeyCasSession(CasPlugin *plugin); + + virtual ~ClearKeyCasSession(); + ssize_t decrypt( bool secure, DescramblerPlugin::ScramblingControl scramblingControl, @@ -58,8 +62,6 @@ private: friend class ClearKeySessionLibrary; - explicit ClearKeyCasSession(CasPlugin *plugin); - virtual ~ClearKeyCasSession(); CasPlugin* getPlugin() const { return mPlugin; } status_t decryptPayload( const AES_KEY& key, size_t length, size_t offset, char* buffer) const; @@ -73,7 +75,7 @@ public: status_t addSession(CasPlugin *plugin, CasSessionId *sessionId); - sp findSession(const CasSessionId& sessionId); + std::shared_ptr findSession(const CasSessionId& sessionId); void destroySession(const CasSessionId& sessionId); @@ -85,7 +87,7 @@ private: Mutex mSessionsLock; uint32_t mNextSessionId; - KeyedVector> mIDToSessionMap; + KeyedVector> mIDToSessionMap; ClearKeySessionLibrary(); DISALLOW_EVIL_CONSTRUCTORS(ClearKeySessionLibrary); From 58b9e7d73c9e2a7a7ff11a4584fd1e1105669831 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Fri, 24 Aug 2018 14:49:33 -0700 Subject: [PATCH 3/9] Fix race condition for cas sessions -- DO NOT MERGE Change the session to shared_ptr and use atomic_load/store. Test: POC; CTS MediaCasTest; CTS MediaDrmClearkeyTest# testClearKeyPlaybackMpeg2ts bug: 113027383 Change-Id: I75f4cb33a022f28d45918442d64c5c46df2640ef --- .../plugins/clearkey/ClearKeyCasPlugin.cpp | 24 ++++++++++--------- .../plugins/clearkey/ClearKeyCasPlugin.h | 2 +- .../clearkey/ClearKeySessionLibrary.cpp | 8 +++---- .../plugins/clearkey/ClearKeySessionLibrary.h | 10 ++++---- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp index e27631fc53..50acc1dab5 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp +++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp @@ -118,9 +118,9 @@ status_t ClearKeyCasPlugin::openSession(CasSessionId* sessionId) { status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) { ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_CAS_SESSION_NOT_OPENED; } @@ -132,9 +132,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData( const CasSessionId &sessionId, const CasData & /*data*/) { ALOGV("setSessionPrivateData: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_CAS_SESSION_NOT_OPENED; } return OK; @@ -143,9 +143,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData( status_t ClearKeyCasPlugin::processEcm( const CasSessionId &sessionId, const CasEcm& ecm) { ALOGV("processEcm: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_CAS_SESSION_NOT_OPENED; } @@ -415,15 +415,15 @@ status_t ClearKeyDescramblerPlugin::setMediaCasSession( const CasSessionId &sessionId) { ALOGV("setMediaCasSession: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { ALOGE("ClearKeyDescramblerPlugin: session not found"); return ERROR_CAS_SESSION_NOT_OPENED; } - mCASSession = session; + std::atomic_store(&mCASSession, session); return OK; } @@ -444,12 +444,14 @@ ssize_t ClearKeyDescramblerPlugin::descramble( subSamplesToString(subSamples, numSubSamples).string(), srcPtr, dstPtr, srcOffset, dstOffset); - if (mCASSession == NULL) { + std::shared_ptr session = std::atomic_load(&mCASSession); + + if (session.get() == nullptr) { ALOGE("Uninitialized CAS session!"); return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED; } - return mCASSession->decrypt( + return session->decrypt( secure, scramblingControl, numSubSamples, subSamples, (uint8_t*)srcPtr + srcOffset, diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h index b7134e4038..8a9ea83686 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h +++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h @@ -120,7 +120,7 @@ public: AString *errorDetailMsg) override; private: - sp mCASSession; + std::shared_ptr mCASSession; String8 subSamplesToString( SubSample const *subSamples, diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp index faea00816c..9fd2d4de9d 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp +++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp @@ -56,7 +56,7 @@ status_t ClearKeySessionLibrary::addSession( Mutex::Autolock lock(mSessionsLock); - sp session = new ClearKeyCasSession(plugin); + std::shared_ptr session(new ClearKeyCasSession(plugin)); uint8_t *byteArray = (uint8_t *) &mNextSessionId; sessionId->push_back(byteArray[3]); @@ -69,7 +69,7 @@ status_t ClearKeySessionLibrary::addSession( return OK; } -sp ClearKeySessionLibrary::findSession( +std::shared_ptr ClearKeySessionLibrary::findSession( const CasSessionId& sessionId) { Mutex::Autolock lock(mSessionsLock); @@ -88,7 +88,7 @@ void ClearKeySessionLibrary::destroySession(const CasSessionId& sessionId) { return; } - sp session = mIDToSessionMap.valueAt(index); + std::shared_ptr session = mIDToSessionMap.valueAt(index); mIDToSessionMap.removeItemsAt(index); } @@ -96,7 +96,7 @@ void ClearKeySessionLibrary::destroyPlugin(CasPlugin *plugin) { Mutex::Autolock lock(mSessionsLock); for (ssize_t index = mIDToSessionMap.size() - 1; index >= 0; index--) { - sp session = mIDToSessionMap.valueAt(index); + std::shared_ptr session = mIDToSessionMap.valueAt(index); if (session->getPlugin() == plugin) { mIDToSessionMap.removeItemsAt(index); } diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h index 01f5f477e2..a537e63bc0 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h +++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h @@ -32,6 +32,10 @@ class KeyFetcher; class ClearKeyCasSession : public RefBase { public: + explicit ClearKeyCasSession(CasPlugin *plugin); + + virtual ~ClearKeyCasSession(); + ssize_t decrypt( bool secure, DescramblerPlugin::ScramblingControl scramblingControl, @@ -58,8 +62,6 @@ private: friend class ClearKeySessionLibrary; - explicit ClearKeyCasSession(CasPlugin *plugin); - virtual ~ClearKeyCasSession(); CasPlugin* getPlugin() const { return mPlugin; } status_t decryptPayload( const AES_KEY& key, size_t length, size_t offset, char* buffer) const; @@ -73,7 +75,7 @@ public: status_t addSession(CasPlugin *plugin, CasSessionId *sessionId); - sp findSession(const CasSessionId& sessionId); + std::shared_ptr findSession(const CasSessionId& sessionId); void destroySession(const CasSessionId& sessionId); @@ -85,7 +87,7 @@ private: Mutex mSessionsLock; uint32_t mNextSessionId; - KeyedVector> mIDToSessionMap; + KeyedVector> mIDToSessionMap; ClearKeySessionLibrary(); DISALLOW_EVIL_CONSTRUCTORS(ClearKeySessionLibrary); From 7934a8f7ee0988b181980b9e6f24ca7dd357f5e3 Mon Sep 17 00:00:00 2001 From: Chong Zhang Date: Fri, 24 Aug 2018 14:49:33 -0700 Subject: [PATCH 4/9] Fix race condition for cas sessions Change the session to shared_ptr and use atomic_load/store. Test: POC; CTS MediaCasTest; CTS MediaDrmClearkeyTest# testClearKeyPlaybackMpeg2ts bug: 113027383 Change-Id: I75f4cb33a022f28d45918442d64c5c46df2640ef --- .../plugins/clearkey/ClearKeyCasPlugin.cpp | 24 ++++++++++--------- .../plugins/clearkey/ClearKeyCasPlugin.h | 2 +- .../clearkey/ClearKeySessionLibrary.cpp | 8 +++---- .../plugins/clearkey/ClearKeySessionLibrary.h | 10 ++++---- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp index 73ed8c3637..1558e8b8da 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp +++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.cpp @@ -118,9 +118,9 @@ status_t ClearKeyCasPlugin::openSession(CasSessionId* sessionId) { status_t ClearKeyCasPlugin::closeSession(const CasSessionId &sessionId) { ALOGV("closeSession: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_CAS_SESSION_NOT_OPENED; } @@ -132,9 +132,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData( const CasSessionId &sessionId, const CasData & /*data*/) { ALOGV("setSessionPrivateData: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_CAS_SESSION_NOT_OPENED; } return OK; @@ -143,9 +143,9 @@ status_t ClearKeyCasPlugin::setSessionPrivateData( status_t ClearKeyCasPlugin::processEcm( const CasSessionId &sessionId, const CasEcm& ecm) { ALOGV("processEcm: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { return ERROR_CAS_SESSION_NOT_OPENED; } @@ -418,15 +418,15 @@ status_t ClearKeyDescramblerPlugin::setMediaCasSession( const CasSessionId &sessionId) { ALOGV("setMediaCasSession: sessionId=%s", sessionIdToString(sessionId).string()); - sp session = + std::shared_ptr session = ClearKeySessionLibrary::get()->findSession(sessionId); - if (session == NULL) { + if (session.get() == nullptr) { ALOGE("ClearKeyDescramblerPlugin: session not found"); return ERROR_CAS_SESSION_NOT_OPENED; } - mCASSession = session; + std::atomic_store(&mCASSession, session); return OK; } @@ -447,12 +447,14 @@ ssize_t ClearKeyDescramblerPlugin::descramble( subSamplesToString(subSamples, numSubSamples).string(), srcPtr, dstPtr, srcOffset, dstOffset); - if (mCASSession == NULL) { + std::shared_ptr session = std::atomic_load(&mCASSession); + + if (session.get() == nullptr) { ALOGE("Uninitialized CAS session!"); return ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED; } - return mCASSession->decrypt( + return session->decrypt( secure, scramblingControl, numSubSamples, subSamples, (uint8_t*)srcPtr + srcOffset, diff --git a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h index 42cfb8f2fb..389e1728d7 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h +++ b/drm/mediacas/plugins/clearkey/ClearKeyCasPlugin.h @@ -120,7 +120,7 @@ public: AString *errorDetailMsg) override; private: - sp mCASSession; + std::shared_ptr mCASSession; String8 subSamplesToString( SubSample const *subSamples, diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp index 4b4051d5bb..3bb11768bf 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp +++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.cpp @@ -56,7 +56,7 @@ status_t ClearKeySessionLibrary::addSession( Mutex::Autolock lock(mSessionsLock); - sp session = new ClearKeyCasSession(plugin); + std::shared_ptr session(new ClearKeyCasSession(plugin)); uint8_t *byteArray = (uint8_t *) &mNextSessionId; sessionId->push_back(byteArray[3]); @@ -69,7 +69,7 @@ status_t ClearKeySessionLibrary::addSession( return OK; } -sp ClearKeySessionLibrary::findSession( +std::shared_ptr ClearKeySessionLibrary::findSession( const CasSessionId& sessionId) { Mutex::Autolock lock(mSessionsLock); @@ -88,7 +88,7 @@ void ClearKeySessionLibrary::destroySession(const CasSessionId& sessionId) { return; } - sp session = mIDToSessionMap.valueAt(index); + std::shared_ptr session = mIDToSessionMap.valueAt(index); mIDToSessionMap.removeItemsAt(index); } @@ -96,7 +96,7 @@ void ClearKeySessionLibrary::destroyPlugin(CasPlugin *plugin) { Mutex::Autolock lock(mSessionsLock); for (ssize_t index = (ssize_t)mIDToSessionMap.size() - 1; index >= 0; index--) { - sp session = mIDToSessionMap.valueAt(index); + std::shared_ptr session = mIDToSessionMap.valueAt(index); if (session->getPlugin() == plugin) { mIDToSessionMap.removeItemsAt(index); } diff --git a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h index 01f5f477e2..a537e63bc0 100644 --- a/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h +++ b/drm/mediacas/plugins/clearkey/ClearKeySessionLibrary.h @@ -32,6 +32,10 @@ class KeyFetcher; class ClearKeyCasSession : public RefBase { public: + explicit ClearKeyCasSession(CasPlugin *plugin); + + virtual ~ClearKeyCasSession(); + ssize_t decrypt( bool secure, DescramblerPlugin::ScramblingControl scramblingControl, @@ -58,8 +62,6 @@ private: friend class ClearKeySessionLibrary; - explicit ClearKeyCasSession(CasPlugin *plugin); - virtual ~ClearKeyCasSession(); CasPlugin* getPlugin() const { return mPlugin; } status_t decryptPayload( const AES_KEY& key, size_t length, size_t offset, char* buffer) const; @@ -73,7 +75,7 @@ public: status_t addSession(CasPlugin *plugin, CasSessionId *sessionId); - sp findSession(const CasSessionId& sessionId); + std::shared_ptr findSession(const CasSessionId& sessionId); void destroySession(const CasSessionId& sessionId); @@ -85,7 +87,7 @@ private: Mutex mSessionsLock; uint32_t mNextSessionId; - KeyedVector> mIDToSessionMap; + KeyedVector> mIDToSessionMap; ClearKeySessionLibrary(); DISALLOW_EVIL_CONSTRUCTORS(ClearKeySessionLibrary); From c20825bd3b751cffcd8d7e66e97c3b1a91ef21e0 Mon Sep 17 00:00:00 2001 From: "ray-cy.lee" Date: Tue, 7 Mar 2017 18:25:15 +0800 Subject: [PATCH 5/9] CTS error while media dump() MediaExtractor should not dump information. CTS is checking and failing due to the dump. Bug: 114770654 Change-Id: Ie5bae5de39545dede6da4198240b4f38c50050b7 --- media/libmedia/IMediaExtractor.cpp | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp index 4be111813c..744af1be00 100644 --- a/media/libmedia/IMediaExtractor.cpp +++ b/media/libmedia/IMediaExtractor.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -272,13 +273,21 @@ void registerMediaExtractor( status_t dumpExtractors(int fd, const Vector&) { String8 out; - out.append("Recent extractors, most recent first:\n"); - { - Mutex::Autolock lock(sExtractorsLock); - for (size_t i = 0; i < sExtractors.size(); i++) { - const ExtractorInstance &instance = sExtractors.itemAt(i); - out.append(" "); - out.append(instance.toString()); + const IPCThreadState* ipc = IPCThreadState::self(); + const int pid = ipc->getCallingPid(); + const int uid = ipc->getCallingUid(); + if (!PermissionCache::checkPermission(String16("android.permission.DUMP"), pid, uid)) { + out.appendFormat("Permission Denial: " + "can't dump MediaExtractor from pid=%d, uid=%d\n", pid, uid); + } else { + out.append("Recent extractors, most recent first:\n"); + { + Mutex::Autolock lock(sExtractorsLock); + for (size_t i = 0; i < sExtractors.size(); i++) { + const ExtractorInstance &instance = sExtractors.itemAt(i); + out.append(" "); + out.append(instance.toString()); + } } } write(fd, out.string(), out.size()); From 2fae5b7c8d457856f0896aafc61845ce5b209d4d Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Thu, 12 Jul 2018 17:14:27 -0700 Subject: [PATCH 6/9] Effect config parser: fix use after free on file path ParsingResult::configPath is the path of the configuration file used for the factory config parsing. This path is used for an error log if the configuration file has errors. The paths used to be a static string literals stored as char* without lifecycle management. When it was changed to dynamic strings, the code was not updated. This patch changes it to a std::string. Bug: 111261328 Bug: 117118292 Test: flash and check effect works Change-Id: Ia2022c794936f3f75793371cdde86c3047bb6c0a Signed-off-by: Kevin Rocard (cherry picked from commit a82fd60004272acc0ea25914cac429035082be21) --- .../config/include/media/EffectsConfig.h | 2 +- media/libeffects/config/src/EffectsConfig.cpp | 16 ++++++++-------- .../factory/EffectsXmlConfigLoader.cpp | 3 ++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/media/libeffects/config/include/media/EffectsConfig.h b/media/libeffects/config/include/media/EffectsConfig.h index 55b946f620..fa0415bbdc 100644 --- a/media/libeffects/config/include/media/EffectsConfig.h +++ b/media/libeffects/config/include/media/EffectsConfig.h @@ -96,7 +96,7 @@ struct ParsingResult { /** Parsed config, nullptr if the xml lib could not load the file */ std::unique_ptr parsedConfig; size_t nbSkippedElement; //< Number of skipped invalid library, effect or processing chain - const char* configPath; //< Path to the loaded configuration + const std::string configPath; //< Path to the loaded configuration }; /** Parses the provided effect configuration. diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp index d79501ff48..351b1ee8c8 100644 --- a/media/libeffects/config/src/EffectsConfig.cpp +++ b/media/libeffects/config/src/EffectsConfig.cpp @@ -250,14 +250,14 @@ bool parseStream(const XMLElement& xmlStream, Effects& effects, std::vector(); @@ -295,7 +295,7 @@ ParsingResult parseWithPath(const char* path) { } } } - return {std::move(config), nbSkippedElements, path}; + return {std::move(config), nbSkippedElements, std::move(path)}; } }; // namespace @@ -310,14 +310,14 @@ ParsingResult parse(const char* path) { if (access(defaultPath.c_str(), R_OK) != 0) { continue; } - auto result = parseWithPath(defaultPath.c_str()); + auto result = parseWithPath(std::move(defaultPath)); if (result.parsedConfig != nullptr) { return result; } } ALOGE("Could not parse effect configuration in any of the default locations."); - return {nullptr, 0, nullptr}; + return {nullptr, 0, ""}; } } // namespace effectsConfig diff --git a/media/libeffects/factory/EffectsXmlConfigLoader.cpp b/media/libeffects/factory/EffectsXmlConfigLoader.cpp index 7a7d431d99..052a88b585 100644 --- a/media/libeffects/factory/EffectsXmlConfigLoader.cpp +++ b/media/libeffects/factory/EffectsXmlConfigLoader.cpp @@ -327,7 +327,8 @@ extern "C" ssize_t EffectLoadXmlEffectConfig(const char* path) &gSkippedEffects, &gSubEffectList); ALOGE_IF(result.nbSkippedElement != 0, "%zu errors during loading of configuration: %s", - result.nbSkippedElement, result.configPath ?: "No config file found"); + result.nbSkippedElement, + result.configPath.empty() ? "No config file found" : result.configPath.c_str()); return result.nbSkippedElement; } From 70a12185ecb780a1cf523d28ed4128ae67b341bd Mon Sep 17 00:00:00 2001 From: Stanley Tng Date: Wed, 10 Oct 2018 18:48:33 -0700 Subject: [PATCH 7/9] Add transaction code to TimeCheck crash When there is a TimeCheck timeout crash, the transaction code will be useful for debugging. Test: Manual run Bug: 117349352 Change-Id: I8a93ead7ec7379f51b211ca31c68ec6ec2553afc Merged-In: I4716852c77d56703ad5f3dfc2500f598a2b80a12 (cherry picked from commit de9e33dfcbdabc0227ab47e4a13325b5b410ab39) --- media/libaudioclient/IAudioFlinger.cpp | 4 +++- media/libaudioclient/IAudioPolicyService.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/media/libaudioclient/IAudioFlinger.cpp b/media/libaudioclient/IAudioFlinger.cpp index 00af7e8ea1..9f3b742413 100644 --- a/media/libaudioclient/IAudioFlinger.cpp +++ b/media/libaudioclient/IAudioFlinger.cpp @@ -951,7 +951,9 @@ status_t BnAudioFlinger::onTransact( break; } - TimeCheck check("IAudioFlinger"); + char timeCheckString[64]; + snprintf(timeCheckString, sizeof(timeCheckString), "IAudioFlinger: %d", code); + TimeCheck check(timeCheckString); switch (code) { case CREATE_TRACK: { diff --git a/media/libaudioclient/IAudioPolicyService.cpp b/media/libaudioclient/IAudioPolicyService.cpp index a1236e7389..8cd4a85794 100644 --- a/media/libaudioclient/IAudioPolicyService.cpp +++ b/media/libaudioclient/IAudioPolicyService.cpp @@ -948,7 +948,9 @@ status_t BnAudioPolicyService::onTransact( break; } - TimeCheck check("IAudioPolicyService"); + char timeCheckString[64]; + snprintf(timeCheckString, sizeof(timeCheckString), "IAudioPolicyService: %d", code); + TimeCheck check(timeCheckString); switch (code) { case SET_DEVICE_CONNECTION_STATE: { From f20dd6b779d0e156dccabb6d56b769eb5d6f5f5c Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Mon, 15 Oct 2018 16:28:06 +0100 Subject: [PATCH 8/9] Camera: Don't drop preview buffers during video In case the camera device supports ZSL, avoid dropping preview buffers while video recording is active. Preview must not get interrupted in this case. Bug: 117640175 Test: Manual using application, Camera CTS Change-Id: I9021b4c46428e008298ddef0a86972640b0afa41 Merged-In: I9021b4c46428e008298ddef0a86972640b0afa41 (cherry picked from commit 6c79c9aa7fe61ea81a154f5c92f96b34889029a0) --- .../camera/libcameraservice/api1/client2/CaptureSequencer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp index 1ee216fd9a..a9b2e7550e 100644 --- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp +++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp @@ -553,9 +553,11 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCapture( return DONE; } - if (l.mParameters.isDeviceZslSupported) { + if ((l.mParameters.isDeviceZslSupported) && (l.mParameters.state != Parameters::RECORD) && + (l.mParameters.state != Parameters::VIDEO_SNAPSHOT)) { // If device ZSL is supported, drop all pending preview buffers to reduce the chance of // rendering preview frames newer than the still frame. + // Additionally, preview must not get interrupted during video recording. client->getCameraDevice()->dropStreamBuffers(true, client->getPreviewStreamId()); } From 2dd98038ac81eb65283f85cb9fdab836377a9df0 Mon Sep 17 00:00:00 2001 From: Nobuaki Tanaka Date: Wed, 12 Sep 2018 16:22:17 +0900 Subject: [PATCH 9/9] Support to play the various tones as per the Indian standard To play the following tones as per Indian standards. - Dial tone - Busy tone - Congestion tone - Call waiting tone - Ringing tone Bug: 117161543 Bug: 118655632 Test: Play each tone in indian locale (cherry picked from commit f4a4005adb8340b2883d0b6771bcebac5c9c75b5) Change-Id: I6358b18bf23fa21b6fd0a6e3ff4d296b2df6e69d (cherry picked from commit b7afce9ef7d9c4cd5181501447663921617f560e) --- media/libaudioclient/ToneGenerator.cpp | 40 +++++++++++++++++++ .../include/media/ToneGenerator.h | 7 ++++ 2 files changed, 47 insertions(+) diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp index 57167275a6..d846d79394 100644 --- a/media/libaudioclient/ToneGenerator.cpp +++ b/media/libaudioclient/ToneGenerator.cpp @@ -826,6 +826,34 @@ const ToneGenerator::ToneDescriptor ToneGenerator::sToneDescriptors[] = { { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, .repeatCnt = ToneGenerator::TONEGEN_INF, .repeatSegment = 0 }, // TONE_IE_CALL_WAITING + { .segments = { { .duration = ToneGenerator::TONEGEN_INF, .waveFreq = { 375, 400, 425, 0 }, 0, 0 }, + { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, + .repeatCnt = ToneGenerator::TONEGEN_INF, + .repeatSegment = 0 }, // TONE_INDIA_DIAL + { .segments = { { .duration = 750, .waveFreq = { 400, 0 }, 0, 0 }, + { .duration = 750, .waveFreq = { 0 }, 0, 0 }, + { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, + .repeatCnt = ToneGenerator::TONEGEN_INF, + .repeatSegment = 0 }, // TONE_INDIA_BUSY + { .segments = { { .duration = 250, .waveFreq = { 400, 0 }, 0, 0 }, + { .duration = 250, .waveFreq = { 0 }, 0, 0 }, + { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, + .repeatCnt = ToneGenerator::TONEGEN_INF, + .repeatSegment = 0 }, // TONE_INDIA_CONGESTION + { .segments = { { .duration = 200, .waveFreq = { 400, 0 }, 0, 0 }, + { .duration = 100, .waveFreq = { 0 }, 0, 0 }, + { .duration = 200, .waveFreq = { 400, 0 }, 0, 0 }, + { .duration = 7500, .waveFreq = { 0 }, 0, 0 }, + { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, + .repeatCnt = ToneGenerator::TONEGEN_INF, + .repeatSegment = 0 }, // TONE_INDIA_CALL_WAITING + { .segments = { { .duration = 400, .waveFreq = { 375, 400, 425, 0 }, 0, 0 }, + { .duration = 200, .waveFreq = { 0 }, 0, 0 }, + { .duration = 400, .waveFreq = { 375, 400, 425, 0 }, 0, 0 }, + { .duration = 2000, .waveFreq = { 0 }, 0, 0 }, + { .duration = 0 , .waveFreq = { 0 }, 0, 0}}, + .repeatCnt = ToneGenerator::TONEGEN_INF, + .repeatSegment = 0 }, // TONE_INDIA_RINGTONE }; // Used by ToneGenerator::getToneForRegion() to convert user specified supervisory tone type @@ -900,6 +928,16 @@ const unsigned char /*tone_type*/ ToneGenerator::sToneMappingTable[NUM_REGIONS-1 TONE_SUP_ERROR, // TONE_SUP_ERROR TONE_IE_CALL_WAITING, // TONE_SUP_CALL_WAITING TONE_IE_RINGTONE // TONE_SUP_RINGTONE + }, + { // INDIA + TONE_INDIA_DIAL, // TONE_SUP_DIAL + TONE_INDIA_BUSY, // TONE_SUP_BUSY + TONE_INDIA_CONGESTION, // TONE_SUP_CONGESTION + TONE_SUP_RADIO_ACK, // TONE_SUP_RADIO_ACK + TONE_SUP_RADIO_NOTAVAIL, // TONE_SUP_RADIO_NOTAVAIL + TONE_SUP_ERROR, // TONE_SUP_ERROR + TONE_INDIA_CALL_WAITING, // TONE_SUP_CALL_WAITING + TONE_INDIA_RINGTONE // TONE_SUP_RINGTONE } }; @@ -971,6 +1009,8 @@ ToneGenerator::ToneGenerator(audio_stream_type_t streamType, float volume, bool mRegion = HONGKONG; } else if (strstr(value, "ie") != NULL) { mRegion = IRELAND; + } else if (strstr(value, "in") != NULL) { + mRegion = INDIA; } else { mRegion = CEPT; } diff --git a/media/libaudioclient/include/media/ToneGenerator.h b/media/libaudioclient/include/media/ToneGenerator.h index 247703fe95..7ae6aa67a2 100644 --- a/media/libaudioclient/include/media/ToneGenerator.h +++ b/media/libaudioclient/include/media/ToneGenerator.h @@ -212,6 +212,12 @@ private: // IRELAND Supervisory tones TONE_IE_RINGTONE, // Ring Tone: A 400Hz + 450Hz tone repeated in a 0.4s on, 0.2s off, 0.4s on, 2.0s off pattern. TONE_IE_CALL_WAITING, // Call waiting tone: 425Hz tone repeated in a 0.18s on, 0.2s off, 0.2s on, 4.5s off pattern. + // INDIA supervisory tones + TONE_INDIA_DIAL, // Dial tone: 400 Hz tone modulated with 25Hz, continuous + TONE_INDIA_BUSY, // Busy tone: 400 Hz, 750ms ON, 750ms OFF... + TONE_INDIA_CONGESTION, // Congestion tone: 400 Hz, 250ms ON, 250ms OFF... + TONE_INDIA_CALL_WAITING, // Call waiting tone: 400 Hz, tone repeated in a 0.2s on, 0.1s off, 0.2s on, 7.5s off pattern. + TONE_INDIA_RINGTONE, // Ring tone: 400 Hz tone modulated with 25Hz, 0.4 on 0.2 off 0.4 on 2..0 off NUM_ALTERNATE_TONES }; @@ -223,6 +229,7 @@ private: SINGAPORE, HONGKONG, IRELAND, + INDIA, CEPT, NUM_REGIONS };