OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "media/mojo/services/mojo_cdm.h" | 5 #include "media/mojo/services/mojo_cdm.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/bind_helpers.h" | 12 #include "base/bind_helpers.h" |
13 #include "base/location.h" | 13 #include "base/location.h" |
14 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
15 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
16 #include "media/base/cdm_context.h" | 16 #include "media/base/cdm_context.h" |
17 #include "media/base/cdm_key_information.h" | 17 #include "media/base/cdm_key_information.h" |
18 #include "media/base/cdm_promise.h" | 18 #include "media/base/cdm_promise.h" |
19 #include "media/mojo/common/media_type_converters.h" | 19 #include "media/mojo/common/media_type_converters.h" |
20 #include "media/mojo/interfaces/decryptor.mojom.h" | 20 #include "media/mojo/interfaces/decryptor.mojom.h" |
21 #include "media/mojo/services/mojo_decryptor.h" | 21 #include "media/mojo/services/mojo_decryptor.h" |
22 #include "services/shell/public/cpp/connect.h" | 22 #include "services/shell/public/cpp/connect.h" |
23 #include "services/shell/public/interfaces/interface_provider.mojom.h" | 23 #include "services/shell/public/interfaces/interface_provider.mojom.h" |
24 #include "url/gurl.h" | 24 #include "url/gurl.h" |
25 | 25 |
26 namespace media { | 26 namespace media { |
27 | 27 |
28 template <typename PromiseType> | 28 template <typename PromiseType> |
29 static void RejectPromise(std::unique_ptr<PromiseType> promise, | 29 static void RejectPromise(std::unique_ptr<PromiseType> promise, |
30 interfaces::CdmPromiseResultPtr result) { | 30 mojom::CdmPromiseResultPtr result) { |
31 promise->reject(static_cast<MediaKeys::Exception>(result->exception), | 31 promise->reject(static_cast<MediaKeys::Exception>(result->exception), |
32 result->system_code, result->error_message); | 32 result->system_code, result->error_message); |
33 } | 33 } |
34 | 34 |
35 // static | 35 // static |
36 void MojoCdm::Create( | 36 void MojoCdm::Create( |
37 const std::string& key_system, | 37 const std::string& key_system, |
38 const GURL& security_origin, | 38 const GURL& security_origin, |
39 const media::CdmConfig& cdm_config, | 39 const media::CdmConfig& cdm_config, |
40 interfaces::ContentDecryptionModulePtr remote_cdm, | 40 mojom::ContentDecryptionModulePtr remote_cdm, |
41 const media::SessionMessageCB& session_message_cb, | 41 const media::SessionMessageCB& session_message_cb, |
42 const media::SessionClosedCB& session_closed_cb, | 42 const media::SessionClosedCB& session_closed_cb, |
43 const media::LegacySessionErrorCB& legacy_session_error_cb, | 43 const media::LegacySessionErrorCB& legacy_session_error_cb, |
44 const media::SessionKeysChangeCB& session_keys_change_cb, | 44 const media::SessionKeysChangeCB& session_keys_change_cb, |
45 const media::SessionExpirationUpdateCB& session_expiration_update_cb, | 45 const media::SessionExpirationUpdateCB& session_expiration_update_cb, |
46 const media::CdmCreatedCB& cdm_created_cb) { | 46 const media::CdmCreatedCB& cdm_created_cb) { |
47 scoped_refptr<MojoCdm> mojo_cdm( | 47 scoped_refptr<MojoCdm> mojo_cdm( |
48 new MojoCdm(std::move(remote_cdm), session_message_cb, session_closed_cb, | 48 new MojoCdm(std::move(remote_cdm), session_message_cb, session_closed_cb, |
49 legacy_session_error_cb, session_keys_change_cb, | 49 legacy_session_error_cb, session_keys_change_cb, |
50 session_expiration_update_cb)); | 50 session_expiration_update_cb)); |
51 | 51 |
52 // |mojo_cdm| ownership is passed to the promise. | 52 // |mojo_cdm| ownership is passed to the promise. |
53 std::unique_ptr<CdmInitializedPromise> promise( | 53 std::unique_ptr<CdmInitializedPromise> promise( |
54 new CdmInitializedPromise(cdm_created_cb, mojo_cdm)); | 54 new CdmInitializedPromise(cdm_created_cb, mojo_cdm)); |
55 | 55 |
56 mojo_cdm->InitializeCdm(key_system, security_origin, cdm_config, | 56 mojo_cdm->InitializeCdm(key_system, security_origin, cdm_config, |
57 std::move(promise)); | 57 std::move(promise)); |
58 } | 58 } |
59 | 59 |
60 MojoCdm::MojoCdm(interfaces::ContentDecryptionModulePtr remote_cdm, | 60 MojoCdm::MojoCdm(mojom::ContentDecryptionModulePtr remote_cdm, |
61 const SessionMessageCB& session_message_cb, | 61 const SessionMessageCB& session_message_cb, |
62 const SessionClosedCB& session_closed_cb, | 62 const SessionClosedCB& session_closed_cb, |
63 const LegacySessionErrorCB& legacy_session_error_cb, | 63 const LegacySessionErrorCB& legacy_session_error_cb, |
64 const SessionKeysChangeCB& session_keys_change_cb, | 64 const SessionKeysChangeCB& session_keys_change_cb, |
65 const SessionExpirationUpdateCB& session_expiration_update_cb) | 65 const SessionExpirationUpdateCB& session_expiration_update_cb) |
66 : remote_cdm_(std::move(remote_cdm)), | 66 : remote_cdm_(std::move(remote_cdm)), |
67 binding_(this), | 67 binding_(this), |
68 cdm_id_(CdmContext::kInvalidCdmId), | 68 cdm_id_(CdmContext::kInvalidCdmId), |
69 session_message_cb_(session_message_cb), | 69 session_message_cb_(session_message_cb), |
70 session_closed_cb_(session_closed_cb), | 70 session_closed_cb_(session_closed_cb), |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
115 return; | 115 return; |
116 } | 116 } |
117 | 117 |
118 // Otherwise, set an error handler to catch the connection error. | 118 // Otherwise, set an error handler to catch the connection error. |
119 remote_cdm_.set_connection_error_handler( | 119 remote_cdm_.set_connection_error_handler( |
120 base::Bind(&MojoCdm::OnConnectionError, base::Unretained(this))); | 120 base::Bind(&MojoCdm::OnConnectionError, base::Unretained(this))); |
121 | 121 |
122 pending_init_promise_ = std::move(promise); | 122 pending_init_promise_ = std::move(promise); |
123 | 123 |
124 remote_cdm_->Initialize( | 124 remote_cdm_->Initialize( |
125 key_system, security_origin.spec(), | 125 key_system, security_origin.spec(), mojom::CdmConfig::From(cdm_config), |
126 interfaces::CdmConfig::From(cdm_config), | |
127 base::Bind(&MojoCdm::OnCdmInitialized, base::Unretained(this))); | 126 base::Bind(&MojoCdm::OnCdmInitialized, base::Unretained(this))); |
128 } | 127 } |
129 | 128 |
130 void MojoCdm::OnConnectionError() { | 129 void MojoCdm::OnConnectionError() { |
131 LOG(ERROR) << "Remote CDM connection error."; | 130 LOG(ERROR) << "Remote CDM connection error."; |
132 DCHECK(thread_checker_.CalledOnValidThread()); | 131 DCHECK(thread_checker_.CalledOnValidThread()); |
133 | 132 |
134 // We only handle initial connection error. | 133 // We only handle initial connection error. |
135 if (!pending_init_promise_) | 134 if (!pending_init_promise_) |
136 return; | 135 return; |
(...skipping 16 matching lines...) Expand all Loading... |
153 | 152 |
154 void MojoCdm::CreateSessionAndGenerateRequest( | 153 void MojoCdm::CreateSessionAndGenerateRequest( |
155 SessionType session_type, | 154 SessionType session_type, |
156 EmeInitDataType init_data_type, | 155 EmeInitDataType init_data_type, |
157 const std::vector<uint8_t>& init_data, | 156 const std::vector<uint8_t>& init_data, |
158 std::unique_ptr<NewSessionCdmPromise> promise) { | 157 std::unique_ptr<NewSessionCdmPromise> promise) { |
159 DVLOG(2) << __FUNCTION__; | 158 DVLOG(2) << __FUNCTION__; |
160 DCHECK(thread_checker_.CalledOnValidThread()); | 159 DCHECK(thread_checker_.CalledOnValidThread()); |
161 | 160 |
162 remote_cdm_->CreateSessionAndGenerateRequest( | 161 remote_cdm_->CreateSessionAndGenerateRequest( |
163 static_cast<interfaces::ContentDecryptionModule::SessionType>( | 162 static_cast<mojom::ContentDecryptionModule::SessionType>(session_type), |
164 session_type), | 163 static_cast<mojom::ContentDecryptionModule::InitDataType>(init_data_type), |
165 static_cast<interfaces::ContentDecryptionModule::InitDataType>( | |
166 init_data_type), | |
167 mojo::Array<uint8_t>::From(init_data), | 164 mojo::Array<uint8_t>::From(init_data), |
168 base::Bind(&MojoCdm::OnPromiseResult<std::string>, base::Unretained(this), | 165 base::Bind(&MojoCdm::OnPromiseResult<std::string>, base::Unretained(this), |
169 base::Passed(&promise))); | 166 base::Passed(&promise))); |
170 } | 167 } |
171 | 168 |
172 void MojoCdm::LoadSession(SessionType session_type, | 169 void MojoCdm::LoadSession(SessionType session_type, |
173 const std::string& session_id, | 170 const std::string& session_id, |
174 std::unique_ptr<NewSessionCdmPromise> promise) { | 171 std::unique_ptr<NewSessionCdmPromise> promise) { |
175 DVLOG(2) << __FUNCTION__; | 172 DVLOG(2) << __FUNCTION__; |
176 DCHECK(thread_checker_.CalledOnValidThread()); | 173 DCHECK(thread_checker_.CalledOnValidThread()); |
177 | 174 |
178 remote_cdm_->LoadSession( | 175 remote_cdm_->LoadSession( |
179 static_cast<interfaces::ContentDecryptionModule::SessionType>( | 176 static_cast<mojom::ContentDecryptionModule::SessionType>(session_type), |
180 session_type), | |
181 session_id, base::Bind(&MojoCdm::OnPromiseResult<std::string>, | 177 session_id, base::Bind(&MojoCdm::OnPromiseResult<std::string>, |
182 base::Unretained(this), base::Passed(&promise))); | 178 base::Unretained(this), base::Passed(&promise))); |
183 } | 179 } |
184 | 180 |
185 void MojoCdm::UpdateSession(const std::string& session_id, | 181 void MojoCdm::UpdateSession(const std::string& session_id, |
186 const std::vector<uint8_t>& response, | 182 const std::vector<uint8_t>& response, |
187 std::unique_ptr<SimpleCdmPromise> promise) { | 183 std::unique_ptr<SimpleCdmPromise> promise) { |
188 DVLOG(2) << __FUNCTION__; | 184 DVLOG(2) << __FUNCTION__; |
189 DCHECK(thread_checker_.CalledOnValidThread()); | 185 DCHECK(thread_checker_.CalledOnValidThread()); |
190 | 186 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 } | 233 } |
238 | 234 |
239 int MojoCdm::GetCdmId() const { | 235 int MojoCdm::GetCdmId() const { |
240 base::AutoLock auto_lock(lock_); | 236 base::AutoLock auto_lock(lock_); |
241 // Can be called on a different thread. | 237 // Can be called on a different thread. |
242 DCHECK_NE(CdmContext::kInvalidCdmId, cdm_id_); | 238 DCHECK_NE(CdmContext::kInvalidCdmId, cdm_id_); |
243 return cdm_id_; | 239 return cdm_id_; |
244 } | 240 } |
245 | 241 |
246 void MojoCdm::OnSessionMessage(const mojo::String& session_id, | 242 void MojoCdm::OnSessionMessage(const mojo::String& session_id, |
247 interfaces::CdmMessageType message_type, | 243 mojom::CdmMessageType message_type, |
248 mojo::Array<uint8_t> message, | 244 mojo::Array<uint8_t> message, |
249 const mojo::String& legacy_destination_url) { | 245 const mojo::String& legacy_destination_url) { |
250 DVLOG(2) << __FUNCTION__; | 246 DVLOG(2) << __FUNCTION__; |
251 DCHECK(thread_checker_.CalledOnValidThread()); | 247 DCHECK(thread_checker_.CalledOnValidThread()); |
252 | 248 |
253 GURL verified_gurl = GURL(legacy_destination_url.get()); | 249 GURL verified_gurl = GURL(legacy_destination_url.get()); |
254 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) { | 250 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) { |
255 DLOG(WARNING) << "SessionMessage destination_url is invalid : " | 251 DLOG(WARNING) << "SessionMessage destination_url is invalid : " |
256 << verified_gurl.possibly_invalid_spec(); | 252 << verified_gurl.possibly_invalid_spec(); |
257 verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. | 253 verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. |
258 } | 254 } |
259 | 255 |
260 session_message_cb_.Run(session_id, | 256 session_message_cb_.Run(session_id, |
261 static_cast<MediaKeys::MessageType>(message_type), | 257 static_cast<MediaKeys::MessageType>(message_type), |
262 message.storage(), verified_gurl); | 258 message.storage(), verified_gurl); |
263 } | 259 } |
264 | 260 |
265 void MojoCdm::OnSessionClosed(const mojo::String& session_id) { | 261 void MojoCdm::OnSessionClosed(const mojo::String& session_id) { |
266 DVLOG(2) << __FUNCTION__; | 262 DVLOG(2) << __FUNCTION__; |
267 DCHECK(thread_checker_.CalledOnValidThread()); | 263 DCHECK(thread_checker_.CalledOnValidThread()); |
268 | 264 |
269 session_closed_cb_.Run(session_id); | 265 session_closed_cb_.Run(session_id); |
270 } | 266 } |
271 | 267 |
272 void MojoCdm::OnLegacySessionError(const mojo::String& session_id, | 268 void MojoCdm::OnLegacySessionError(const mojo::String& session_id, |
273 interfaces::CdmException exception, | 269 mojom::CdmException exception, |
274 uint32_t system_code, | 270 uint32_t system_code, |
275 const mojo::String& error_message) { | 271 const mojo::String& error_message) { |
276 DVLOG(2) << __FUNCTION__; | 272 DVLOG(2) << __FUNCTION__; |
277 DCHECK(thread_checker_.CalledOnValidThread()); | 273 DCHECK(thread_checker_.CalledOnValidThread()); |
278 | 274 |
279 legacy_session_error_cb_.Run(session_id, | 275 legacy_session_error_cb_.Run(session_id, |
280 static_cast<MediaKeys::Exception>(exception), | 276 static_cast<MediaKeys::Exception>(exception), |
281 system_code, error_message); | 277 system_code, error_message); |
282 } | 278 } |
283 | 279 |
284 void MojoCdm::OnSessionKeysChange( | 280 void MojoCdm::OnSessionKeysChange( |
285 const mojo::String& session_id, | 281 const mojo::String& session_id, |
286 bool has_additional_usable_key, | 282 bool has_additional_usable_key, |
287 mojo::Array<interfaces::CdmKeyInformationPtr> keys_info) { | 283 mojo::Array<mojom::CdmKeyInformationPtr> keys_info) { |
288 DVLOG(2) << __FUNCTION__; | 284 DVLOG(2) << __FUNCTION__; |
289 DCHECK(thread_checker_.CalledOnValidThread()); | 285 DCHECK(thread_checker_.CalledOnValidThread()); |
290 | 286 |
291 // TODO(jrummell): Handling resume playback should be done in the media | 287 // TODO(jrummell): Handling resume playback should be done in the media |
292 // player, not in the Decryptors. http://crbug.com/413413. | 288 // player, not in the Decryptors. http://crbug.com/413413. |
293 if (has_additional_usable_key) { | 289 if (has_additional_usable_key) { |
294 base::AutoLock auto_lock(lock_); | 290 base::AutoLock auto_lock(lock_); |
295 if (decryptor_) { | 291 if (decryptor_) { |
296 DCHECK(decryptor_task_runner_); | 292 DCHECK(decryptor_task_runner_); |
297 decryptor_task_runner_->PostTask( | 293 decryptor_task_runner_->PostTask( |
(...skipping 14 matching lines...) Expand all Loading... |
312 | 308 |
313 void MojoCdm::OnSessionExpirationUpdate(const mojo::String& session_id, | 309 void MojoCdm::OnSessionExpirationUpdate(const mojo::String& session_id, |
314 double new_expiry_time_sec) { | 310 double new_expiry_time_sec) { |
315 DVLOG(2) << __FUNCTION__; | 311 DVLOG(2) << __FUNCTION__; |
316 DCHECK(thread_checker_.CalledOnValidThread()); | 312 DCHECK(thread_checker_.CalledOnValidThread()); |
317 | 313 |
318 session_expiration_update_cb_.Run( | 314 session_expiration_update_cb_.Run( |
319 session_id, base::Time::FromDoubleT(new_expiry_time_sec)); | 315 session_id, base::Time::FromDoubleT(new_expiry_time_sec)); |
320 } | 316 } |
321 | 317 |
322 void MojoCdm::OnCdmInitialized(interfaces::CdmPromiseResultPtr result, | 318 void MojoCdm::OnCdmInitialized(mojom::CdmPromiseResultPtr result, |
323 int cdm_id, | 319 int cdm_id, |
324 interfaces::DecryptorPtr decryptor) { | 320 mojom::DecryptorPtr decryptor) { |
325 DVLOG(2) << __FUNCTION__ << " cdm_id: " << cdm_id; | 321 DVLOG(2) << __FUNCTION__ << " cdm_id: " << cdm_id; |
326 DCHECK(thread_checker_.CalledOnValidThread()); | 322 DCHECK(thread_checker_.CalledOnValidThread()); |
327 DCHECK(pending_init_promise_); | 323 DCHECK(pending_init_promise_); |
328 | 324 |
329 if (!result->success) { | 325 if (!result->success) { |
330 RejectPromise(std::move(pending_init_promise_), std::move(result)); | 326 RejectPromise(std::move(pending_init_promise_), std::move(result)); |
331 return; | 327 return; |
332 } | 328 } |
333 | 329 |
334 { | 330 { |
(...skipping 11 matching lines...) Expand all Loading... |
346 base::AutoLock auto_lock(lock_); | 342 base::AutoLock auto_lock(lock_); |
347 | 343 |
348 DCHECK(decryptor_task_runner_); | 344 DCHECK(decryptor_task_runner_); |
349 DCHECK(decryptor_task_runner_->BelongsToCurrentThread()); | 345 DCHECK(decryptor_task_runner_->BelongsToCurrentThread()); |
350 DCHECK(decryptor_); | 346 DCHECK(decryptor_); |
351 | 347 |
352 decryptor_->OnKeyAdded(); | 348 decryptor_->OnKeyAdded(); |
353 } | 349 } |
354 | 350 |
355 } // namespace media | 351 } // namespace media |
OLD | NEW |