Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / media / mojo / services / mojo_cdm.cc
blob97feb0586b74c754d8c10d16c8ae5f26e260b039
1 // Copyright 2014 The Chromium Authors. All rights reserved.
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.h"
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "media/base/cdm_context.h"
10 #include "media/base/cdm_key_information.h"
11 #include "media/base/cdm_promise.h"
12 #include "media/mojo/services/media_type_converters.h"
13 #include "mojo/application/public/cpp/connect.h"
14 #include "mojo/application/public/interfaces/service_provider.mojom.h"
15 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_impl.h"
16 #include "url/gurl.h"
18 namespace media {
20 template <typename PromiseType>
21 static void RejectPromise(scoped_ptr<PromiseType> promise,
22 interfaces::CdmPromiseResultPtr result) {
23 promise->reject(static_cast<MediaKeys::Exception>(result->exception),
24 result->system_code, result->error_message);
27 int MojoCdm::next_cdm_id_ = CdmContext::kInvalidCdmId + 1;
29 // static
30 void MojoCdm::Create(
31 const std::string& key_system,
32 const GURL& security_origin,
33 const media::CdmConfig& cdm_config,
34 interfaces::ContentDecryptionModulePtr remote_cdm,
35 const media::SessionMessageCB& session_message_cb,
36 const media::SessionClosedCB& session_closed_cb,
37 const media::LegacySessionErrorCB& legacy_session_error_cb,
38 const media::SessionKeysChangeCB& session_keys_change_cb,
39 const media::SessionExpirationUpdateCB& session_expiration_update_cb,
40 const media::CdmCreatedCB& cdm_created_cb) {
41 scoped_ptr<MojoCdm> mojo_cdm(
42 new MojoCdm(remote_cdm.Pass(), session_message_cb, session_closed_cb,
43 legacy_session_error_cb, session_keys_change_cb,
44 session_expiration_update_cb));
46 // |mojo_cdm|'s ownership will be passed to the promise. Get a raw pointer
47 // here in order to call Initialize().
48 MojoCdm* mojo_cdm_ptr = mojo_cdm.get();
49 scoped_ptr<CdmInitializedPromise> promise(
50 new CdmInitializedPromise(cdm_created_cb, mojo_cdm.Pass()));
51 mojo_cdm_ptr->InitializeCdm(key_system, security_origin, cdm_config,
52 promise.Pass());
55 MojoCdm::MojoCdm(interfaces::ContentDecryptionModulePtr remote_cdm,
56 const SessionMessageCB& session_message_cb,
57 const SessionClosedCB& session_closed_cb,
58 const LegacySessionErrorCB& legacy_session_error_cb,
59 const SessionKeysChangeCB& session_keys_change_cb,
60 const SessionExpirationUpdateCB& session_expiration_update_cb)
61 : remote_cdm_(remote_cdm.Pass()),
62 binding_(this),
63 // Safe because MojoCdm is always created on one thread.
64 cdm_id_(next_cdm_id_++),
65 session_message_cb_(session_message_cb),
66 session_closed_cb_(session_closed_cb),
67 legacy_session_error_cb_(legacy_session_error_cb),
68 session_keys_change_cb_(session_keys_change_cb),
69 session_expiration_update_cb_(session_expiration_update_cb),
70 weak_factory_(this) {
71 DVLOG(1) << __FUNCTION__;
72 DCHECK_NE(CdmContext::kInvalidCdmId, cdm_id_);
73 DCHECK(!session_message_cb_.is_null());
74 DCHECK(!session_closed_cb_.is_null());
75 DCHECK(!legacy_session_error_cb_.is_null());
76 DCHECK(!session_keys_change_cb_.is_null());
77 DCHECK(!session_expiration_update_cb_.is_null());
79 interfaces::ContentDecryptionModuleClientPtr client_ptr;
80 binding_.Bind(GetProxy(&client_ptr));
81 remote_cdm_->SetClient(client_ptr.Pass());
84 MojoCdm::~MojoCdm() {
85 DVLOG(1) << __FUNCTION__;
88 void MojoCdm::InitializeCdm(const std::string& key_system,
89 const GURL& security_origin,
90 const media::CdmConfig& cdm_config,
91 scoped_ptr<CdmInitializedPromise> promise) {
92 DVLOG(1) << __FUNCTION__ << ": " << key_system;
93 remote_cdm_->Initialize(
94 key_system, security_origin.spec(),
95 interfaces::CdmConfig::From(cdm_config), cdm_id_,
96 base::Bind(&MojoCdm::OnPromiseResult<>, weak_factory_.GetWeakPtr(),
97 base::Passed(&promise)));
100 void MojoCdm::SetServerCertificate(const std::vector<uint8_t>& certificate,
101 scoped_ptr<SimpleCdmPromise> promise) {
102 DVLOG(2) << __FUNCTION__;
103 remote_cdm_->SetServerCertificate(
104 mojo::Array<uint8_t>::From(certificate),
105 base::Bind(&MojoCdm::OnPromiseResult<>, weak_factory_.GetWeakPtr(),
106 base::Passed(&promise)));
109 void MojoCdm::CreateSessionAndGenerateRequest(
110 SessionType session_type,
111 EmeInitDataType init_data_type,
112 const std::vector<uint8_t>& init_data,
113 scoped_ptr<NewSessionCdmPromise> promise) {
114 DVLOG(2) << __FUNCTION__;
115 remote_cdm_->CreateSessionAndGenerateRequest(
116 static_cast<interfaces::ContentDecryptionModule::SessionType>(
117 session_type),
118 static_cast<interfaces::ContentDecryptionModule::InitDataType>(
119 init_data_type),
120 mojo::Array<uint8_t>::From(init_data),
121 base::Bind(&MojoCdm::OnPromiseResult<std::string>,
122 weak_factory_.GetWeakPtr(), base::Passed(&promise)));
125 void MojoCdm::LoadSession(SessionType session_type,
126 const std::string& session_id,
127 scoped_ptr<NewSessionCdmPromise> promise) {
128 DVLOG(2) << __FUNCTION__;
129 remote_cdm_->LoadSession(
130 static_cast<interfaces::ContentDecryptionModule::SessionType>(
131 session_type),
132 session_id,
133 base::Bind(&MojoCdm::OnPromiseResult<std::string>,
134 weak_factory_.GetWeakPtr(), base::Passed(&promise)));
137 void MojoCdm::UpdateSession(const std::string& session_id,
138 const std::vector<uint8_t>& response,
139 scoped_ptr<SimpleCdmPromise> promise) {
140 DVLOG(2) << __FUNCTION__;
141 remote_cdm_->UpdateSession(
142 session_id, mojo::Array<uint8_t>::From(response),
143 base::Bind(&MojoCdm::OnPromiseResult<>, weak_factory_.GetWeakPtr(),
144 base::Passed(&promise)));
147 void MojoCdm::CloseSession(const std::string& session_id,
148 scoped_ptr<SimpleCdmPromise> promise) {
149 DVLOG(2) << __FUNCTION__;
150 remote_cdm_->CloseSession(session_id, base::Bind(&MojoCdm::OnPromiseResult<>,
151 weak_factory_.GetWeakPtr(),
152 base::Passed(&promise)));
155 void MojoCdm::RemoveSession(const std::string& session_id,
156 scoped_ptr<SimpleCdmPromise> promise) {
157 DVLOG(2) << __FUNCTION__;
158 remote_cdm_->RemoveSession(session_id, base::Bind(&MojoCdm::OnPromiseResult<>,
159 weak_factory_.GetWeakPtr(),
160 base::Passed(&promise)));
163 CdmContext* MojoCdm::GetCdmContext() {
164 DVLOG(2) << __FUNCTION__;
165 return this;
168 media::Decryptor* MojoCdm::GetDecryptor() {
169 NOTIMPLEMENTED();
170 return nullptr;
173 int MojoCdm::GetCdmId() const {
174 DCHECK_NE(CdmContext::kInvalidCdmId, cdm_id_);
175 return cdm_id_;
178 void MojoCdm::OnSessionMessage(const mojo::String& session_id,
179 interfaces::CdmMessageType message_type,
180 mojo::Array<uint8_t> message,
181 const mojo::String& legacy_destination_url) {
182 DVLOG(2) << __FUNCTION__;
183 GURL verified_gurl = GURL(legacy_destination_url);
184 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) {
185 DLOG(WARNING) << "SessionMessage destination_url is invalid : "
186 << verified_gurl.possibly_invalid_spec();
187 verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url.
190 session_message_cb_.Run(session_id,
191 static_cast<MediaKeys::MessageType>(message_type),
192 message.storage(), verified_gurl);
195 void MojoCdm::OnSessionClosed(const mojo::String& session_id) {
196 DVLOG(2) << __FUNCTION__;
197 session_closed_cb_.Run(session_id);
200 void MojoCdm::OnLegacySessionError(const mojo::String& session_id,
201 interfaces::CdmException exception,
202 uint32_t system_code,
203 const mojo::String& error_message) {
204 DVLOG(2) << __FUNCTION__;
205 legacy_session_error_cb_.Run(session_id,
206 static_cast<MediaKeys::Exception>(exception),
207 system_code, error_message);
210 void MojoCdm::OnSessionKeysChange(
211 const mojo::String& session_id,
212 bool has_additional_usable_key,
213 mojo::Array<interfaces::CdmKeyInformationPtr> keys_info) {
214 DVLOG(2) << __FUNCTION__;
215 media::CdmKeysInfo key_data;
216 key_data.reserve(keys_info.size());
217 for (size_t i = 0; i < keys_info.size(); ++i) {
218 key_data.push_back(
219 keys_info[i].To<scoped_ptr<media::CdmKeyInformation>>().release());
221 session_keys_change_cb_.Run(session_id, has_additional_usable_key,
222 key_data.Pass());
225 void MojoCdm::OnSessionExpirationUpdate(const mojo::String& session_id,
226 double new_expiry_time_sec) {
227 DVLOG(2) << __FUNCTION__;
228 session_expiration_update_cb_.Run(
229 session_id, base::Time::FromDoubleT(new_expiry_time_sec));
232 } // namespace media