LCOV - code coverage report
Current view: top level - dom/media/eme - CDMCaps.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 78 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 "mozilla/CDMCaps.h"
       8             : #include "mozilla/EMEUtils.h"
       9             : #include "nsThreadUtils.h"
      10             : #include "SamplesWaitingForKey.h"
      11             : 
      12             : namespace mozilla {
      13             : 
      14           0 : CDMCaps::CDMCaps()
      15           0 :   : mMonitor("CDMCaps")
      16             : {
      17           0 : }
      18             : 
      19           0 : CDMCaps::~CDMCaps()
      20             : {
      21           0 : }
      22             : 
      23             : void
      24           0 : CDMCaps::Lock()
      25             : {
      26           0 :   mMonitor.Lock();
      27           0 : }
      28             : 
      29             : void
      30           0 : CDMCaps::Unlock()
      31             : {
      32           0 :   mMonitor.Unlock();
      33           0 : }
      34             : 
      35           0 : CDMCaps::AutoLock::AutoLock(CDMCaps& aInstance)
      36           0 :   : mData(aInstance)
      37             : {
      38           0 :   mData.Lock();
      39           0 : }
      40             : 
      41           0 : CDMCaps::AutoLock::~AutoLock()
      42             : {
      43           0 :   mData.Unlock();
      44           0 : }
      45             : 
      46             : // Keys with MediaKeyStatus::Usable, MediaKeyStatus::Output_downscaled,
      47             : // or MediaKeyStatus::Output_restricted status can be used by the CDM
      48             : // to decrypt or decrypt-and-decode samples.
      49             : static bool
      50           0 : IsUsableStatus(dom::MediaKeyStatus aStatus)
      51             : {
      52           0 :   return aStatus == dom::MediaKeyStatus::Usable ||
      53           0 :          aStatus == dom::MediaKeyStatus::Output_restricted ||
      54           0 :          aStatus == dom::MediaKeyStatus::Output_downscaled;
      55             : }
      56             : 
      57             : bool
      58           0 : CDMCaps::AutoLock::IsKeyUsable(const CencKeyId& aKeyId)
      59             : {
      60           0 :   mData.mMonitor.AssertCurrentThreadOwns();
      61           0 :   for (const KeyStatus& keyStatus : mData.mKeyStatuses) {
      62           0 :     if (keyStatus.mId == aKeyId) {
      63           0 :       return IsUsableStatus(keyStatus.mStatus);
      64             :     }
      65             :   }
      66           0 :   return false;
      67             : }
      68             : 
      69             : bool
      70           0 : CDMCaps::AutoLock::SetKeyStatus(const CencKeyId& aKeyId,
      71             :                                 const nsString& aSessionId,
      72             :                                 const dom::Optional<dom::MediaKeyStatus>& aStatus)
      73             : {
      74           0 :   mData.mMonitor.AssertCurrentThreadOwns();
      75             : 
      76           0 :   if (!aStatus.WasPassed()) {
      77             :     // Called from ForgetKeyStatus.
      78             :     // Return true if the element is found to notify key changes.
      79           0 :     return mData.mKeyStatuses.RemoveElement(KeyStatus(aKeyId,
      80             :                                                       aSessionId,
      81           0 :                                                       dom::MediaKeyStatus::Internal_error));
      82             :   }
      83             : 
      84           0 :   KeyStatus key(aKeyId, aSessionId, aStatus.Value());
      85           0 :   auto index = mData.mKeyStatuses.IndexOf(key);
      86           0 :   if (index != mData.mKeyStatuses.NoIndex) {
      87           0 :     if (mData.mKeyStatuses[index].mStatus == aStatus.Value()) {
      88             :       // No change.
      89           0 :       return false;
      90             :     }
      91           0 :     auto oldStatus = mData.mKeyStatuses[index].mStatus;
      92           0 :     mData.mKeyStatuses[index].mStatus = aStatus.Value();
      93             :     // The old key status was one for which we can decrypt media. We don't
      94             :     // need to do the "notify usable" step below, as it should be impossible
      95             :     // for us to have anything waiting on this key to become usable, since it
      96             :     // was already usable.
      97           0 :     if (IsUsableStatus(oldStatus)) {
      98           0 :       return true;
      99             :     }
     100             :   } else {
     101           0 :     mData.mKeyStatuses.AppendElement(key);
     102             :   }
     103             : 
     104             :   // Only call NotifyUsable() for a key when we are going from non-usable
     105             :   // to usable state.
     106           0 :   if (!IsUsableStatus(aStatus.Value())) {
     107           0 :     return true;
     108             :   }
     109             : 
     110           0 :   auto& waiters = mData.mWaitForKeys;
     111           0 :   size_t i = 0;
     112           0 :   while (i < waiters.Length()) {
     113           0 :     auto& w = waiters[i];
     114           0 :     if (w.mKeyId == aKeyId) {
     115           0 :       w.mListener->NotifyUsable(aKeyId);
     116           0 :       waiters.RemoveElementAt(i);
     117             :     } else {
     118           0 :       i++;
     119             :     }
     120             :   }
     121           0 :   return true;
     122             : }
     123             : 
     124             : void
     125           0 : CDMCaps::AutoLock::NotifyWhenKeyIdUsable(const CencKeyId& aKey,
     126             :                                          SamplesWaitingForKey* aListener)
     127             : {
     128           0 :   mData.mMonitor.AssertCurrentThreadOwns();
     129           0 :   MOZ_ASSERT(!IsKeyUsable(aKey));
     130           0 :   MOZ_ASSERT(aListener);
     131           0 :   mData.mWaitForKeys.AppendElement(WaitForKeys(aKey, aListener));
     132           0 : }
     133             : 
     134             : void
     135           0 : CDMCaps::AutoLock::GetKeyStatusesForSession(const nsAString& aSessionId,
     136             :                                             nsTArray<KeyStatus>& aOutKeyStatuses)
     137             : {
     138           0 :   for (const KeyStatus& keyStatus : mData.mKeyStatuses) {
     139           0 :     if (keyStatus.mSessionId.Equals(aSessionId)) {
     140           0 :       aOutKeyStatuses.AppendElement(keyStatus);
     141             :     }
     142             :   }
     143           0 : }
     144             : 
     145             : void
     146           0 : CDMCaps::AutoLock::GetSessionIdsForKeyId(const CencKeyId& aKeyId,
     147             :                                          nsTArray<nsCString>& aOutSessionIds)
     148             : {
     149           0 :   for (const KeyStatus& keyStatus : mData.mKeyStatuses) {
     150           0 :     if (keyStatus.mId == aKeyId) {
     151           0 :       aOutSessionIds.AppendElement(NS_ConvertUTF16toUTF8(keyStatus.mSessionId));
     152             :     }
     153             :   }
     154           0 : }
     155             : 
     156             : bool
     157           0 : CDMCaps::AutoLock::RemoveKeysForSession(const nsString& aSessionId)
     158             : {
     159           0 :   bool changed = false;
     160           0 :   nsTArray<KeyStatus> statuses;
     161           0 :   GetKeyStatusesForSession(aSessionId, statuses);
     162           0 :   for (const KeyStatus& status : statuses) {
     163           0 :     changed |= SetKeyStatus(status.mId,
     164             :                             aSessionId,
     165           0 :                             dom::Optional<dom::MediaKeyStatus>());
     166             :   }
     167           0 :   return changed;
     168             : }
     169             : 
     170             : } // namespace mozilla

Generated by: LCOV version 1.13