diff --git a/dom/media/eme/CDMCallbackProxy.cpp b/dom/media/eme/CDMCallbackProxy.cpp index e8570b6d303d..78ab8a9bd784 100644 --- a/dom/media/eme/CDMCallbackProxy.cpp +++ b/dom/media/eme/CDMCallbackProxy.cpp @@ -267,35 +267,18 @@ CDMCallbackProxy::SessionError(const nsCString& aSessionId, } void -CDMCallbackProxy::KeyIdUsable(const nsCString& aSessionId, - const nsTArray& aKeyId) +CDMCallbackProxy::KeyStatusChanged(const nsCString& aSessionId, + const nsTArray& aKeyId, + GMPMediaKeyStatus aStatus) { MOZ_ASSERT(mProxy->IsOnGMPThread()); bool keysChange = false; { CDMCaps::AutoLock caps(mProxy->Capabilites()); - keysChange = caps.SetKeyUsable(aKeyId, NS_ConvertUTF8toUTF16(aSessionId)); - } - if (keysChange) { - nsRefPtr task; - task = NS_NewRunnableMethodWithArg(mProxy, - &CDMProxy::OnKeysChange, - NS_ConvertUTF8toUTF16(aSessionId)); - NS_DispatchToMainThread(task); - } -} - -void -CDMCallbackProxy::KeyIdNotUsable(const nsCString& aSessionId, - const nsTArray& aKeyId) -{ - MOZ_ASSERT(mProxy->IsOnGMPThread()); - - bool keysChange = false; - { - CDMCaps::AutoLock caps(mProxy->Capabilites()); - keysChange = caps.SetKeyUnusable(aKeyId, NS_ConvertUTF8toUTF16(aSessionId)); + keysChange = caps.SetKeyStatus(aKeyId, + NS_ConvertUTF8toUTF16(aSessionId), + aStatus); } if (keysChange) { nsRefPtr task; diff --git a/dom/media/eme/CDMCallbackProxy.h b/dom/media/eme/CDMCallbackProxy.h index 47a94abf4540..6f41743ad601 100644 --- a/dom/media/eme/CDMCallbackProxy.h +++ b/dom/media/eme/CDMCallbackProxy.h @@ -43,11 +43,9 @@ public: uint32_t aSystemCode, const nsCString& aMessage) MOZ_OVERRIDE; - virtual void KeyIdUsable(const nsCString& aSessionId, - const nsTArray& aKeyId) MOZ_OVERRIDE; - - virtual void KeyIdNotUsable(const nsCString& aSessionId, - const nsTArray& aKeyId) MOZ_OVERRIDE; + virtual void KeyStatusChanged(const nsCString& aSessionId, + const nsTArray& aKeyId, + GMPMediaKeyStatus aStatus) MOZ_OVERRIDE; virtual void SetCaps(uint64_t aCaps) MOZ_OVERRIDE; diff --git a/dom/media/eme/CDMCaps.cpp b/dom/media/eme/CDMCaps.cpp index e86cccbc1a6c..16f7ed486c9b 100644 --- a/dom/media/eme/CDMCaps.cpp +++ b/dom/media/eme/CDMCaps.cpp @@ -5,7 +5,6 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "CDMCaps.h" -#include "gmp-decryption.h" #include "EMELog.h" #include "nsThreadUtils.h" #include "SamplesWaitingForKey.h" @@ -80,9 +79,9 @@ bool CDMCaps::AutoLock::IsKeyUsable(const CencKeyId& aKeyId) { mData.mMonitor.AssertCurrentThreadOwns(); - const auto& keys = mData.mUsableKeyIds; + const auto& keys = mData.mKeyStatuses; for (size_t i = 0; i < keys.Length(); i++) { - if (keys[i].mId == aKeyId) { + if (keys[i].mId == aKeyId && keys[i].mStatus == kGMPUsable) { return true; } } @@ -90,15 +89,32 @@ CDMCaps::AutoLock::IsKeyUsable(const CencKeyId& aKeyId) } bool -CDMCaps::AutoLock::SetKeyUsable(const CencKeyId& aKeyId, - const nsString& aSessionId) +CDMCaps::AutoLock::SetKeyStatus(const CencKeyId& aKeyId, + const nsString& aSessionId, + GMPMediaKeyStatus aStatus) { mData.mMonitor.AssertCurrentThreadOwns(); - UsableKey key(aKeyId, aSessionId); - if (mData.mUsableKeyIds.Contains(key)) { - return false; + KeyStatus key(aKeyId, aSessionId, aStatus); + auto index = mData.mKeyStatuses.IndexOf(key); + + if (aStatus == kGMPUnknown) { + // Return true if the element is found to notify key changes. + return mData.mKeyStatuses.RemoveElement(key); } - mData.mUsableKeyIds.AppendElement(key); + + if (index != mData.mKeyStatuses.NoIndex) { + if (mData.mKeyStatuses[index].mStatus == aStatus) { + return false; + } + mData.mKeyStatuses[index].mStatus = aStatus; + } else { + mData.mKeyStatuses.AppendElement(key); + } + + if (aStatus != kGMPUsable) { + return true; + } + auto& waiters = mData.mWaitForKeys; size_t i = 0; while (i < waiters.Length()) { @@ -113,26 +129,6 @@ CDMCaps::AutoLock::SetKeyUsable(const CencKeyId& aKeyId, return true; } -bool -CDMCaps::AutoLock::SetKeyUnusable(const CencKeyId& aKeyId, - const nsString& aSessionId) -{ - mData.mMonitor.AssertCurrentThreadOwns(); - UsableKey key(aKeyId, aSessionId); - if (!mData.mUsableKeyIds.Contains(key)) { - return false; - } - auto& keys = mData.mUsableKeyIds; - for (size_t i = 0; i < keys.Length(); i++) { - if (keys[i].mId == aKeyId && - keys[i].mSessionId == aSessionId) { - keys.RemoveElementAt(i); - break; - } - } - return true; -} - void CDMCaps::AutoLock::NotifyWhenKeyIdUsable(const CencKeyId& aKey, SamplesWaitingForKey* aListener) @@ -178,12 +174,12 @@ void CDMCaps::AutoLock::GetUsableKeysForSession(const nsAString& aSessionId, nsTArray& aOutKeyIds) { - for (size_t i = 0; i < mData.mUsableKeyIds.Length(); i++) { - const auto& key = mData.mUsableKeyIds[i]; - if (key.mSessionId.Equals(aSessionId)) { + for (size_t i = 0; i < mData.mKeyStatuses.Length(); i++) { + const auto& key = mData.mKeyStatuses[i]; + if (key.mSessionId.Equals(aSessionId) && key.mStatus == kGMPUsable) { aOutKeyIds.AppendElement(key.mId); } } } -} // namespace mozilla \ No newline at end of file +} // namespace mozilla diff --git a/dom/media/eme/CDMCaps.h b/dom/media/eme/CDMCaps.h index 5e2415f8b780..cd34348ab51a 100644 --- a/dom/media/eme/CDMCaps.h +++ b/dom/media/eme/CDMCaps.h @@ -14,6 +14,7 @@ #include "nsTArray.h" #include "mozilla/Attributes.h" #include "SamplesWaitingForKey.h" +#include "gmp-decryption.h" namespace mozilla { @@ -37,13 +38,9 @@ public: bool IsKeyUsable(const CencKeyId& aKeyId); - // Returns true if setting this key usable results in the usable keys - // changing for this session, i.e. the key was not previously marked usable. - bool SetKeyUsable(const CencKeyId& aKeyId, const nsString& aSessionId); - - // Returns true if setting this key unusable results in the usable keys - // changing for this session, i.e. the key was previously marked usable. - bool SetKeyUnusable(const CencKeyId& aKeyId, const nsString& aSessionId); + // Returns true if key status changed, + // i.e. the key status changed from usable to expired. + bool SetKeyStatus(const CencKeyId& aKeyId, const nsString& aSessionId, GMPMediaKeyStatus aStatus); void GetUsableKeysForSession(const nsAString& aSessionId, nsTArray& aOutKeyIds); @@ -85,25 +82,29 @@ private: Monitor mMonitor; - struct UsableKey { - UsableKey(const CencKeyId& aId, - const nsString& aSessionId) + struct KeyStatus { + KeyStatus(const CencKeyId& aId, + const nsString& aSessionId, + GMPMediaKeyStatus aStatus) : mId(aId) , mSessionId(aSessionId) + , mStatus(aStatus) {} - UsableKey(const UsableKey& aOther) + KeyStatus(const KeyStatus& aOther) : mId(aOther.mId) , mSessionId(aOther.mSessionId) + , mStatus(aOther.mStatus) {} - bool operator==(const UsableKey& aOther) const { + bool operator==(const KeyStatus& aOther) const { return mId == aOther.mId && mSessionId == aOther.mSessionId; }; CencKeyId mId; nsString mSessionId; + GMPMediaKeyStatus mStatus; }; - nsTArray mUsableKeyIds; + nsTArray mKeyStatuses; nsTArray mWaitForKeys; diff --git a/dom/media/gmp-plugin/fake.info b/dom/media/gmp-plugin/fake.info index 5b29387b6b71..58624893c0cf 100644 --- a/dom/media/gmp-plugin/fake.info +++ b/dom/media/gmp-plugin/fake.info @@ -1,5 +1,5 @@ Name: fake Description: Fake GMP Plugin Version: 1.0 -APIs: encode-video[h264], decode-video[h264], eme-decrypt-v4[fake] +APIs: encode-video[h264], decode-video[h264], eme-decrypt-v5[fake] Libraries: dxva2.dll diff --git a/dom/media/gmp/GMPDecryptorChild.cpp b/dom/media/gmp/GMPDecryptorChild.cpp index b8cf43da7cf8..4c17065b6f9d 100644 --- a/dom/media/gmp/GMPDecryptorChild.cpp +++ b/dom/media/gmp/GMPDecryptorChild.cpp @@ -126,27 +126,17 @@ GMPDecryptorChild::SessionError(const char* aSessionId, } void -GMPDecryptorChild::KeyIdUsable(const char* aSessionId, - uint32_t aSessionIdLength, - const uint8_t* aKeyId, - uint32_t aKeyIdLength) +GMPDecryptorChild::KeyStatusChanged(const char* aSessionId, + uint32_t aSessionIdLength, + const uint8_t* aKeyId, + uint32_t aKeyIdLength, + GMPMediaKeyStatus aStatus) { nsAutoTArray kid; kid.AppendElements(aKeyId, aKeyIdLength); - CALL_ON_GMP_THREAD(SendKeyIdUsable, - nsAutoCString(aSessionId, aSessionIdLength), kid); -} - -void -GMPDecryptorChild::KeyIdNotUsable(const char* aSessionId, - uint32_t aSessionIdLength, - const uint8_t* aKeyId, - uint32_t aKeyIdLength) -{ - nsAutoTArray kid; - kid.AppendElements(aKeyId, aKeyIdLength); - CALL_ON_GMP_THREAD(SendKeyIdNotUsable, - nsAutoCString(aSessionId, aSessionIdLength), kid); + CALL_ON_GMP_THREAD(SendKeyStatusChanged, + nsAutoCString(aSessionId, aSessionIdLength), kid, + aStatus); } void diff --git a/dom/media/gmp/GMPDecryptorChild.h b/dom/media/gmp/GMPDecryptorChild.h index ee1f72c327fd..f175ece69854 100644 --- a/dom/media/gmp/GMPDecryptorChild.h +++ b/dom/media/gmp/GMPDecryptorChild.h @@ -63,15 +63,11 @@ public: const char* aMessage, uint32_t aMessageLength) MOZ_OVERRIDE; - virtual void KeyIdUsable(const char* aSessionId, - uint32_t aSessionIdLength, - const uint8_t* aKeyId, - uint32_t aKeyIdLength) MOZ_OVERRIDE; - - virtual void KeyIdNotUsable(const char* aSessionId, - uint32_t aSessionIdLength, - const uint8_t* aKeyId, - uint32_t aKeyIdLength) MOZ_OVERRIDE; + virtual void KeyStatusChanged(const char* aSessionId, + uint32_t aSessionIdLength, + const uint8_t* aKeyId, + uint32_t aKeyIdLength, + GMPMediaKeyStatus aStatus) MOZ_OVERRIDE; virtual void SetCapabilities(uint64_t aCaps) MOZ_OVERRIDE; diff --git a/dom/media/gmp/GMPDecryptorParent.cpp b/dom/media/gmp/GMPDecryptorParent.cpp index 946687b786e5..b87e70b19626 100644 --- a/dom/media/gmp/GMPDecryptorParent.cpp +++ b/dom/media/gmp/GMPDecryptorParent.cpp @@ -265,26 +265,15 @@ GMPDecryptorParent::RecvSessionError(const nsCString& aSessionId, } bool -GMPDecryptorParent::RecvKeyIdUsable(const nsCString& aSessionId, - InfallibleTArray&& aKeyId) +GMPDecryptorParent::RecvKeyStatusChanged(const nsCString& aSessionId, + InfallibleTArray&& aKeyId, + const GMPMediaKeyStatus& aStatus) { if (!mIsOpen) { NS_WARNING("Trying to use a dead GMP decrypter!"); return false; } - mCallback->KeyIdUsable(aSessionId, aKeyId); - return true; -} - -bool -GMPDecryptorParent::RecvKeyIdNotUsable(const nsCString& aSessionId, - InfallibleTArray&& aKeyId) -{ - if (!mIsOpen) { - NS_WARNING("Trying to use a dead GMP decrypter!"); - return false; - } - mCallback->KeyIdNotUsable(aSessionId, aKeyId); + mCallback->KeyStatusChanged(aSessionId, aKeyId, aStatus); return true; } diff --git a/dom/media/gmp/GMPDecryptorParent.h b/dom/media/gmp/GMPDecryptorParent.h index b61e6e87e62e..cb1fb173b2c5 100644 --- a/dom/media/gmp/GMPDecryptorParent.h +++ b/dom/media/gmp/GMPDecryptorParent.h @@ -91,11 +91,9 @@ private: const uint32_t& aSystemCode, const nsCString& aMessage) MOZ_OVERRIDE; - virtual bool RecvKeyIdUsable(const nsCString& aSessionId, - InfallibleTArray&& aKeyId) MOZ_OVERRIDE; - - virtual bool RecvKeyIdNotUsable(const nsCString& aSessionId, - InfallibleTArray&& aKeyId) MOZ_OVERRIDE; + virtual bool RecvKeyStatusChanged(const nsCString& aSessionId, + InfallibleTArray&& aKeyId, + const GMPMediaKeyStatus& aStatus) MOZ_OVERRIDE; virtual bool RecvDecrypted(const uint32_t& aId, const GMPErr& aErr, diff --git a/dom/media/gmp/GMPDecryptorProxy.h b/dom/media/gmp/GMPDecryptorProxy.h index 1e4e2c682d79..b3916e5a3386 100644 --- a/dom/media/gmp/GMPDecryptorProxy.h +++ b/dom/media/gmp/GMPDecryptorProxy.h @@ -44,11 +44,9 @@ public: uint32_t aSystemCode, const nsCString& aMessage) = 0; - virtual void KeyIdUsable(const nsCString& aSessionId, - const nsTArray& aKeyId) = 0; - - virtual void KeyIdNotUsable(const nsCString& aSessionId, - const nsTArray& aKeyId) = 0; + virtual void KeyStatusChanged(const nsCString& aSessionId, + const nsTArray& aKeyId, + GMPMediaKeyStatus aStatus) = 0; virtual void SetCaps(uint64_t aCaps) = 0; diff --git a/dom/media/gmp/GMPMessageUtils.h b/dom/media/gmp/GMPMessageUtils.h index 0b381713fb93..471f928e5e6d 100644 --- a/dom/media/gmp/GMPMessageUtils.h +++ b/dom/media/gmp/GMPMessageUtils.h @@ -60,6 +60,13 @@ struct ParamTraits kGMPMessageInvalid> {}; +template <> +struct ParamTraits +: public ContiguousEnumSerializer +{}; + template <> struct ParamTraits : public ContiguousEnumSerializer& aKeyId) MOZ_OVERRIDE { } - virtual void KeyIdNotUsable(const nsCString& aSessionId, - const nsTArray& aKeyId) MOZ_OVERRIDE {} + virtual void KeyStatusChanged(const nsCString& aSessionId, + const nsTArray& aKeyId, + GMPMediaKeyStatus aStatus) MOZ_OVERRIDE { } virtual void SetCaps(uint64_t aCaps) MOZ_OVERRIDE {} virtual void Decrypted(uint32_t aId, GMPErr aResult, diff --git a/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp b/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp index 4d67aac2ae42..4d86fe121f23 100644 --- a/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp +++ b/media/gmp-clearkey/0.1/ClearKeySessionManager.cpp @@ -167,8 +167,9 @@ ClearKeySessionManager::PersistentSessionDataLoaded(GMPErr aStatus, mDecryptionManager->ExpectKeyId(keyId); mDecryptionManager->InitKey(keyId, key); mKeyIds.insert(key); - mCallback->KeyIdUsable(&aSessionId[0], aSessionId.size(), - &keyId[0], keyId.size()); + mCallback->KeyStatusChanged(&aSessionId[0], aSessionId.size(), + &keyId[0], keyId.size(), + kGMPUsable); } mCallback->ResolveLoadSessionPromise(aPromiseId, true); @@ -203,8 +204,9 @@ ClearKeySessionManager::UpdateSession(uint32_t aPromiseId, for (auto it = keyPairs.begin(); it != keyPairs.end(); it++) { mDecryptionManager->InitKey(it->mKeyId, it->mKey); mKeyIds.insert(it->mKeyId); - mCallback->KeyIdUsable(aSessionId, aSessionIdLength, - &it->mKeyId[0], it->mKeyId.size()); + mCallback->KeyStatusChanged(aSessionId, aSessionIdLength, + &it->mKeyId[0], it->mKeyId.size(), + kGMPUsable); } if (session->Type() != kGMPPersistentSession) { @@ -279,8 +281,9 @@ ClearKeySessionManager::ClearInMemorySessionData(ClearKeySession* aSession) mDecryptionManager->ReleaseKeyId(*it); const string& sessionId = aSession->Id(); - mCallback->KeyIdNotUsable(&sessionId[0], sessionId.size(), - &(*it)[0], it->size()); + mCallback->KeyStatusChanged(&sessionId[0], sessionId.size(), + &(*it)[0], it->size(), + kGMPUnknown); } mSessions.erase(aSession->Id()); diff --git a/media/gmp-clearkey/0.1/clearkey.info b/media/gmp-clearkey/0.1/clearkey.info index 639fe84ee38e..feb0df924311 100644 --- a/media/gmp-clearkey/0.1/clearkey.info +++ b/media/gmp-clearkey/0.1/clearkey.info @@ -1,4 +1,4 @@ Name: clearkey Description: ClearKey decrypt-only GMP plugin Version: 0.1 -APIs: eme-decrypt-v4[org.w3.clearkey] +APIs: eme-decrypt-v5[org.w3.clearkey]