| 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 CdmWrapper* CdmAdapter::CreateCdmInstance(const std::string& key_system) { |
| 338 PP_DCHECK(!cdm_); | 338 CdmWrapper* cdm = CdmWrapper::Create(key_system.data(), key_system.size(), |
| 339 cdm_ = make_linked_ptr(CdmWrapper::Create( | 339 GetCdmHost, this); |
| 340 key_system.data(), key_system.size(), GetCdmHost, this)); | |
| 341 bool success = cdm_ != NULL; | |
| 342 | 340 |
| 343 const std::string message = "CDM instance for " + key_system + | 341 const std::string message = "CDM instance for " + key_system + |
| 344 (success ? "" : " could not be") + " created."; | 342 (cdm ? "" : " could not be") + " created."; |
| 345 DLOG_TO_CONSOLE(message); | 343 DLOG_TO_CONSOLE(message); |
| 346 CDM_DLOG() << message; | 344 CDM_DLOG() << message; |
| 347 | 345 |
| 348 return success; | 346 return cdm; |
| 349 } | 347 } |
| 350 | 348 |
| 351 // No errors should be reported in this function because the spec says: | 349 void CdmAdapter::Initialize(uint32_t promise_id, |
| 352 // "Store this new error object internally with the MediaKeys instance being | 350 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, | 351 bool allow_distinctive_identifier, |
| 360 bool allow_persistent_state) { | 352 bool allow_persistent_state) { |
| 361 PP_DCHECK(!key_system.empty()); | 353 PP_DCHECK(!key_system.empty()); |
| 362 // TODO(jrummell): Remove this check when CDM creation is asynchronous. | 354 PP_DCHECK(!cdm_); |
| 363 // http://crbug.com/469003 | |
| 364 PP_DCHECK(key_system_.empty() || (key_system_ == key_system && cdm_)); | |
| 365 | 355 |
| 366 #if defined(CHECK_DOCUMENT_URL) | 356 #if defined(CHECK_DOCUMENT_URL) |
| 367 PP_URLComponents_Dev url_components = {}; | 357 PP_URLComponents_Dev url_components = {}; |
| 368 const pp::URLUtil_Dev* url_util = pp::URLUtil_Dev::Get(); | 358 const pp::URLUtil_Dev* url_util = pp::URLUtil_Dev::Get(); |
| 369 if (!url_util) | 359 if (!url_util) { |
| 360 RejectPromise(promise_id, cdm::kUnknownError, 0, |
| 361 "Unable to determine origin."); |
| 370 return; | 362 return; |
| 363 } |
| 364 |
| 371 pp::Var href = url_util->GetDocumentURL(pp::InstanceHandle(pp_instance()), | 365 pp::Var href = url_util->GetDocumentURL(pp::InstanceHandle(pp_instance()), |
| 372 &url_components); | 366 &url_components); |
| 373 PP_DCHECK(href.is_string()); | 367 PP_DCHECK(href.is_string()); |
| 374 std::string url = href.AsString(); | 368 std::string url = href.AsString(); |
| 375 PP_DCHECK(!url.empty()); | 369 PP_DCHECK(!url.empty()); |
| 376 std::string url_scheme = | 370 std::string url_scheme = |
| 377 url.substr(url_components.scheme.begin, url_components.scheme.len); | 371 url.substr(url_components.scheme.begin, url_components.scheme.len); |
| 378 if (url_scheme != "file") { | 372 if (url_scheme != "file") { |
| 379 // Skip this check for file:// URLs as they don't have a host component. | 373 // Skip this check for file:// URLs as they don't have a host component. |
| 380 PP_DCHECK(url_components.host.begin); | 374 PP_DCHECK(url_components.host.begin); |
| 381 PP_DCHECK(0 < url_components.host.len); | 375 PP_DCHECK(0 < url_components.host.len); |
| 382 } | 376 } |
| 383 #endif // defined(CHECK_DOCUMENT_URL) | 377 #endif // defined(CHECK_DOCUMENT_URL) |
| 384 | 378 |
| 385 if (!cdm_ && !CreateCdmInstance(key_system)) | 379 cdm_ = make_linked_ptr(CreateCdmInstance(key_system)); |
| 380 if (!cdm_) { |
| 381 RejectPromise(promise_id, cdm::kInvalidAccessError, 0, |
| 382 "Unable to create CDM."); |
| 386 return; | 383 return; |
| 384 } |
| 387 | 385 |
| 388 PP_DCHECK(cdm_); | |
| 389 key_system_ = key_system; | 386 key_system_ = key_system; |
| 390 allow_distinctive_identifier_ = allow_distinctive_identifier; | 387 allow_distinctive_identifier_ = allow_distinctive_identifier; |
| 391 allow_persistent_state_ = allow_persistent_state; | 388 allow_persistent_state_ = allow_persistent_state; |
| 392 cdm_->Initialize(allow_distinctive_identifier, allow_persistent_state); | 389 cdm_->Initialize(allow_distinctive_identifier, allow_persistent_state); |
| 390 OnResolvePromise(promise_id); |
| 393 } | 391 } |
| 394 | 392 |
| 395 void CdmAdapter::SetServerCertificate(uint32_t promise_id, | 393 void CdmAdapter::SetServerCertificate(uint32_t promise_id, |
| 396 pp::VarArrayBuffer server_certificate) { | 394 pp::VarArrayBuffer server_certificate) { |
| 397 const uint8_t* server_certificate_ptr = | 395 const uint8_t* server_certificate_ptr = |
| 398 static_cast<const uint8_t*>(server_certificate.Map()); | 396 static_cast<const uint8_t*>(server_certificate.Map()); |
| 399 const uint32_t server_certificate_size = server_certificate.ByteLength(); | 397 const uint32_t server_certificate_size = server_certificate.ByteLength(); |
| 400 | 398 |
| 401 if (!server_certificate_ptr || | 399 if (!server_certificate_ptr || |
| 402 server_certificate_size < media::limits::kMinCertificateLength || | 400 server_certificate_size < media::limits::kMinCertificateLength || |
| 403 server_certificate_size > media::limits::kMaxCertificateLength) { | 401 server_certificate_size > media::limits::kMaxCertificateLength) { |
| 404 RejectPromise( | 402 RejectPromise( |
| 405 promise_id, cdm::kInvalidAccessError, 0, "Incorrect certificate."); | 403 promise_id, cdm::kInvalidAccessError, 0, "Incorrect certificate."); |
| 406 return; | 404 return; |
| 407 } | 405 } |
| 408 | 406 |
| 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( | 407 cdm_->SetServerCertificate( |
| 421 promise_id, server_certificate_ptr, server_certificate_size); | 408 promise_id, server_certificate_ptr, server_certificate_size); |
| 422 } | 409 } |
| 423 | 410 |
| 424 void CdmAdapter::CreateSessionAndGenerateRequest(uint32_t promise_id, | 411 void CdmAdapter::CreateSessionAndGenerateRequest(uint32_t promise_id, |
| 425 PP_SessionType session_type, | 412 PP_SessionType session_type, |
| 426 PP_InitDataType init_data_type, | 413 PP_InitDataType init_data_type, |
| 427 pp::VarArrayBuffer init_data) { | 414 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( | 415 cdm_->CreateSessionAndGenerateRequest( |
| 442 promise_id, PpSessionTypeToCdmSessionType(session_type), | 416 promise_id, PpSessionTypeToCdmSessionType(session_type), |
| 443 PpInitDataTypeToCdmInitDataType(init_data_type), | 417 PpInitDataTypeToCdmInitDataType(init_data_type), |
| 444 static_cast<const uint8_t*>(init_data.Map()), init_data.ByteLength()); | 418 static_cast<const uint8_t*>(init_data.Map()), init_data.ByteLength()); |
| 445 } | 419 } |
| 446 | 420 |
| 447 void CdmAdapter::LoadSession(uint32_t promise_id, | 421 void CdmAdapter::LoadSession(uint32_t promise_id, |
| 448 PP_SessionType session_type, | 422 PP_SessionType session_type, |
| 449 const std::string& session_id) { | 423 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), | 424 cdm_->LoadSession(promise_id, PpSessionTypeToCdmSessionType(session_type), |
| 464 session_id.data(), session_id.size()); | 425 session_id.data(), session_id.size()); |
| 465 } | 426 } |
| 466 | 427 |
| 467 void CdmAdapter::UpdateSession(uint32_t promise_id, | 428 void CdmAdapter::UpdateSession(uint32_t promise_id, |
| 468 const std::string& session_id, | 429 const std::string& session_id, |
| 469 pp::VarArrayBuffer response) { | 430 pp::VarArrayBuffer response) { |
| 470 const uint8_t* response_ptr = static_cast<const uint8_t*>(response.Map()); | 431 const uint8_t* response_ptr = static_cast<const uint8_t*>(response.Map()); |
| 471 const uint32_t response_size = response.ByteLength(); | 432 const uint32_t response_size = response.ByteLength(); |
| 472 | 433 |
| (...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1372 } // namespace media | 1333 } // namespace media |
| 1373 | 1334 |
| 1374 namespace pp { | 1335 namespace pp { |
| 1375 | 1336 |
| 1376 // Factory function for your specialization of the Module object. | 1337 // Factory function for your specialization of the Module object. |
| 1377 Module* CreateModule() { | 1338 Module* CreateModule() { |
| 1378 return new media::CdmAdapterModule(); | 1339 return new media::CdmAdapterModule(); |
| 1379 } | 1340 } |
| 1380 | 1341 |
| 1381 } // namespace pp | 1342 } // namespace pp |
| OLD | NEW |