OLD | NEW |
---|---|
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/cdm/ppapi/cdm_adapter.h" | 5 #include "media/cdm/ppapi/cdm_adapter.h" |
6 | 6 |
7 #include "media/base/limits.h" | 7 #include "media/base/limits.h" |
8 #include "media/cdm/ppapi/cdm_file_io_impl.h" | 8 #include "media/cdm/ppapi/cdm_file_io_impl.h" |
9 #include "media/cdm/ppapi/cdm_helpers.h" | 9 #include "media/cdm/ppapi/cdm_helpers.h" |
10 #include "media/cdm/ppapi/cdm_logging.h" | 10 #include "media/cdm/ppapi/cdm_logging.h" |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
327 deferred_audio_decoder_config_id_(0), | 327 deferred_audio_decoder_config_id_(0), |
328 deferred_initialize_video_decoder_(false), | 328 deferred_initialize_video_decoder_(false), |
329 deferred_video_decoder_config_id_(0), | 329 deferred_video_decoder_config_id_(0), |
330 last_read_file_size_kb_(0), | 330 last_read_file_size_kb_(0), |
331 file_size_uma_reported_(false) { | 331 file_size_uma_reported_(false) { |
332 callback_factory_.Initialize(this); | 332 callback_factory_.Initialize(this); |
333 } | 333 } |
334 | 334 |
335 CdmAdapter::~CdmAdapter() {} | 335 CdmAdapter::~CdmAdapter() {} |
336 | 336 |
337 bool CdmAdapter::CreateCdmInstance(const std::string& key_system) { | 337 bool CdmAdapter::CreateCdmInstance(const std::string& key_system) { |
ddorwin
2015/05/04 22:46:02
This can probably be simplified too. We can just r
jrummell
2015/05/05 00:54:18
Done.
| |
338 PP_DCHECK(!cdm_); | 338 PP_DCHECK(!cdm_); |
339 cdm_ = make_linked_ptr(CdmWrapper::Create( | 339 cdm_ = make_linked_ptr(CdmWrapper::Create( |
340 key_system.data(), key_system.size(), GetCdmHost, this)); | 340 key_system.data(), key_system.size(), GetCdmHost, this)); |
341 bool success = cdm_ != NULL; | 341 bool success = cdm_ != NULL; |
342 | 342 |
343 const std::string message = "CDM instance for " + key_system + | 343 const std::string message = "CDM instance for " + key_system + |
344 (success ? "" : " could not be") + " created."; | 344 (success ? "" : " could not be") + " created."; |
345 DLOG_TO_CONSOLE(message); | 345 DLOG_TO_CONSOLE(message); |
346 CDM_DLOG() << message; | 346 CDM_DLOG() << message; |
347 | 347 |
348 return success; | 348 return success; |
349 } | 349 } |
350 | 350 |
351 // No errors should be reported in this function because the spec says: | 351 void CdmAdapter::Initialize(uint32_t promise_id, |
352 // "Store this new error object internally with the MediaKeys instance being | 352 const std::string& key_system, |
353 // created. This will be used to fire an error against any session created for | |
354 // this instance." These errors will be reported during session creation | |
355 // (CreateSession()) or session loading (LoadSession()). | |
356 // TODO(xhwang): If necessary, we need to store the error here if we want to | |
357 // support more specific error reporting (other than "Unknown"). | |
358 void CdmAdapter::Initialize(const std::string& key_system, | |
359 bool allow_distinctive_identifier, | 353 bool allow_distinctive_identifier, |
360 bool allow_persistent_state) { | 354 bool allow_persistent_state) { |
361 PP_DCHECK(!key_system.empty()); | 355 PP_DCHECK(!key_system.empty()); |
362 // TODO(jrummell): Remove this check when CDM creation is asynchronous. | |
363 // http://crbug.com/469003 | |
364 PP_DCHECK(key_system_.empty() || (key_system_ == key_system && cdm_)); | |
365 | 356 |
366 #if defined(CHECK_DOCUMENT_URL) | 357 #if defined(CHECK_DOCUMENT_URL) |
367 PP_URLComponents_Dev url_components = {}; | 358 PP_URLComponents_Dev url_components = {}; |
368 const pp::URLUtil_Dev* url_util = pp::URLUtil_Dev::Get(); | 359 const pp::URLUtil_Dev* url_util = pp::URLUtil_Dev::Get(); |
369 if (!url_util) | 360 if (!url_util) { |
361 RejectPromise(promise_id, cdm::kInvalidAccessError, 0, | |
ddorwin
2015/05/04 22:46:02
Not sure this is correct. Probably kUnknownError.
jrummell
2015/05/05 00:54:17
Done.
| |
362 "Unable to determine origin."); | |
370 return; | 363 return; |
364 } | |
365 | |
371 pp::Var href = url_util->GetDocumentURL(pp::InstanceHandle(pp_instance()), | 366 pp::Var href = url_util->GetDocumentURL(pp::InstanceHandle(pp_instance()), |
372 &url_components); | 367 &url_components); |
373 PP_DCHECK(href.is_string()); | 368 PP_DCHECK(href.is_string()); |
374 std::string url = href.AsString(); | 369 std::string url = href.AsString(); |
375 PP_DCHECK(!url.empty()); | 370 PP_DCHECK(!url.empty()); |
376 std::string url_scheme = | 371 std::string url_scheme = |
377 url.substr(url_components.scheme.begin, url_components.scheme.len); | 372 url.substr(url_components.scheme.begin, url_components.scheme.len); |
378 if (url_scheme != "file") { | 373 if (url_scheme != "file") { |
379 // Skip this check for file:// URLs as they don't have a host component. | 374 // Skip this check for file:// URLs as they don't have a host component. |
380 PP_DCHECK(url_components.host.begin); | 375 PP_DCHECK(url_components.host.begin); |
381 PP_DCHECK(0 < url_components.host.len); | 376 PP_DCHECK(0 < url_components.host.len); |
382 } | 377 } |
383 #endif // defined(CHECK_DOCUMENT_URL) | 378 #endif // defined(CHECK_DOCUMENT_URL) |
384 | 379 |
385 if (!cdm_ && !CreateCdmInstance(key_system)) | 380 if (!cdm_ && !CreateCdmInstance(key_system)) { |
ddorwin
2015/05/04 22:46:02
I think cdm_ must be NULL. You can DCHECK at 356.
jrummell
2015/05/05 00:54:17
Done.
| |
381 RejectPromise(promise_id, cdm::kInvalidAccessError, 0, | |
382 "Unable to create CDM."); | |
386 return; | 383 return; |
384 } | |
387 | 385 |
388 PP_DCHECK(cdm_); | 386 PP_DCHECK(cdm_); |
389 key_system_ = key_system; | 387 key_system_ = key_system; |
390 allow_distinctive_identifier_ = allow_distinctive_identifier; | 388 allow_distinctive_identifier_ = allow_distinctive_identifier; |
391 allow_persistent_state_ = allow_persistent_state; | 389 allow_persistent_state_ = allow_persistent_state; |
392 cdm_->Initialize(allow_distinctive_identifier, allow_persistent_state); | 390 cdm_->Initialize(allow_distinctive_identifier, allow_persistent_state); |
391 OnResolvePromise(promise_id); | |
393 } | 392 } |
394 | 393 |
395 void CdmAdapter::SetServerCertificate(uint32_t promise_id, | 394 void CdmAdapter::SetServerCertificate(uint32_t promise_id, |
396 pp::VarArrayBuffer server_certificate) { | 395 pp::VarArrayBuffer server_certificate) { |
397 const uint8_t* server_certificate_ptr = | 396 const uint8_t* server_certificate_ptr = |
398 static_cast<const uint8_t*>(server_certificate.Map()); | 397 static_cast<const uint8_t*>(server_certificate.Map()); |
399 const uint32_t server_certificate_size = server_certificate.ByteLength(); | 398 const uint32_t server_certificate_size = server_certificate.ByteLength(); |
400 | 399 |
401 if (!server_certificate_ptr || | 400 if (!server_certificate_ptr || |
402 server_certificate_size < media::limits::kMinCertificateLength || | 401 server_certificate_size < media::limits::kMinCertificateLength || |
403 server_certificate_size > media::limits::kMaxCertificateLength) { | 402 server_certificate_size > media::limits::kMaxCertificateLength) { |
404 RejectPromise( | 403 RejectPromise( |
405 promise_id, cdm::kInvalidAccessError, 0, "Incorrect certificate."); | 404 promise_id, cdm::kInvalidAccessError, 0, "Incorrect certificate."); |
406 return; | 405 return; |
407 } | 406 } |
408 | 407 |
409 // Initialize() doesn't report an error, so SetServerCertificate() can be | |
410 // called even if Initialize() failed. | |
411 // TODO(jrummell): Remove this code when prefixed EME gets removed. | |
412 if (!cdm_) { | |
413 RejectPromise(promise_id, | |
414 cdm::kInvalidStateError, | |
415 0, | |
416 "CDM has not been initialized."); | |
417 return; | |
418 } | |
419 | |
420 cdm_->SetServerCertificate( | 408 cdm_->SetServerCertificate( |
421 promise_id, server_certificate_ptr, server_certificate_size); | 409 promise_id, server_certificate_ptr, server_certificate_size); |
422 } | 410 } |
423 | 411 |
424 void CdmAdapter::CreateSessionAndGenerateRequest(uint32_t promise_id, | 412 void CdmAdapter::CreateSessionAndGenerateRequest(uint32_t promise_id, |
425 PP_SessionType session_type, | 413 PP_SessionType session_type, |
426 PP_InitDataType init_data_type, | 414 PP_InitDataType init_data_type, |
427 pp::VarArrayBuffer init_data) { | 415 pp::VarArrayBuffer init_data) { |
428 // Initialize() doesn't report an error, so CreateSession() can be called | |
429 // even if Initialize() failed. | |
430 // TODO(jrummell): Remove this code when prefixed EME gets removed. | |
431 // TODO(jrummell): Verify that Initialize() failing does not resolve the | |
432 // MediaKeys.create() promise. | |
433 if (!cdm_) { | |
434 RejectPromise(promise_id, | |
435 cdm::kInvalidStateError, | |
436 0, | |
437 "CDM has not been initialized."); | |
438 return; | |
439 } | |
440 | |
441 cdm_->CreateSessionAndGenerateRequest( | 416 cdm_->CreateSessionAndGenerateRequest( |
442 promise_id, PpSessionTypeToCdmSessionType(session_type), | 417 promise_id, PpSessionTypeToCdmSessionType(session_type), |
443 PpInitDataTypeToCdmInitDataType(init_data_type), | 418 PpInitDataTypeToCdmInitDataType(init_data_type), |
444 static_cast<const uint8_t*>(init_data.Map()), init_data.ByteLength()); | 419 static_cast<const uint8_t*>(init_data.Map()), init_data.ByteLength()); |
445 } | 420 } |
446 | 421 |
447 void CdmAdapter::LoadSession(uint32_t promise_id, | 422 void CdmAdapter::LoadSession(uint32_t promise_id, |
448 PP_SessionType session_type, | 423 PP_SessionType session_type, |
449 const std::string& session_id) { | 424 const std::string& session_id) { |
450 // Initialize() doesn't report an error, so LoadSession() can be called | |
451 // even if Initialize() failed. | |
452 // TODO(jrummell): Remove this code when prefixed EME gets removed. | |
453 // TODO(jrummell): Verify that Initialize() failing does not resolve the | |
454 // MediaKeys.create() promise. | |
455 if (!cdm_) { | |
456 RejectPromise(promise_id, | |
457 cdm::kInvalidStateError, | |
458 0, | |
459 "CDM has not been initialized."); | |
460 return; | |
461 } | |
462 | |
463 cdm_->LoadSession(promise_id, PpSessionTypeToCdmSessionType(session_type), | 425 cdm_->LoadSession(promise_id, PpSessionTypeToCdmSessionType(session_type), |
464 session_id.data(), session_id.size()); | 426 session_id.data(), session_id.size()); |
465 } | 427 } |
466 | 428 |
467 void CdmAdapter::UpdateSession(uint32_t promise_id, | 429 void CdmAdapter::UpdateSession(uint32_t promise_id, |
468 const std::string& session_id, | 430 const std::string& session_id, |
469 pp::VarArrayBuffer response) { | 431 pp::VarArrayBuffer response) { |
470 const uint8_t* response_ptr = static_cast<const uint8_t*>(response.Map()); | 432 const uint8_t* response_ptr = static_cast<const uint8_t*>(response.Map()); |
471 const uint32_t response_size = response.ByteLength(); | 433 const uint32_t response_size = response.ByteLength(); |
472 | 434 |
(...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1372 } // namespace media | 1334 } // namespace media |
1373 | 1335 |
1374 namespace pp { | 1336 namespace pp { |
1375 | 1337 |
1376 // Factory function for your specialization of the Module object. | 1338 // Factory function for your specialization of the Module object. |
1377 Module* CreateModule() { | 1339 Module* CreateModule() { |
1378 return new media::CdmAdapterModule(); | 1340 return new media::CdmAdapterModule(); |
1379 } | 1341 } |
1380 | 1342 |
1381 } // namespace pp | 1343 } // namespace pp |
OLD | NEW |