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 <sstream> | 9 #include <sstream> |
9 #include <string> | 10 #include <string> |
10 #include <vector> | 11 #include <vector> |
11 | 12 |
12 #include "base/bind.h" | 13 #include "base/bind.h" |
13 #include "base/debug/trace_event.h" | 14 #include "base/debug/trace_event.h" |
14 #include "base/logging.h" | 15 #include "base/logging.h" |
15 #include "base/time/time.h" | 16 #include "base/time/time.h" |
16 #include "media/base/decoder_buffer.h" | 17 #include "media/base/decoder_buffer.h" |
17 #include "media/base/decrypt_config.h" | 18 #include "media/base/decrypt_config.h" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
189 base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this)), | 190 base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this)), |
190 base::Bind(&ClearKeyCdm::OnSessionMessage, base::Unretained(this)), | 191 base::Bind(&ClearKeyCdm::OnSessionMessage, base::Unretained(this)), |
191 base::Bind(&ClearKeyCdm::OnSessionReady, base::Unretained(this)), | 192 base::Bind(&ClearKeyCdm::OnSessionReady, base::Unretained(this)), |
192 base::Bind(&ClearKeyCdm::OnSessionClosed, base::Unretained(this)), | 193 base::Bind(&ClearKeyCdm::OnSessionClosed, base::Unretained(this)), |
193 base::Bind(&ClearKeyCdm::OnSessionError, base::Unretained(this))), | 194 base::Bind(&ClearKeyCdm::OnSessionError, base::Unretained(this))), |
194 host_(host), | 195 host_(host), |
195 key_system_(key_system), | 196 key_system_(key_system), |
196 last_session_id_(MediaKeys::kInvalidSessionId), | 197 last_session_id_(MediaKeys::kInvalidSessionId), |
197 session_id_for_emulated_loadsession_(MediaKeys::kInvalidSessionId), | 198 session_id_for_emulated_loadsession_(MediaKeys::kInvalidSessionId), |
198 timer_delay_ms_(kInitialTimerDelayMs), | 199 timer_delay_ms_(kInitialTimerDelayMs), |
199 timer_set_(false) { | 200 heartbeat_timer_set_(false) { |
200 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | 201 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
201 channel_count_ = 0; | 202 channel_count_ = 0; |
202 bits_per_channel_ = 0; | 203 bits_per_channel_ = 0; |
203 samples_per_second_ = 0; | 204 samples_per_second_ = 0; |
204 output_timestamp_base_in_microseconds_ = kNoTimestamp; | 205 output_timestamp_base_in_microseconds_ = kNoTimestamp; |
205 total_samples_generated_ = 0; | 206 total_samples_generated_ = 0; |
206 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER | 207 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER |
207 } | 208 } |
208 | 209 |
209 ClearKeyCdm::~ClearKeyCdm() {} | 210 ClearKeyCdm::~ClearKeyCdm() {} |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 | 244 |
244 decryptor_.CreateSession(session_id, kLoadableSessionContentType, NULL, 0); | 245 decryptor_.CreateSession(session_id, kLoadableSessionContentType, NULL, 0); |
245 } | 246 } |
246 | 247 |
247 void ClearKeyCdm::UpdateSession(uint32 session_id, | 248 void ClearKeyCdm::UpdateSession(uint32 session_id, |
248 const uint8* response, | 249 const uint8* response, |
249 uint32 response_size) { | 250 uint32 response_size) { |
250 DVLOG(1) << __FUNCTION__; | 251 DVLOG(1) << __FUNCTION__; |
251 decryptor_.UpdateSession(session_id, response, response_size); | 252 decryptor_.UpdateSession(session_id, response, response_size); |
252 | 253 |
253 if (!timer_set_) { | 254 if (!heartbeat_timer_set_) { |
254 ScheduleNextHeartBeat(); | 255 ScheduleNextHeartBeat(); |
255 timer_set_ = true; | 256 heartbeat_timer_set_ = true; |
256 } | 257 } |
257 } | 258 } |
258 | 259 |
259 void ClearKeyCdm::ReleaseSession(uint32 session_id) { | 260 void ClearKeyCdm::ReleaseSession(uint32 session_id) { |
260 DVLOG(1) << __FUNCTION__; | 261 DVLOG(1) << __FUNCTION__; |
261 decryptor_.ReleaseSession(session_id); | 262 decryptor_.ReleaseSession(session_id); |
262 } | 263 } |
263 | 264 |
264 void ClearKeyCdm::TimerExpired(void* context) { | 265 void ClearKeyCdm::TimerExpired(void* context) { |
266 if (context == &session_id_for_emulated_loadsession_) { | |
267 LoadLoadableSession(); | |
268 return; | |
269 } | |
270 | |
271 DCHECK(heartbeat_timer_set_); | |
265 std::string heartbeat_message; | 272 std::string heartbeat_message; |
266 if (!next_heartbeat_message_.empty() && | 273 if (!next_heartbeat_message_.empty() && |
267 context == &next_heartbeat_message_[0]) { | 274 context == &next_heartbeat_message_[0]) { |
268 heartbeat_message = next_heartbeat_message_; | 275 heartbeat_message = next_heartbeat_message_; |
269 } else { | 276 } else { |
270 heartbeat_message = "ERROR: Invalid timer context found!"; | 277 heartbeat_message = "ERROR: Invalid timer context found!"; |
271 } | 278 } |
272 | 279 |
273 // This URL is only used for testing the code path for defaultURL. | 280 // This URL is only used for testing the code path for defaultURL. |
274 // There is no service at this URL, so applications should ignore it. | 281 // There is no service at this URL, so applications should ignore it. |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
514 void ClearKeyCdm::OnPlatformChallengeResponse( | 521 void ClearKeyCdm::OnPlatformChallengeResponse( |
515 const cdm::PlatformChallengeResponse& response) { | 522 const cdm::PlatformChallengeResponse& response) { |
516 NOTIMPLEMENTED(); | 523 NOTIMPLEMENTED(); |
517 } | 524 } |
518 | 525 |
519 void ClearKeyCdm::OnQueryOutputProtectionStatus( | 526 void ClearKeyCdm::OnQueryOutputProtectionStatus( |
520 uint32_t link_mask, uint32_t output_protection_mask) { | 527 uint32_t link_mask, uint32_t output_protection_mask) { |
521 NOTIMPLEMENTED(); | 528 NOTIMPLEMENTED(); |
522 }; | 529 }; |
523 | 530 |
524 void ClearKeyCdm::UpdateLoadableSession() { | 531 void ClearKeyCdm::LoadLoadableSession() { |
525 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey, | 532 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey, |
526 sizeof(kLoadableSessionKey), | 533 sizeof(kLoadableSessionKey), |
527 kLoadableSessionKeyId, | 534 kLoadableSessionKeyId, |
528 sizeof(kLoadableSessionKeyId) - 1); | 535 sizeof(kLoadableSessionKeyId) - 1); |
529 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support, | 536 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support, |
530 // this is okay. Check WD EME support. | 537 // this is okay. Check WD EME support. |
531 decryptor_.UpdateSession(session_id_for_emulated_loadsession_, | 538 decryptor_.UpdateSession(session_id_for_emulated_loadsession_, |
532 reinterpret_cast<const uint8*>(jwk_set.data()), | 539 reinterpret_cast<const uint8*>(jwk_set.data()), |
533 jwk_set.size()); | 540 jwk_set.size()); |
534 } | 541 } |
535 | 542 |
536 void ClearKeyCdm::OnSessionCreated(uint32 session_id, | 543 void ClearKeyCdm::OnSessionCreated(uint32 session_id, |
537 const std::string& web_session_id) { | 544 const std::string& web_session_id) { |
538 std::string new_web_session_id = web_session_id; | 545 std::string new_web_session_id = web_session_id; |
539 | 546 |
540 if (session_id == session_id_for_emulated_loadsession_) { | 547 if (session_id == session_id_for_emulated_loadsession_) { |
541 new_web_session_id = kLoadableWebSessionId; | 548 // Delay LoadLoadableSession() to test the case where Decrypt*() calls are |
542 UpdateLoadableSession(); | 549 // made before the session is fully loaded. |
543 session_id_for_emulated_loadsession_ = MediaKeys::kInvalidSessionId; | 550 const int64 kDelayToLoadSessionMs = 500; |
551 // Use the address of |session_id_for_emulated_loadsession_| as the timer | |
552 // context so that we can call LoadLoadableSession() when the timer expires. | |
553 host_->SetTimer(kDelayToLoadSessionMs, | |
554 &session_id_for_emulated_loadsession_); | |
555 // Defer OnSessionCreated() until the session is loaded with | |
556 // kLoadableSessionKey. | |
ddorwin
2014/02/19 00:38:13
nit: The fact that it is loaded with this specific
xhwang
2014/02/19 00:46:42
Done.
| |
557 return; | |
544 } | 558 } |
545 | 559 |
546 host_->OnSessionCreated( | 560 host_->OnSessionCreated( |
547 session_id, new_web_session_id.data(), new_web_session_id.size()); | 561 session_id, web_session_id.data(), web_session_id.size()); |
548 } | 562 } |
549 | 563 |
550 void ClearKeyCdm::OnSessionMessage(uint32 session_id, | 564 void ClearKeyCdm::OnSessionMessage(uint32 session_id, |
551 const std::vector<uint8>& message, | 565 const std::vector<uint8>& message, |
552 const std::string& destination_url) { | 566 const std::string& destination_url) { |
567 DVLOG(1) << "OnSessionMessage: " << message.size(); | |
568 | |
569 // Ignore the message when we are waiting to update the loadable session. | |
570 if (session_id == session_id_for_emulated_loadsession_) | |
571 return; | |
572 | |
553 host_->OnSessionMessage(session_id, | 573 host_->OnSessionMessage(session_id, |
554 reinterpret_cast<const char*>(message.data()), | 574 reinterpret_cast<const char*>(message.data()), |
555 message.size(), | 575 message.size(), |
556 destination_url.data(), | 576 destination_url.data(), |
557 destination_url.size()); | 577 destination_url.size()); |
558 } | 578 } |
559 | 579 |
560 void ClearKeyCdm::OnSessionReady(uint32 session_id) { | 580 void ClearKeyCdm::OnSessionReady(uint32 session_id) { |
581 if (session_id == session_id_for_emulated_loadsession_) { | |
582 session_id_for_emulated_loadsession_ = MediaKeys::kInvalidSessionId; | |
583 host_->OnSessionCreated( | |
584 session_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId)); | |
585 } | |
586 | |
561 host_->OnSessionReady(session_id); | 587 host_->OnSessionReady(session_id); |
562 } | 588 } |
563 | 589 |
564 void ClearKeyCdm::OnSessionClosed(uint32 session_id) { | 590 void ClearKeyCdm::OnSessionClosed(uint32 session_id) { |
565 host_->OnSessionClosed(session_id); | 591 host_->OnSessionClosed(session_id); |
566 } | 592 } |
567 | 593 |
568 void ClearKeyCdm::OnSessionError(uint32 session_id, | 594 void ClearKeyCdm::OnSessionError(uint32 session_id, |
569 media::MediaKeys::KeyError error_code, | 595 media::MediaKeys::KeyError error_code, |
570 int system_code) { | 596 int system_code) { |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
640 | 666 |
641 void ClearKeyCdm::OnFileIOTestComplete(bool success) { | 667 void ClearKeyCdm::OnFileIOTestComplete(bool success) { |
642 DVLOG(1) << __FUNCTION__ << ": " << success; | 668 DVLOG(1) << __FUNCTION__ << ": " << success; |
643 std::string message = GetFileIOTestResultMessage(success); | 669 std::string message = GetFileIOTestResultMessage(success); |
644 host_->OnSessionMessage( | 670 host_->OnSessionMessage( |
645 last_session_id_, message.data(), message.size(), NULL, 0); | 671 last_session_id_, message.data(), message.size(), NULL, 0); |
646 file_io_test_runner_.reset(); | 672 file_io_test_runner_.reset(); |
647 } | 673 } |
648 | 674 |
649 } // namespace media | 675 } // namespace media |
OLD | NEW |