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