1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5  * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "SamplesWaitingForKey.h"
8 #include "MediaData.h"
9 #include "MediaEventSource.h"
10 #include "mozilla/CDMCaps.h"
11 #include "mozilla/CDMProxy.h"
12 #include "mozilla/TaskQueue.h"
13 
14 namespace mozilla {
15 
SamplesWaitingForKey(CDMProxy * aProxy,TrackInfo::TrackType aType,MediaEventProducer<TrackInfo::TrackType> * aOnWaitingForKey)16 SamplesWaitingForKey::SamplesWaitingForKey(
17     CDMProxy* aProxy, TrackInfo::TrackType aType,
18     MediaEventProducer<TrackInfo::TrackType>* aOnWaitingForKey)
19     : mMutex("SamplesWaitingForKey"),
20       mProxy(aProxy),
21       mType(aType),
22       mOnWaitingForKeyEvent(aOnWaitingForKey) {}
23 
~SamplesWaitingForKey()24 SamplesWaitingForKey::~SamplesWaitingForKey() { Flush(); }
25 
26 RefPtr<SamplesWaitingForKey::WaitForKeyPromise>
WaitIfKeyNotUsable(MediaRawData * aSample)27 SamplesWaitingForKey::WaitIfKeyNotUsable(MediaRawData* aSample) {
28   if (!aSample || !aSample->mCrypto.mValid || !mProxy) {
29     return WaitForKeyPromise::CreateAndResolve(aSample, __func__);
30   }
31   auto caps = mProxy->Capabilites().Lock();
32   const auto& keyid = aSample->mCrypto.mKeyId;
33   if (caps->IsKeyUsable(keyid)) {
34     return WaitForKeyPromise::CreateAndResolve(aSample, __func__);
35   }
36   SampleEntry entry;
37   entry.mSample = aSample;
38   RefPtr<WaitForKeyPromise> p = entry.mPromise.Ensure(__func__);
39   {
40     MutexAutoLock lock(mMutex);
41     mSamples.AppendElement(Move(entry));
42   }
43   if (mOnWaitingForKeyEvent) {
44     mOnWaitingForKeyEvent->Notify(mType);
45   }
46   caps->NotifyWhenKeyIdUsable(aSample->mCrypto.mKeyId, this);
47   return p;
48 }
49 
NotifyUsable(const CencKeyId & aKeyId)50 void SamplesWaitingForKey::NotifyUsable(const CencKeyId& aKeyId) {
51   MutexAutoLock lock(mMutex);
52   size_t i = 0;
53   while (i < mSamples.Length()) {
54     auto& entry = mSamples[i];
55     if (aKeyId == entry.mSample->mCrypto.mKeyId) {
56       entry.mPromise.Resolve(entry.mSample, __func__);
57       mSamples.RemoveElementAt(i);
58     } else {
59       i++;
60     }
61   }
62 }
63 
Flush()64 void SamplesWaitingForKey::Flush() {
65   MutexAutoLock lock(mMutex);
66   for (auto& sample : mSamples) {
67     sample.mPromise.Reject(true, __func__);
68   }
69   mSamples.Clear();
70 }
71 
72 }  // namespace mozilla
73