tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WMFCDMImpl.cpp (5204B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim:set ts=2 sw=2 sts=2 et cindent: */
      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 "WMFCDMImpl.h"
      8 
      9 #include "mozilla/AppShutdown.h"
     10 #include "mozilla/ClearOnShutdown.h"
     11 #include "mozilla/ScopeExit.h"
     12 #include "mozilla/dom/KeySystemNames.h"
     13 #include "mozilla/dom/MediaKeySession.h"
     14 
     15 namespace mozilla {
     16 
     17 RefPtr<WMFCDMImpl::InitPromise> WMFCDMImpl::Init(
     18    const WMFCDMImpl::InitParams& aParams) {
     19  if (!mCDM) {
     20    mCDM = MakeRefPtr<MFCDMChild>(mKeySystem);
     21    mCDM->EnsureRemote();
     22  }
     23  RefPtr<WMFCDMImpl> self = this;
     24  mCDM->Init(aParams.mOrigin, aParams.mInitDataTypes,
     25             aParams.mPersistentStateRequired
     26                 ? KeySystemConfig::Requirement::Required
     27                 : KeySystemConfig::Requirement::Optional,
     28             aParams.mDistinctiveIdentifierRequired
     29                 ? KeySystemConfig::Requirement::Required
     30                 : KeySystemConfig::Requirement::Optional,
     31             aParams.mAudioCapabilities, aParams.mVideoCapabilities,
     32             aParams.mProxyCallback)
     33      ->Then(
     34          mCDM->ManagerThread(), __func__,
     35          [self, this](const MFCDMInitIPDL& init) {
     36            mInitPromiseHolder.ResolveIfExists(true, __func__);
     37          },
     38          [self, this](const nsresult rv) {
     39            mInitPromiseHolder.RejectIfExists(rv, __func__);
     40          });
     41  return mInitPromiseHolder.Ensure(__func__);
     42 }
     43 
     44 RefPtr<KeySystemConfig::SupportedConfigsPromise>
     45 WMFCDMCapabilites::GetCapabilities(
     46    const nsTArray<KeySystemConfigRequest>& aRequests) {
     47  MOZ_ASSERT(NS_IsMainThread());
     48  if (AppShutdown::IsInOrBeyond(ShutdownPhase::AppShutdownConfirmed)) {
     49    return SupportedConfigsPromise::CreateAndReject(false, __func__);
     50  }
     51 
     52  if (!mCapabilitiesPromiseHolder.IsEmpty()) {
     53    return mCapabilitiesPromiseHolder.Ensure(__func__);
     54  }
     55 
     56  using CapabilitiesPromise = MFCDMChild::CapabilitiesPromise;
     57  nsTArray<RefPtr<CapabilitiesPromise>> promises;
     58  for (const auto& request : aRequests) {
     59    RefPtr<MFCDMChild> cdm = new MFCDMChild(request.mKeySystem);
     60    cdm->EnsureRemote();
     61    promises.AppendElement(cdm->GetCapabilities(MFCDMCapabilitiesRequest{
     62        nsString{request.mKeySystem},
     63        request.mDecryption == KeySystemConfig::DecryptionInfo::Hardware,
     64        request.mIsPrivateBrowsing}));
     65    mCDMs.AppendElement(std::move(cdm));
     66  }
     67 
     68  CapabilitiesPromise::AllSettled(GetCurrentSerialEventTarget(), promises)
     69      ->Then(
     70          GetMainThreadSerialEventTarget(), __func__,
     71          [self = RefPtr<WMFCDMCapabilites>(this), this](
     72              CapabilitiesPromise::AllSettledPromiseType::ResolveOrRejectValue&&
     73                  aResult) {
     74            mCapabilitiesPromisesRequest.Complete();
     75 
     76            // Reset cdm
     77            auto exit = MakeScopeExit([&] {
     78              for (auto& cdm : mCDMs) {
     79                cdm->Shutdown();
     80              }
     81              mCDMs.Clear();
     82            });
     83 
     84            nsTArray<KeySystemConfig> outConfigs;
     85            for (const auto& promiseRv : aResult.ResolveValue()) {
     86              if (promiseRv.IsReject()) {
     87                continue;
     88              }
     89              const MFCDMCapabilitiesIPDL& capabilities =
     90                  promiseRv.ResolveValue();
     91              EME_LOG("capabilities: keySystem=%s (hw-secure=%d)",
     92                      NS_ConvertUTF16toUTF8(capabilities.keySystem()).get(),
     93                      capabilities.isHardwareDecryption());
     94              for (const auto& v : capabilities.videoCapabilities()) {
     95                for (const auto& scheme : v.encryptionSchemes()) {
     96                  EME_LOG("capabilities: video=%s, scheme=%s",
     97                          NS_ConvertUTF16toUTF8(v.contentType()).get(),
     98                          EnumValueToString(scheme));
     99                }
    100              }
    101              for (const auto& a : capabilities.audioCapabilities()) {
    102                for (const auto& scheme : a.encryptionSchemes()) {
    103                  EME_LOG("capabilities: audio=%s, scheme=%s",
    104                          NS_ConvertUTF16toUTF8(a.contentType()).get(),
    105                          EnumValueToString(scheme));
    106                }
    107              }
    108              KeySystemConfig* config = outConfigs.AppendElement();
    109              MFCDMCapabilitiesIPDLToKeySystemConfig(capabilities, *config);
    110            }
    111            if (outConfigs.IsEmpty()) {
    112              EME_LOG(
    113                  "Failed on getting capabilities from all settled promise");
    114              mCapabilitiesPromiseHolder.Reject(false, __func__);
    115              return;
    116            }
    117            mCapabilitiesPromiseHolder.Resolve(std::move(outConfigs), __func__);
    118          })
    119      ->Track(mCapabilitiesPromisesRequest);
    120 
    121  return mCapabilitiesPromiseHolder.Ensure(__func__);
    122 }
    123 
    124 WMFCDMCapabilites::~WMFCDMCapabilites() {
    125  mCapabilitiesPromisesRequest.DisconnectIfExists();
    126  mCapabilitiesPromiseHolder.RejectIfExists(false, __func__);
    127  for (auto& cdm : mCDMs) {
    128    cdm->Shutdown();
    129  }
    130 }
    131 
    132 }  // namespace mozilla