Bug 1293101 - Refactor CDMCaps.cpp to treat keys marked as output-restricted as usable in all cases. r?gerald
This is a follow up from
bug 1289623, as I missed a few cases in that bug.
MozReview-Commit-ID: DM7FtVSZUo3
--- a/dom/media/eme/CDMCaps.cpp
+++ b/dom/media/eme/CDMCaps.cpp
@@ -38,66 +38,73 @@ CDMCaps::AutoLock::AutoLock(CDMCaps& aIn
mData.Lock();
}
CDMCaps::AutoLock::~AutoLock()
{
mData.Unlock();
}
+// Keys with kGMPUsable, kGMPOutputDownscaled, or kGMPOutputRestricted status
+// can be used by the CDM to decrypt or decrypt-and-decode samples.
+static bool
+IsUsableStatus(GMPMediaKeyStatus aStatus)
+{
+ return aStatus == kGMPUsable ||
+ aStatus == kGMPOutputRestricted ||
+ aStatus == kGMPOutputDownscaled;
+}
+
bool
CDMCaps::AutoLock::IsKeyUsable(const CencKeyId& aKeyId)
{
mData.mMonitor.AssertCurrentThreadOwns();
- const auto& keys = mData.mKeyStatuses;
- for (size_t i = 0; i < keys.Length(); i++) {
- if (keys[i].mId != aKeyId) {
- continue;
- }
- if (keys[i].mStatus == kGMPUsable ||
- keys[i].mStatus == kGMPOutputRestricted ||
- keys[i].mStatus == kGMPOutputDownscaled) {
- return true;
+ for (const KeyStatus& keyStatus : mData.mKeyStatuses) {
+ if (keyStatus.mId == aKeyId) {
+ return IsUsableStatus(keyStatus.mStatus);
}
}
return false;
}
bool
CDMCaps::AutoLock::SetKeyStatus(const CencKeyId& aKeyId,
const nsString& aSessionId,
GMPMediaKeyStatus aStatus)
{
mData.mMonitor.AssertCurrentThreadOwns();
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);
}
+ auto index = mData.mKeyStatuses.IndexOf(key);
if (index != mData.mKeyStatuses.NoIndex) {
if (mData.mKeyStatuses[index].mStatus == aStatus) {
+ // No change.
return false;
}
auto oldStatus = mData.mKeyStatuses[index].mStatus;
mData.mKeyStatuses[index].mStatus = aStatus;
- if (oldStatus == kGMPUsable || oldStatus == kGMPOutputDownscaled) {
+ // The old key status was one for which we can decrypt media. We don't
+ // need to do the "notify usable" step below, as it should be impossible
+ // for us to have anything waiting on this key to become usable, since it
+ // was already usable.
+ if (IsUsableStatus(oldStatus)) {
return true;
}
} else {
mData.mKeyStatuses.AppendElement(key);
}
- // Both kGMPUsable and kGMPOutputDownscaled are treated able to decrypt.
- // We don't need to notify when transition happens between kGMPUsable and
- // kGMPOutputDownscaled. Only call NotifyUsable() when we are going from
- // ![kGMPUsable|kGMPOutputDownscaled] to [kGMPUsable|kGMPOutputDownscaled]
- if (aStatus != kGMPUsable && aStatus != kGMPOutputDownscaled) {
+ // Only call NotifyUsable() for a key when we are going from non-usable
+ // to usable state.
+ if (!IsUsableStatus(aStatus)) {
return true;
}
auto& waiters = mData.mWaitForKeys;
size_t i = 0;
while (i < waiters.Length()) {
auto& w = waiters[i];
if (w.mKeyId == aKeyId) {
@@ -119,40 +126,39 @@ CDMCaps::AutoLock::NotifyWhenKeyIdUsable
MOZ_ASSERT(aListener);
mData.mWaitForKeys.AppendElement(WaitForKeys(aKey, aListener));
}
void
CDMCaps::AutoLock::GetKeyStatusesForSession(const nsAString& aSessionId,
nsTArray<KeyStatus>& aOutKeyStatuses)
{
- for (size_t i = 0; i < mData.mKeyStatuses.Length(); i++) {
- const auto& key = mData.mKeyStatuses[i];
- if (key.mSessionId.Equals(aSessionId)) {
- aOutKeyStatuses.AppendElement(key);
+ for (const KeyStatus& keyStatus : mData.mKeyStatuses) {
+ if (keyStatus.mSessionId.Equals(aSessionId)) {
+ aOutKeyStatuses.AppendElement(keyStatus);
}
}
}
void
CDMCaps::AutoLock::GetSessionIdsForKeyId(const CencKeyId& aKeyId,
nsTArray<nsCString>& aOutSessionIds)
{
- for (const auto& keyStatus : mData.mKeyStatuses) {
+ for (const KeyStatus& keyStatus : mData.mKeyStatuses) {
if (keyStatus.mId == aKeyId) {
aOutSessionIds.AppendElement(NS_ConvertUTF16toUTF8(keyStatus.mSessionId));
}
}
}
bool
CDMCaps::AutoLock::RemoveKeysForSession(const nsString& aSessionId)
{
bool changed = false;
nsTArray<KeyStatus> statuses;
GetKeyStatusesForSession(aSessionId, statuses);
- for (const KeyStatus& status : statuses) {
- changed |= SetKeyStatus(status.mId, aSessionId, kGMPUnknown);
+ for (const KeyStatus& keyStatus : statuses) {
+ changed |= SetKeyStatus(keyStatus.mId, aSessionId, kGMPUnknown);
}
return changed;
}
} // namespace mozilla