| 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/external_clear_key/clear_key_cdm.h" | 5 #include "media/cdm/ppapi/external_clear_key/clear_key_cdm.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <cstring> | 8 #include <cstring> |
| 9 #include <sstream> | 9 #include <sstream> |
| 10 #include <string> | 10 #include <string> |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 const int64 kMaxTimerDelayMs = 1 * kSecondsPerMinute * kMsPerSecond; | 88 const int64 kMaxTimerDelayMs = 1 * kSecondsPerMinute * kMsPerSecond; |
| 89 // Heart beat message header. If a key message starts with |kHeartBeatHeader|, | 89 // Heart beat message header. If a key message starts with |kHeartBeatHeader|, |
| 90 // it's a heart beat message. Otherwise, it's a key request. | 90 // it's a heart beat message. Otherwise, it's a key request. |
| 91 const char kHeartBeatHeader[] = "HEARTBEAT"; | 91 const char kHeartBeatHeader[] = "HEARTBEAT"; |
| 92 // CDM file IO test result header. | 92 // CDM file IO test result header. |
| 93 const char kFileIOTestResultHeader[] = "FILEIOTESTRESULT"; | 93 const char kFileIOTestResultHeader[] = "FILEIOTESTRESULT"; |
| 94 | 94 |
| 95 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is | 95 // Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is |
| 96 // empty, an empty (end-of-stream) media::DecoderBuffer is returned. | 96 // empty, an empty (end-of-stream) media::DecoderBuffer is returned. |
| 97 static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom( | 97 static scoped_refptr<media::DecoderBuffer> CopyDecoderBufferFrom( |
| 98 const cdm::InputBuffer_1& input_buffer) { | 98 const cdm::InputBuffer& input_buffer) { |
| 99 if (!input_buffer.data) { | 99 if (!input_buffer.data) { |
| 100 DCHECK(!input_buffer.data_size); | 100 DCHECK(!input_buffer.data_size); |
| 101 return media::DecoderBuffer::CreateEOSBuffer(); | 101 return media::DecoderBuffer::CreateEOSBuffer(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 // TODO(xhwang): Get rid of this copy. | 104 // TODO(xhwang): Get rid of this copy. |
| 105 scoped_refptr<media::DecoderBuffer> output_buffer = | 105 scoped_refptr<media::DecoderBuffer> output_buffer = |
| 106 media::DecoderBuffer::CopyFrom(input_buffer.data, input_buffer.data_size); | 106 media::DecoderBuffer::CopyFrom(input_buffer.data, input_buffer.data_size); |
| 107 | 107 |
| 108 std::vector<media::SubsampleEntry> subsamples; | 108 std::vector<media::SubsampleEntry> subsamples; |
| 109 for (uint32_t i = 0; i < input_buffer.num_subsamples; ++i) { | 109 for (uint32_t i = 0; i < input_buffer.num_subsamples; ++i) { |
| 110 media::SubsampleEntry subsample; | 110 media::SubsampleEntry subsample; |
| 111 subsample.clear_bytes = input_buffer.subsamples[i].clear_bytes; | 111 subsample.clear_bytes = input_buffer.subsamples[i].clear_bytes; |
| 112 subsample.cypher_bytes = input_buffer.subsamples[i].cipher_bytes; | 112 subsample.cypher_bytes = input_buffer.subsamples[i].cipher_bytes; |
| 113 subsamples.push_back(subsample); | 113 subsamples.push_back(subsample); |
| 114 } | 114 } |
| 115 | 115 |
| 116 DCHECK_EQ(input_buffer.data_offset, 0u); | |
| 117 scoped_ptr<media::DecryptConfig> decrypt_config(new media::DecryptConfig( | 116 scoped_ptr<media::DecryptConfig> decrypt_config(new media::DecryptConfig( |
| 118 std::string(reinterpret_cast<const char*>(input_buffer.key_id), | 117 std::string(reinterpret_cast<const char*>(input_buffer.key_id), |
| 119 input_buffer.key_id_size), | 118 input_buffer.key_id_size), |
| 120 std::string(reinterpret_cast<const char*>(input_buffer.iv), | 119 std::string(reinterpret_cast<const char*>(input_buffer.iv), |
| 121 input_buffer.iv_size), | 120 input_buffer.iv_size), |
| 122 subsamples)); | 121 subsamples)); |
| 123 | 122 |
| 124 output_buffer->set_decrypt_config(decrypt_config.Pass()); | 123 output_buffer->set_decrypt_config(decrypt_config.Pass()); |
| 125 output_buffer->set_timestamp( | 124 output_buffer->set_timestamp( |
| 126 base::TimeDelta::FromMicroseconds(input_buffer.timestamp)); | 125 base::TimeDelta::FromMicroseconds(input_buffer.timestamp)); |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 // Loads a emulated stored session. Currently only |kLoadableWebSessionId| | 265 // Loads a emulated stored session. Currently only |kLoadableWebSessionId| |
| 267 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is | 266 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is |
| 268 // supported. | 267 // supported. |
| 269 void ClearKeyCdm::LoadSession(uint32 promise_id, | 268 void ClearKeyCdm::LoadSession(uint32 promise_id, |
| 270 const char* web_session_id, | 269 const char* web_session_id, |
| 271 uint32_t web_session_id_length) { | 270 uint32_t web_session_id_length) { |
| 272 DVLOG(1) << __FUNCTION__; | 271 DVLOG(1) << __FUNCTION__; |
| 273 | 272 |
| 274 if (std::string(kLoadableWebSessionId) != | 273 if (std::string(kLoadableWebSessionId) != |
| 275 std::string(web_session_id, web_session_id_length)) { | 274 std::string(web_session_id, web_session_id_length)) { |
| 275 // TODO(jrummell): This should be resolved with undefined, not rejected. |
| 276 std::string message("Incorrect session id specified for LoadSession()."); | 276 std::string message("Incorrect session id specified for LoadSession()."); |
| 277 host_->OnRejectPromise(promise_id, | 277 host_->OnRejectPromise(promise_id, |
| 278 cdm::kInvalidAccessError, | 278 cdm::kInvalidAccessError, |
| 279 0, | 279 0, |
| 280 message.data(), | 280 message.data(), |
| 281 message.length()); | 281 message.length()); |
| 282 return; | 282 return; |
| 283 } | 283 } |
| 284 | 284 |
| 285 scoped_ptr<media::NewSessionCdmPromise> promise( | 285 scoped_ptr<media::NewSessionCdmPromise> promise( |
| 286 new media::NewSessionCdmPromise(base::Bind(&ClearKeyCdm::OnSessionLoaded, | 286 new media::NewSessionCdmPromise(base::Bind(&ClearKeyCdm::OnSessionLoaded, |
| 287 base::Unretained(this), | 287 base::Unretained(this), |
| 288 promise_id), | 288 promise_id), |
| 289 base::Bind(&ClearKeyCdm::OnPromiseFailed, | 289 base::Bind(&ClearKeyCdm::OnPromiseFailed, |
| 290 base::Unretained(this), | 290 base::Unretained(this), |
| 291 promise_id))); | 291 promise_id))); |
| 292 decryptor_.CreateSession(std::string(kLoadableSessionContentType), | 292 decryptor_.CreateSession(std::string(kLoadableSessionContentType), |
| 293 NULL, | 293 NULL, |
| 294 0, | 294 0, |
| 295 MediaKeys::TEMPORARY_SESSION, | 295 MediaKeys::TEMPORARY_SESSION, |
| 296 promise.Pass()); | 296 promise.Pass()); |
| 297 } | 297 } |
| 298 | 298 |
| 299 void ClearKeyCdm::UpdateSession(uint32 promise_id, | 299 void ClearKeyCdm::UpdateSession(uint32 promise_id, |
| 300 const char* web_session_id, | 300 const char* web_session_id, |
| 301 uint32_t web_session_id_size, | 301 uint32_t web_session_id_length, |
| 302 const uint8* response, | 302 const uint8* response, |
| 303 uint32 response_size) { | 303 uint32 response_size) { |
| 304 DVLOG(1) << __FUNCTION__; | 304 DVLOG(1) << __FUNCTION__; |
| 305 std::string web_session_str(web_session_id, web_session_id_size); | 305 std::string web_session_str(web_session_id, web_session_id_length); |
| 306 | 306 |
| 307 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( | 307 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( |
| 308 base::Bind(&ClearKeyCdm::OnSessionUpdated, | 308 base::Bind(&ClearKeyCdm::OnSessionUpdated, |
| 309 base::Unretained(this), | 309 base::Unretained(this), |
| 310 promise_id, | 310 promise_id, |
| 311 web_session_str), | 311 web_session_str), |
| 312 base::Bind( | 312 base::Bind( |
| 313 &ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); | 313 &ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); |
| 314 decryptor_.UpdateSession( | 314 decryptor_.UpdateSession( |
| 315 web_session_str, response, response_size, promise.Pass()); | 315 web_session_str, response, response_size, promise.Pass()); |
| 316 | 316 |
| 317 if (!heartbeat_timer_set_) { | 317 if (!heartbeat_timer_set_) { |
| 318 ScheduleNextHeartBeat(); | 318 ScheduleNextHeartBeat(); |
| 319 heartbeat_timer_set_ = true; | 319 heartbeat_timer_set_ = true; |
| 320 } | 320 } |
| 321 } | 321 } |
| 322 | 322 |
| 323 void ClearKeyCdm::ReleaseSession(uint32 promise_id, | 323 void ClearKeyCdm::CloseSession(uint32 promise_id, |
| 324 const char* web_session_id, | 324 const char* web_session_id, |
| 325 uint32_t web_session_id_size) { | 325 uint32_t web_session_id_length) { |
| 326 DVLOG(1) << __FUNCTION__; | 326 DVLOG(1) << __FUNCTION__; |
| 327 std::string web_session_str(web_session_id, web_session_id_size); | 327 std::string web_session_str(web_session_id, web_session_id_length); |
| 328 | 328 |
| 329 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( | 329 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( |
| 330 base::Bind(&ClearKeyCdm::OnSessionReleased, | 330 base::Bind(&ClearKeyCdm::OnSessionReleased, |
| 331 base::Unretained(this), | 331 base::Unretained(this), |
| 332 promise_id, | 332 promise_id, |
| 333 web_session_str), | 333 web_session_str), |
| 334 base::Bind( | 334 base::Bind( |
| 335 &ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); | 335 &ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); |
| 336 decryptor_.ReleaseSession(web_session_str, promise.Pass()); | 336 decryptor_.ReleaseSession(web_session_str, promise.Pass()); |
| 337 } | 337 } |
| 338 | 338 |
| 339 void ClearKeyCdm::RemoveSession(uint32 promise_id, |
| 340 const char* web_session_id, |
| 341 uint32_t web_session_id_length) { |
| 342 DVLOG(1) << __FUNCTION__; |
| 343 // RemoveSession only allowed for persistent sessions. |
| 344 bool is_persistent_session = |
| 345 std::string(kLoadableWebSessionId) == |
| 346 std::string(web_session_id, web_session_id_length); |
| 347 if (is_persistent_session) { |
| 348 host_->OnResolvePromise(promise_id); |
| 349 } else { |
| 350 std::string message("Not supported for non-persistent sessions."); |
| 351 host_->OnRejectPromise(promise_id, |
| 352 cdm::kInvalidAccessError, |
| 353 0, |
| 354 message.data(), |
| 355 message.length()); |
| 356 } |
| 357 } |
| 358 |
| 339 void ClearKeyCdm::SetServerCertificate(uint32 promise_id, | 359 void ClearKeyCdm::SetServerCertificate(uint32 promise_id, |
| 340 const uint8_t* server_certificate_data, | 360 const uint8_t* server_certificate_data, |
| 341 uint32_t server_certificate_data_size) { | 361 uint32_t server_certificate_data_size) { |
| 342 // ClearKey doesn't use a server certificate. | 362 // ClearKey doesn't use a server certificate. |
| 343 host_->OnResolvePromise(promise_id); | 363 host_->OnResolvePromise(promise_id); |
| 344 } | 364 } |
| 345 | 365 |
| 366 void ClearKeyCdm::GetUsableKeyIds(uint32_t promise_id, |
| 367 const char* web_session_id, |
| 368 uint32_t web_session_id_length) { |
| 369 std::string web_session_str(web_session_id, web_session_id_length); |
| 370 scoped_ptr<media::KeyIdsPromise> promise(new media::KeyIdsPromise( |
| 371 base::Bind(&ClearKeyCdm::OnUsableKeyIdsObtained, |
| 372 base::Unretained(this), |
| 373 promise_id), |
| 374 base::Bind( |
| 375 &ClearKeyCdm::OnPromiseFailed, base::Unretained(this), promise_id))); |
| 376 decryptor_.GetUsableKeyIds(web_session_str, promise.Pass()); |
| 377 } |
| 378 |
| 346 void ClearKeyCdm::TimerExpired(void* context) { | 379 void ClearKeyCdm::TimerExpired(void* context) { |
| 347 if (context == &session_id_for_emulated_loadsession_) { | 380 if (context == &session_id_for_emulated_loadsession_) { |
| 348 LoadLoadableSession(); | 381 LoadLoadableSession(); |
| 349 return; | 382 return; |
| 350 } | 383 } |
| 351 | 384 |
| 352 DCHECK(heartbeat_timer_set_); | 385 DCHECK(heartbeat_timer_set_); |
| 353 std::string heartbeat_message; | 386 std::string heartbeat_message; |
| 354 if (!next_heartbeat_message_.empty() && | 387 if (!next_heartbeat_message_.empty() && |
| 355 context == &next_heartbeat_message_[0]) { | 388 context == &next_heartbeat_message_[0]) { |
| (...skipping 18 matching lines...) Expand all Loading... |
| 374 | 407 |
| 375 static void CopyDecryptResults( | 408 static void CopyDecryptResults( |
| 376 media::Decryptor::Status* status_copy, | 409 media::Decryptor::Status* status_copy, |
| 377 scoped_refptr<media::DecoderBuffer>* buffer_copy, | 410 scoped_refptr<media::DecoderBuffer>* buffer_copy, |
| 378 media::Decryptor::Status status, | 411 media::Decryptor::Status status, |
| 379 const scoped_refptr<media::DecoderBuffer>& buffer) { | 412 const scoped_refptr<media::DecoderBuffer>& buffer) { |
| 380 *status_copy = status; | 413 *status_copy = status; |
| 381 *buffer_copy = buffer; | 414 *buffer_copy = buffer; |
| 382 } | 415 } |
| 383 | 416 |
| 384 cdm::Status ClearKeyCdm::Decrypt(const cdm::InputBuffer_1& encrypted_buffer, | 417 cdm::Status ClearKeyCdm::Decrypt(const cdm::InputBuffer& encrypted_buffer, |
| 385 cdm::DecryptedBlock* decrypted_block) { | 418 cdm::DecryptedBlock* decrypted_block) { |
| 386 DVLOG(1) << "Decrypt()"; | 419 DVLOG(1) << "Decrypt()"; |
| 387 DCHECK(encrypted_buffer.data); | 420 DCHECK(encrypted_buffer.data); |
| 388 | 421 |
| 389 scoped_refptr<media::DecoderBuffer> buffer; | 422 scoped_refptr<media::DecoderBuffer> buffer; |
| 390 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); | 423 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); |
| 391 | 424 |
| 392 if (status != cdm::kSuccess) | 425 if (status != cdm::kSuccess) |
| 393 return status; | 426 return status; |
| 394 | 427 |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 480 output_timestamp_base_in_microseconds_ = kNoTimestamp; | 513 output_timestamp_base_in_microseconds_ = kNoTimestamp; |
| 481 total_samples_generated_ = 0; | 514 total_samples_generated_ = 0; |
| 482 #endif | 515 #endif |
| 483 break; | 516 break; |
| 484 default: | 517 default: |
| 485 NOTREACHED() << "DeinitializeDecoder(): invalid cdm::StreamType"; | 518 NOTREACHED() << "DeinitializeDecoder(): invalid cdm::StreamType"; |
| 486 } | 519 } |
| 487 } | 520 } |
| 488 | 521 |
| 489 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( | 522 cdm::Status ClearKeyCdm::DecryptAndDecodeFrame( |
| 490 const cdm::InputBuffer_1& encrypted_buffer, | 523 const cdm::InputBuffer& encrypted_buffer, |
| 491 cdm::VideoFrame* decoded_frame) { | 524 cdm::VideoFrame* decoded_frame) { |
| 492 DVLOG(1) << "DecryptAndDecodeFrame()"; | 525 DVLOG(1) << "DecryptAndDecodeFrame()"; |
| 493 TRACE_EVENT0("media", "ClearKeyCdm::DecryptAndDecodeFrame"); | 526 TRACE_EVENT0("media", "ClearKeyCdm::DecryptAndDecodeFrame"); |
| 494 | 527 |
| 495 scoped_refptr<media::DecoderBuffer> buffer; | 528 scoped_refptr<media::DecoderBuffer> buffer; |
| 496 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); | 529 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); |
| 497 | 530 |
| 498 if (status != cdm::kSuccess) | 531 if (status != cdm::kSuccess) |
| 499 return status; | 532 return status; |
| 500 | 533 |
| 501 const uint8_t* data = NULL; | 534 const uint8_t* data = NULL; |
| 502 int32_t size = 0; | 535 int32_t size = 0; |
| 503 int64_t timestamp = 0; | 536 int64_t timestamp = 0; |
| 504 if (!buffer->end_of_stream()) { | 537 if (!buffer->end_of_stream()) { |
| 505 data = buffer->data(); | 538 data = buffer->data(); |
| 506 size = buffer->data_size(); | 539 size = buffer->data_size(); |
| 507 timestamp = encrypted_buffer.timestamp; | 540 timestamp = encrypted_buffer.timestamp; |
| 508 } | 541 } |
| 509 | 542 |
| 510 return video_decoder_->DecodeFrame(data, size, timestamp, decoded_frame); | 543 return video_decoder_->DecodeFrame(data, size, timestamp, decoded_frame); |
| 511 } | 544 } |
| 512 | 545 |
| 513 cdm::Status ClearKeyCdm::DecryptAndDecodeSamples( | 546 cdm::Status ClearKeyCdm::DecryptAndDecodeSamples( |
| 514 const cdm::InputBuffer_1& encrypted_buffer, | 547 const cdm::InputBuffer& encrypted_buffer, |
| 515 cdm::AudioFrames* audio_frames) { | 548 cdm::AudioFrames* audio_frames) { |
| 516 DVLOG(1) << "DecryptAndDecodeSamples()"; | 549 DVLOG(1) << "DecryptAndDecodeSamples()"; |
| 517 | 550 |
| 518 // Trigger a crash on purpose for testing purpose. | 551 // Trigger a crash on purpose for testing purpose. |
| 519 if (key_system_ == kExternalClearKeyCrashKeySystem) | 552 if (key_system_ == kExternalClearKeyCrashKeySystem) |
| 520 CHECK(false); | 553 CHECK(false); |
| 521 | 554 |
| 522 scoped_refptr<media::DecoderBuffer> buffer; | 555 scoped_refptr<media::DecoderBuffer> buffer; |
| 523 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); | 556 cdm::Status status = DecryptToMediaDecoderBuffer(encrypted_buffer, &buffer); |
| 524 | 557 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 550 | 583 |
| 551 void ClearKeyCdm::Destroy() { | 584 void ClearKeyCdm::Destroy() { |
| 552 DVLOG(1) << "Destroy()"; | 585 DVLOG(1) << "Destroy()"; |
| 553 delete this; | 586 delete this; |
| 554 } | 587 } |
| 555 | 588 |
| 556 void ClearKeyCdm::ScheduleNextHeartBeat() { | 589 void ClearKeyCdm::ScheduleNextHeartBeat() { |
| 557 // Prepare the next heartbeat message and set timer. | 590 // Prepare the next heartbeat message and set timer. |
| 558 std::ostringstream msg_stream; | 591 std::ostringstream msg_stream; |
| 559 msg_stream << kHeartBeatHeader << " from ClearKey CDM set at time " | 592 msg_stream << kHeartBeatHeader << " from ClearKey CDM set at time " |
| 560 << host_->GetCurrentTime() << "."; | 593 << host_->GetCurrentWallTime() << "."; |
| 561 next_heartbeat_message_ = msg_stream.str(); | 594 next_heartbeat_message_ = msg_stream.str(); |
| 562 | 595 |
| 563 host_->SetTimer(timer_delay_ms_, &next_heartbeat_message_[0]); | 596 host_->SetTimer(timer_delay_ms_, &next_heartbeat_message_[0]); |
| 564 | 597 |
| 565 // Use a smaller timer delay at start-up to facilitate testing. Increase the | 598 // Use a smaller timer delay at start-up to facilitate testing. Increase the |
| 566 // timer delay up to a limit to avoid message spam. | 599 // timer delay up to a limit to avoid message spam. |
| 567 if (timer_delay_ms_ < kMaxTimerDelayMs) | 600 if (timer_delay_ms_ < kMaxTimerDelayMs) |
| 568 timer_delay_ms_ = std::min(2 * timer_delay_ms_, kMaxTimerDelayMs); | 601 timer_delay_ms_ = std::min(2 * timer_delay_ms_, kMaxTimerDelayMs); |
| 569 } | 602 } |
| 570 | 603 |
| 571 cdm::Status ClearKeyCdm::DecryptToMediaDecoderBuffer( | 604 cdm::Status ClearKeyCdm::DecryptToMediaDecoderBuffer( |
| 572 const cdm::InputBuffer_1& encrypted_buffer, | 605 const cdm::InputBuffer& encrypted_buffer, |
| 573 scoped_refptr<media::DecoderBuffer>* decrypted_buffer) { | 606 scoped_refptr<media::DecoderBuffer>* decrypted_buffer) { |
| 574 DCHECK(decrypted_buffer); | 607 DCHECK(decrypted_buffer); |
| 575 scoped_refptr<media::DecoderBuffer> buffer = | 608 scoped_refptr<media::DecoderBuffer> buffer = |
| 576 CopyDecoderBufferFrom(encrypted_buffer); | 609 CopyDecoderBufferFrom(encrypted_buffer); |
| 577 | 610 |
| 578 if (buffer->end_of_stream()) { | 611 if (buffer->end_of_stream()) { |
| 579 *decrypted_buffer = buffer; | 612 *decrypted_buffer = buffer; |
| 580 return cdm::kSuccess; | 613 return cdm::kSuccess; |
| 581 } | 614 } |
| 582 | 615 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 // Defer resolving the promise until the session is loaded. | 713 // Defer resolving the promise until the session is loaded. |
| 681 promise_id_for_emulated_loadsession_ = promise_id; | 714 promise_id_for_emulated_loadsession_ = promise_id; |
| 682 | 715 |
| 683 // Use the address of |session_id_for_emulated_loadsession_| as the timer | 716 // Use the address of |session_id_for_emulated_loadsession_| as the timer |
| 684 // context so that we can call LoadLoadableSession() when the timer expires. | 717 // context so that we can call LoadLoadableSession() when the timer expires. |
| 685 host_->SetTimer(kDelayToLoadSessionMs, &session_id_for_emulated_loadsession_); | 718 host_->SetTimer(kDelayToLoadSessionMs, &session_id_for_emulated_loadsession_); |
| 686 } | 719 } |
| 687 | 720 |
| 688 void ClearKeyCdm::OnSessionUpdated(uint32 promise_id, | 721 void ClearKeyCdm::OnSessionUpdated(uint32 promise_id, |
| 689 const std::string& web_session_id) { | 722 const std::string& web_session_id) { |
| 690 // OnSessionReady() only called as success for UpdateSession(). However, | 723 // UpdateSession() may be called to finish loading sessions, so handle |
| 691 // UpdateSession() also called to finish loading sessions, so handle | |
| 692 // appropriately. | 724 // appropriately. |
| 693 if (web_session_id == session_id_for_emulated_loadsession_) { | 725 if (web_session_id == session_id_for_emulated_loadsession_) { |
| 694 session_id_for_emulated_loadsession_ = std::string(); | 726 session_id_for_emulated_loadsession_ = std::string(); |
| 695 // |promise_id| is the LoadSession() promise, so resolve appropriately. | 727 // |promise_id| is the LoadSession() promise, so resolve appropriately. |
| 696 host_->OnResolveNewSessionPromise( | 728 host_->OnResolveNewSessionPromise( |
| 697 promise_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId)); | 729 promise_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId)); |
| 698 host_->OnSessionReady(kLoadableWebSessionId, strlen(kLoadableWebSessionId)); | |
| 699 return; | 730 return; |
| 700 } | 731 } |
| 701 | 732 |
| 702 host_->OnResolvePromise(promise_id); | 733 host_->OnResolvePromise(promise_id); |
| 703 } | 734 } |
| 704 | 735 |
| 705 void ClearKeyCdm::OnSessionReleased(uint32 promise_id, | 736 void ClearKeyCdm::OnSessionReleased(uint32 promise_id, |
| 706 const std::string& web_session_id) { | 737 const std::string& web_session_id) { |
| 707 host_->OnResolvePromise(promise_id); | 738 host_->OnResolvePromise(promise_id); |
| 708 } | 739 } |
| 709 | 740 |
| 741 void ClearKeyCdm::OnUsableKeyIdsObtained(uint32 promise_id, |
| 742 const KeyIdsVector& key_ids) { |
| 743 scoped_ptr<cdm::BinaryData[]> result(new cdm::BinaryData[key_ids.size()]); |
| 744 for (uint32 i = 0; i < key_ids.size(); ++i) { |
| 745 result[i].data = key_ids[i].data(); |
| 746 result[i].length = key_ids[i].size(); |
| 747 } |
| 748 host_->OnResolveKeyIdsPromise(promise_id, result.get(), key_ids.size()); |
| 749 } |
| 750 |
| 710 void ClearKeyCdm::OnPromiseFailed(uint32 promise_id, | 751 void ClearKeyCdm::OnPromiseFailed(uint32 promise_id, |
| 711 MediaKeys::Exception exception_code, | 752 MediaKeys::Exception exception_code, |
| 712 uint32 system_code, | 753 uint32 system_code, |
| 713 const std::string& error_message) { | 754 const std::string& error_message) { |
| 714 host_->OnRejectPromise(promise_id, | 755 host_->OnRejectPromise(promise_id, |
| 715 ConvertException(exception_code), | 756 ConvertException(exception_code), |
| 716 system_code, | 757 system_code, |
| 717 error_message.data(), | 758 error_message.data(), |
| 718 error_message.length()); | 759 error_message.length()); |
| 719 } | 760 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 790 host_->OnSessionMessage(last_session_id_.data(), | 831 host_->OnSessionMessage(last_session_id_.data(), |
| 791 last_session_id_.length(), | 832 last_session_id_.length(), |
| 792 message.data(), | 833 message.data(), |
| 793 message.length(), | 834 message.length(), |
| 794 NULL, | 835 NULL, |
| 795 0); | 836 0); |
| 796 file_io_test_runner_.reset(); | 837 file_io_test_runner_.reset(); |
| 797 } | 838 } |
| 798 | 839 |
| 799 } // namespace media | 840 } // namespace media |
| OLD | NEW |