1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "media/mojo/services/mojo_cdm_helper.h"
9 #include "base/containers/cxx20_erase.h"
10 #include "build/build_config.h"
11 #include "media/base/cdm_context.h"
12 #include "media/cdm/cdm_helpers.h"
13 #include "media/mojo/services/mojo_cdm_allocator.h"
14 #include "media/mojo/services/mojo_cdm_file_io.h"
15 #include "mojo/public/cpp/bindings/callback_helpers.h"
16 #include "mojo/public/cpp/bindings/pending_remote.h"
20 MojoCdmHelper::MojoCdmHelper(mojom::FrameInterfaceFactory* frame_interfaces)
21 : frame_interfaces_(frame_interfaces) {}
23 MojoCdmHelper::~MojoCdmHelper() = default;
25 void MojoCdmHelper::SetFileReadCB(FileReadCB file_read_cb) {
26 file_read_cb_ = std::move(file_read_cb);
29 cdm::FileIO* MojoCdmHelper::CreateCdmFileIO(cdm::FileIOClient* client) {
30 mojo::Remote<mojom::CdmStorage> cdm_storage;
31 frame_interfaces_->CreateCdmStorage(cdm_storage.BindNewPipeAndPassReceiver());
32 // No reset_on_disconnect() since when document is destroyed the CDM should be
35 auto mojo_cdm_file_io =
36 std::make_unique<MojoCdmFileIO>(this, client, std::move(cdm_storage));
38 cdm::FileIO* cdm_file_io = mojo_cdm_file_io.get();
39 DVLOG(3) << __func__ << ": cdm_file_io = " << cdm_file_io;
41 cdm_file_io_set_.push_back(std::move(mojo_cdm_file_io));
45 url::Origin MojoCdmHelper::GetCdmOrigin() {
46 url::Origin cdm_origin;
47 // Since the CDM is created asynchronously, by the time this function is
48 // called, the RenderFrameHost in the browser process may already be gone.
49 // It's safe to ignore the error since the origin is used for crash reporting.
50 std::ignore = frame_interfaces_->GetCdmOrigin(&cdm_origin);
55 void MojoCdmHelper::GetMediaFoundationCdmData(
56 GetMediaFoundationCdmDataCB callback) {
57 ConnectToCdmDocumentService();
58 cdm_document_service_->GetMediaFoundationCdmData(std::move(callback));
61 void MojoCdmHelper::SetCdmClientToken(
62 const std::vector<uint8_t>& client_token) {
63 ConnectToCdmDocumentService();
64 cdm_document_service_->SetCdmClientToken(client_token);
67 void MojoCdmHelper::OnCdmEvent(CdmEvent event, HRESULT hresult) {
68 ConnectToCdmDocumentService();
69 cdm_document_service_->OnCdmEvent(event, hresult);
71 #endif // BUILDFLAG(IS_WIN)
73 cdm::Buffer* MojoCdmHelper::CreateCdmBuffer(size_t capacity) {
74 return GetAllocator()->CreateCdmBuffer(capacity);
77 std::unique_ptr<VideoFrameImpl> MojoCdmHelper::CreateCdmVideoFrame() {
78 return GetAllocator()->CreateCdmVideoFrame();
81 void MojoCdmHelper::QueryStatus(QueryStatusCB callback) {
82 QueryStatusCB scoped_callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(
83 std::move(callback), false, 0, 0);
84 ConnectToOutputProtection();
85 output_protection_->QueryStatus(std::move(scoped_callback));
88 void MojoCdmHelper::EnableProtection(uint32_t desired_protection_mask,
89 EnableProtectionCB callback) {
90 EnableProtectionCB scoped_callback =
91 mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), false);
92 ConnectToOutputProtection();
93 output_protection_->EnableProtection(desired_protection_mask,
94 std::move(scoped_callback));
97 void MojoCdmHelper::ChallengePlatform(const std::string& service_id,
98 const std::string& challenge,
99 ChallengePlatformCB callback) {
100 ChallengePlatformCB scoped_callback =
101 mojo::WrapCallbackWithDefaultInvokeIfNotRun(std::move(callback), false,
103 ConnectToCdmDocumentService();
104 cdm_document_service_->ChallengePlatform(service_id, challenge,
105 std::move(scoped_callback));
108 void MojoCdmHelper::GetStorageId(uint32_t version, StorageIdCB callback) {
109 StorageIdCB scoped_callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(
110 std::move(callback), version, std::vector<uint8_t>());
111 ConnectToCdmDocumentService();
112 cdm_document_service_->GetStorageId(version, std::move(scoped_callback));
115 void MojoCdmHelper::CloseCdmFileIO(MojoCdmFileIO* cdm_file_io) {
116 DVLOG(3) << __func__ << ": cdm_file_io = " << cdm_file_io;
117 base::EraseIf(cdm_file_io_set_,
118 [cdm_file_io](const std::unique_ptr<MojoCdmFileIO>& ptr) {
119 return ptr.get() == cdm_file_io;
123 void MojoCdmHelper::ReportFileReadSize(int file_size_bytes) {
124 DVLOG(3) << __func__ << ": file_size_bytes = " << file_size_bytes;
126 file_read_cb_.Run(file_size_bytes);
129 void MojoCdmHelper::ConnectToOutputProtection() {
130 if (!output_protection_) {
131 DVLOG(2) << "Connect to mojom::OutputProtection";
132 frame_interfaces_->BindEmbedderReceiver(
133 output_protection_.BindNewPipeAndPassReceiver());
134 // No reset_on_disconnect() since MediaInterfaceProxy should be destroyed
135 // when document is destroyed, which will destroy MojoCdmHelper as well.
139 void MojoCdmHelper::ConnectToCdmDocumentService() {
140 if (!cdm_document_service_) {
141 DVLOG(2) << "Connect to mojom::CdmDocumentService";
142 frame_interfaces_->BindEmbedderReceiver(
143 cdm_document_service_.BindNewPipeAndPassReceiver());
144 // No reset_on_disconnect() since MediaInterfaceProxy should be destroyed
145 // when document is destroyed, which will destroy MojoCdmHelper as well.
149 CdmAllocator* MojoCdmHelper::GetAllocator() {
151 allocator_ = std::make_unique<MojoCdmAllocator>();
152 return allocator_.get();