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