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 |