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> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/debug/trace_event.h" | 14 #include "base/debug/trace_event.h" |
15 #include "base/logging.h" | 15 #include "base/logging.h" |
16 #include "base/time/time.h" | 16 #include "base/time/time.h" |
17 #include "media/base/cdm_promise.h" | |
17 #include "media/base/decoder_buffer.h" | 18 #include "media/base/decoder_buffer.h" |
18 #include "media/base/decrypt_config.h" | 19 #include "media/base/decrypt_config.h" |
19 #include "media/cdm/json_web_key.h" | 20 #include "media/cdm/json_web_key.h" |
20 #include "media/cdm/ppapi/cdm_file_io_test.h" | 21 #include "media/cdm/ppapi/cdm_file_io_test.h" |
21 #include "media/cdm/ppapi/external_clear_key/cdm_video_decoder.h" | 22 #include "media/cdm/ppapi/external_clear_key/cdm_video_decoder.h" |
22 | 23 |
23 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | 24 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
24 #include "base/basictypes.h" | 25 #include "base/basictypes.h" |
25 const int64 kNoTimestamp = kint64min; | 26 const int64 kNoTimestamp = kint64min; |
26 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER | 27 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 | 127 |
127 return output_buffer; | 128 return output_buffer; |
128 } | 129 } |
129 | 130 |
130 static std::string GetFileIOTestResultMessage(bool success) { | 131 static std::string GetFileIOTestResultMessage(bool success) { |
131 std::string message(kFileIOTestResultHeader); | 132 std::string message(kFileIOTestResultHeader); |
132 message += success ? '1' : '0'; | 133 message += success ? '1' : '0'; |
133 return message; | 134 return message; |
134 } | 135 } |
135 | 136 |
137 static cdm::Error ConvertException(media::MediaKeys::Exception exception_code) { | |
138 switch (exception_code) { | |
139 case media::MediaKeys::NOT_SUPPORTED_ERROR: | |
140 return cdm::kNotSupportedError; | |
141 case media::MediaKeys::INVALID_STATE_ERROR: | |
142 return cdm::kInvalidStateError; | |
143 case media::MediaKeys::INVALID_ACCESS_ERROR: | |
144 return cdm::kInvalidAccessError; | |
145 case media::MediaKeys::QUOTA_EXCEEDED_ERROR: | |
146 return cdm::kQuotaExceededError; | |
147 case media::MediaKeys::UNKNOWN_ERROR: | |
148 return cdm::kUnknownError; | |
149 case media::MediaKeys::CLIENT_ERROR: | |
150 return cdm::kClientError; | |
151 case media::MediaKeys::OUTPUT_ERROR: | |
152 return cdm::kOutputError; | |
153 } | |
154 } | |
155 | |
156 static media::MediaKeys::SessionType ConvertSessionType( | |
157 cdm::SessionType session_type) { | |
158 switch (session_type) { | |
159 case cdm::kPersistent: | |
160 return media::MediaKeys::PERSISTENT_SESSION; | |
161 case cdm::kTemporary: | |
162 return media::MediaKeys::TEMPORARY_SESSION; | |
163 } | |
164 } | |
165 | |
136 template<typename Type> | 166 template<typename Type> |
137 class ScopedResetter { | 167 class ScopedResetter { |
138 public: | 168 public: |
139 explicit ScopedResetter(Type* object) : object_(object) {} | 169 explicit ScopedResetter(Type* object) : object_(object) {} |
140 ~ScopedResetter() { object_->Reset(); } | 170 ~ScopedResetter() { object_->Reset(); } |
141 | 171 |
142 private: | 172 private: |
143 Type* const object_; | 173 Type* const object_; |
144 }; | 174 }; |
145 | 175 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
180 } | 210 } |
181 | 211 |
182 const char* GetCdmVersion() { | 212 const char* GetCdmVersion() { |
183 return kClearKeyCdmVersion; | 213 return kClearKeyCdmVersion; |
184 } | 214 } |
185 | 215 |
186 namespace media { | 216 namespace media { |
187 | 217 |
188 ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system) | 218 ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system) |
189 : decryptor_( | 219 : decryptor_( |
190 base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this)), | 220 base::Bind(&ClearKeyCdm::OnSessionMessage, base::Unretained(this))), |
191 base::Bind(&ClearKeyCdm::OnSessionMessage, base::Unretained(this)), | |
192 base::Bind(&ClearKeyCdm::OnSessionReady, base::Unretained(this)), | |
193 base::Bind(&ClearKeyCdm::OnSessionClosed, base::Unretained(this)), | |
194 base::Bind(&ClearKeyCdm::OnSessionError, base::Unretained(this))), | |
195 host_(host), | 221 host_(host), |
196 key_system_(key_system), | 222 key_system_(key_system), |
197 last_session_id_(MediaKeys::kInvalidSessionId), | |
198 session_id_for_emulated_loadsession_(MediaKeys::kInvalidSessionId), | |
199 timer_delay_ms_(kInitialTimerDelayMs), | 223 timer_delay_ms_(kInitialTimerDelayMs), |
200 heartbeat_timer_set_(false) { | 224 heartbeat_timer_set_(false) { |
201 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | 225 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
202 channel_count_ = 0; | 226 channel_count_ = 0; |
203 bits_per_channel_ = 0; | 227 bits_per_channel_ = 0; |
204 samples_per_second_ = 0; | 228 samples_per_second_ = 0; |
205 output_timestamp_base_in_microseconds_ = kNoTimestamp; | 229 output_timestamp_base_in_microseconds_ = kNoTimestamp; |
206 total_samples_generated_ = 0; | 230 total_samples_generated_ = 0; |
207 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER | 231 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER |
208 } | 232 } |
209 | 233 |
210 ClearKeyCdm::~ClearKeyCdm() {} | 234 ClearKeyCdm::~ClearKeyCdm() {} |
211 | 235 |
212 void ClearKeyCdm::CreateSession(uint32 session_id, | 236 void ClearKeyCdm::CreateSession(uint32 promise_id, |
213 const char* type, | 237 const char* init_data_type, |
214 uint32 type_size, | 238 uint32 init_data_type_size, |
215 const uint8* init_data, | 239 const uint8* init_data, |
216 uint32 init_data_size) { | 240 uint32 init_data_size, |
241 cdm::SessionType session_type) { | |
217 DVLOG(1) << __FUNCTION__; | 242 DVLOG(1) << __FUNCTION__; |
218 decryptor_.CreateSession( | |
219 session_id, std::string(type, type_size), init_data, init_data_size); | |
220 | 243 |
221 // Save the latest session ID for heartbeat and file IO test messages. | 244 scoped_ptr<media::NewSessionCdmPromise> promise( |
222 last_session_id_ = session_id; | 245 new media::NewSessionCdmPromise( |
246 base::Bind(&ClearKeyCdm::OnSessionCreated, | |
247 base::Unretained(this), | |
248 promise_id), | |
249 base::Bind(&ClearKeyCdm::OnSessionCreateFailed, | |
250 base::Unretained(this), | |
251 promise_id))); | |
252 decryptor_.CreateSession(std::string(init_data_type, init_data_type_size), | |
253 init_data, | |
254 init_data_size, | |
255 ConvertSessionType(session_type), | |
256 promise.Pass()); | |
223 | 257 |
224 if (key_system_ == kExternalClearKeyFileIOTestKeySystem) | 258 if (key_system_ == kExternalClearKeyFileIOTestKeySystem) |
225 StartFileIOTest(); | 259 StartFileIOTest(); |
226 } | 260 } |
227 | 261 |
228 // Loads a emulated stored session. Currently only |kLoadableWebSessionId| | 262 // Loads a emulated stored session. Currently only |kLoadableWebSessionId| |
229 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is | 263 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is |
230 // supported. | 264 // supported. |
231 void ClearKeyCdm::LoadSession(uint32_t session_id, | 265 void ClearKeyCdm::LoadSession(uint32 promise_id, |
232 const char* web_session_id, | 266 const char* web_session_id, |
233 uint32_t web_session_id_length) { | 267 uint32_t web_session_id_length) { |
234 DVLOG(1) << __FUNCTION__; | 268 DVLOG(1) << __FUNCTION__; |
235 | 269 |
236 if (std::string(kLoadableWebSessionId) != | 270 if (std::string(kLoadableWebSessionId) != |
237 std::string(web_session_id, web_session_id_length)) { | 271 std::string(web_session_id, web_session_id_length)) { |
238 // TODO(xhwang): Report "NotFoundError" when we support DOMError style. | 272 std::string message("Incorrect session id specified for LoadSession()."); |
239 OnSessionError(session_id, MediaKeys::kUnknownError, 0); | 273 host_->OnRejectPromise(promise_id, |
274 cdm::kInvalidAccessError, | |
275 0, | |
276 message.data(), | |
277 message.length()); | |
240 return; | 278 return; |
241 } | 279 } |
242 | 280 |
243 session_id_for_emulated_loadsession_ = session_id; | 281 scoped_ptr<media::NewSessionCdmPromise> promise( |
244 | 282 new media::NewSessionCdmPromise( |
245 decryptor_.CreateSession(session_id, kLoadableSessionContentType, NULL, 0); | 283 base::Bind(&ClearKeyCdm::OnSessionLoaded, |
284 base::Unretained(this), | |
285 promise_id), | |
286 base::Bind(&ClearKeyCdm::OnSessionLoadFailed, | |
287 base::Unretained(this), | |
288 promise_id))); | |
289 decryptor_.CreateSession(std::string(kLoadableSessionContentType), | |
290 NULL, | |
291 0, | |
292 MediaKeys::TEMPORARY_SESSION, | |
293 promise.Pass()); | |
246 } | 294 } |
247 | 295 |
248 void ClearKeyCdm::UpdateSession(uint32 session_id, | 296 void ClearKeyCdm::UpdateSession(uint32 promise_id, |
297 const char* web_session_id, | |
298 uint32_t web_session_id_size, | |
249 const uint8* response, | 299 const uint8* response, |
250 uint32 response_size) { | 300 uint32 response_size) { |
251 DVLOG(1) << __FUNCTION__; | 301 DVLOG(1) << __FUNCTION__; |
252 decryptor_.UpdateSession(session_id, response, response_size); | 302 std::string web_session_str(web_session_id, web_session_id_size); |
303 | |
304 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( | |
305 base::Bind(&ClearKeyCdm::OnSessionUpdated, | |
306 base::Unretained(this), | |
307 promise_id, | |
308 web_session_str), | |
309 base::Bind(&ClearKeyCdm::OnSessionUpdateFailed, | |
310 base::Unretained(this), | |
311 promise_id))); | |
312 decryptor_.UpdateSession( | |
313 web_session_str, response, response_size, promise.Pass()); | |
253 | 314 |
254 if (!heartbeat_timer_set_) { | 315 if (!heartbeat_timer_set_) { |
255 ScheduleNextHeartBeat(); | 316 ScheduleNextHeartBeat(); |
256 heartbeat_timer_set_ = true; | 317 heartbeat_timer_set_ = true; |
257 } | 318 } |
258 } | 319 } |
259 | 320 |
260 void ClearKeyCdm::ReleaseSession(uint32 session_id) { | 321 void ClearKeyCdm::ReleaseSession(uint32 promise_id, |
322 const char* web_session_id, | |
323 uint32_t web_session_id_size) { | |
261 DVLOG(1) << __FUNCTION__; | 324 DVLOG(1) << __FUNCTION__; |
262 decryptor_.ReleaseSession(session_id); | 325 std::string web_session_str(web_session_id, web_session_id_size); |
326 | |
327 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( | |
328 base::Bind(&ClearKeyCdm::OnSessionReleased, | |
329 base::Unretained(this), | |
330 promise_id, | |
331 web_session_str), | |
332 base::Bind(&ClearKeyCdm::OnSessionReleaseFailed, | |
333 base::Unretained(this), | |
334 promise_id))); | |
335 decryptor_.ReleaseSession(web_session_str, promise.Pass()); | |
336 } | |
337 | |
338 void ClearKeyCdm::SetServerCertificate(uint32 promise_id, | |
339 const uint8_t* server_certificate_data, | |
340 uint32_t server_certificate_data_size) { | |
341 // ClearKey doesn't use a server certificate. | |
342 host_->OnResolvePromise(promise_id); | |
263 } | 343 } |
264 | 344 |
265 void ClearKeyCdm::TimerExpired(void* context) { | 345 void ClearKeyCdm::TimerExpired(void* context) { |
266 if (context == &session_id_for_emulated_loadsession_) { | 346 if (context == &session_id_for_emulated_loadsession_) { |
267 LoadLoadableSession(); | 347 LoadLoadableSession(); |
268 return; | 348 return; |
269 } | 349 } |
270 | 350 |
271 DCHECK(heartbeat_timer_set_); | 351 DCHECK(heartbeat_timer_set_); |
272 std::string heartbeat_message; | 352 std::string heartbeat_message; |
273 if (!next_heartbeat_message_.empty() && | 353 if (!next_heartbeat_message_.empty() && |
274 context == &next_heartbeat_message_[0]) { | 354 context == &next_heartbeat_message_[0]) { |
275 heartbeat_message = next_heartbeat_message_; | 355 heartbeat_message = next_heartbeat_message_; |
276 } else { | 356 } else { |
277 heartbeat_message = "ERROR: Invalid timer context found!"; | 357 heartbeat_message = "ERROR: Invalid timer context found!"; |
278 } | 358 } |
279 | 359 |
280 // This URL is only used for testing the code path for defaultURL. | 360 // This URL is only used for testing the code path for defaultURL. |
281 // There is no service at this URL, so applications should ignore it. | 361 // There is no service at this URL, so applications should ignore it. |
282 const char url[] = "http://test.externalclearkey.chromium.org"; | 362 const char url[] = "http://test.externalclearkey.chromium.org"; |
283 | 363 |
284 host_->OnSessionMessage(last_session_id_, | 364 host_->OnSessionMessage(last_session_id_.data(), |
365 last_session_id_.length(), | |
285 heartbeat_message.data(), | 366 heartbeat_message.data(), |
286 heartbeat_message.size(), | 367 heartbeat_message.length(), |
287 url, | 368 url, |
288 arraysize(url) - 1); | 369 arraysize(url) - 1); |
289 | 370 |
290 ScheduleNextHeartBeat(); | 371 ScheduleNextHeartBeat(); |
291 } | 372 } |
292 | 373 |
293 static void CopyDecryptResults( | 374 static void CopyDecryptResults( |
294 media::Decryptor::Status* status_copy, | 375 media::Decryptor::Status* status_copy, |
295 scoped_refptr<media::DecoderBuffer>* buffer_copy, | 376 scoped_refptr<media::DecoderBuffer>* buffer_copy, |
296 media::Decryptor::Status status, | 377 media::Decryptor::Status status, |
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
469 | 550 |
470 void ClearKeyCdm::Destroy() { | 551 void ClearKeyCdm::Destroy() { |
471 DVLOG(1) << "Destroy()"; | 552 DVLOG(1) << "Destroy()"; |
472 delete this; | 553 delete this; |
473 } | 554 } |
474 | 555 |
475 void ClearKeyCdm::ScheduleNextHeartBeat() { | 556 void ClearKeyCdm::ScheduleNextHeartBeat() { |
476 // Prepare the next heartbeat message and set timer. | 557 // Prepare the next heartbeat message and set timer. |
477 std::ostringstream msg_stream; | 558 std::ostringstream msg_stream; |
478 msg_stream << kHeartBeatHeader << " from ClearKey CDM set at time " | 559 msg_stream << kHeartBeatHeader << " from ClearKey CDM set at time " |
479 << host_->GetCurrentWallTimeInSeconds() << "."; | 560 << host_->GetCurrentTime() << "."; |
480 next_heartbeat_message_ = msg_stream.str(); | 561 next_heartbeat_message_ = msg_stream.str(); |
481 | 562 |
482 host_->SetTimer(timer_delay_ms_, &next_heartbeat_message_[0]); | 563 host_->SetTimer(timer_delay_ms_, &next_heartbeat_message_[0]); |
483 | 564 |
484 // Use a smaller timer delay at start-up to facilitate testing. Increase the | 565 // Use a smaller timer delay at start-up to facilitate testing. Increase the |
485 // timer delay up to a limit to avoid message spam. | 566 // timer delay up to a limit to avoid message spam. |
486 if (timer_delay_ms_ < kMaxTimerDelayMs) | 567 if (timer_delay_ms_ < kMaxTimerDelayMs) |
487 timer_delay_ms_ = std::min(2 * timer_delay_ms_, kMaxTimerDelayMs); | 568 timer_delay_ms_ = std::min(2 * timer_delay_ms_, kMaxTimerDelayMs); |
488 } | 569 } |
489 | 570 |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
528 NOTIMPLEMENTED(); | 609 NOTIMPLEMENTED(); |
529 }; | 610 }; |
530 | 611 |
531 void ClearKeyCdm::LoadLoadableSession() { | 612 void ClearKeyCdm::LoadLoadableSession() { |
532 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey, | 613 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey, |
533 sizeof(kLoadableSessionKey), | 614 sizeof(kLoadableSessionKey), |
534 kLoadableSessionKeyId, | 615 kLoadableSessionKeyId, |
535 sizeof(kLoadableSessionKeyId) - 1); | 616 sizeof(kLoadableSessionKeyId) - 1); |
536 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support, | 617 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support, |
537 // this is okay. Check WD EME support. | 618 // this is okay. Check WD EME support. |
619 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise( | |
620 base::Bind(&ClearKeyCdm::OnSessionUpdated, | |
621 base::Unretained(this), | |
622 promise_id_for_emulated_loadsession_, | |
623 session_id_for_emulated_loadsession_), | |
624 base::Bind(&ClearKeyCdm::OnSessionUpdateFailed, | |
625 base::Unretained(this), | |
626 promise_id_for_emulated_loadsession_))); | |
538 decryptor_.UpdateSession(session_id_for_emulated_loadsession_, | 627 decryptor_.UpdateSession(session_id_for_emulated_loadsession_, |
539 reinterpret_cast<const uint8*>(jwk_set.data()), | 628 reinterpret_cast<const uint8*>(jwk_set.data()), |
540 jwk_set.size()); | 629 jwk_set.size(), |
630 promise.Pass()); | |
541 } | 631 } |
542 | 632 |
543 void ClearKeyCdm::OnSessionCreated(uint32 session_id, | 633 void ClearKeyCdm::OnSessionMessage(const std::string& web_session_id, |
544 const std::string& web_session_id) { | |
545 std::string new_web_session_id = web_session_id; | |
546 | |
547 if (session_id == session_id_for_emulated_loadsession_) { | |
548 // Delay LoadLoadableSession() to test the case where Decrypt*() calls are | |
549 // made before the session is fully loaded. | |
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. | |
556 return; | |
557 } | |
558 | |
559 host_->OnSessionCreated( | |
560 session_id, web_session_id.data(), web_session_id.size()); | |
561 } | |
562 | |
563 void ClearKeyCdm::OnSessionMessage(uint32 session_id, | |
564 const std::vector<uint8>& message, | 634 const std::vector<uint8>& message, |
565 const GURL& destination_url) { | 635 const GURL& destination_url) { |
566 DVLOG(1) << "OnSessionMessage: " << message.size(); | 636 DVLOG(1) << "OnSessionMessage: " << message.size(); |
567 | 637 |
568 // Ignore the message when we are waiting to update the loadable session. | 638 // Ignore the message when we are waiting to update the loadable session. |
569 if (session_id == session_id_for_emulated_loadsession_) | 639 if (web_session_id == session_id_for_emulated_loadsession_) |
570 return; | 640 return; |
571 | 641 |
572 host_->OnSessionMessage(session_id, | 642 // OnSessionMessage() only called during CreateSession(), so no promise |
643 // involved (OnSessionCreated() called to resolve the CreateSession() | |
644 // promise). | |
645 host_->OnSessionMessage(web_session_id.data(), | |
646 web_session_id.length(), | |
573 reinterpret_cast<const char*>(message.data()), | 647 reinterpret_cast<const char*>(message.data()), |
574 message.size(), | 648 message.size(), |
575 destination_url.spec().data(), | 649 destination_url.spec().data(), |
576 destination_url.spec().size()); | 650 destination_url.spec().size()); |
577 } | 651 } |
578 | 652 |
579 void ClearKeyCdm::OnSessionReady(uint32 session_id) { | 653 void ClearKeyCdm::OnSessionCreated(uint32 promise_id, |
580 if (session_id == session_id_for_emulated_loadsession_) { | 654 const std::string& web_session_id) { |
581 session_id_for_emulated_loadsession_ = MediaKeys::kInvalidSessionId; | 655 // Save the latest session ID for heartbeat and file IO test messages. |
582 host_->OnSessionCreated( | 656 last_session_id_ = web_session_id; |
583 session_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId)); | 657 |
658 host_->OnResolveNewSessionPromise( | |
659 promise_id, web_session_id.data(), web_session_id.length()); | |
660 } | |
661 | |
662 void ClearKeyCdm::OnSessionCreateFailed(uint32 promise_id, | |
663 MediaKeys::Exception exception_code, | |
664 uint32 system_code, | |
665 const std::string& error_message) { | |
666 RejectPromise(promise_id, exception_code, system_code, error_message); | |
667 } | |
668 | |
669 void ClearKeyCdm::OnSessionLoaded(uint32 promise_id, | |
670 const std::string& web_session_id) { | |
671 // Save the latest session ID for heartbeat and file IO test messages. | |
672 last_session_id_ = web_session_id; | |
673 | |
674 // |decryptor_| created some session as |web_session_id|, but going forward | |
675 // we need to map that to |kLoadableWebSessionId|, as that is what callers | |
676 // expect. | |
677 session_id_for_emulated_loadsession_ = web_session_id; | |
678 | |
679 // Delay LoadLoadableSession() to test the case where Decrypt*() calls are | |
680 // made before the session is fully loaded. | |
681 const int64 kDelayToLoadSessionMs = 500; | |
682 | |
683 // Defer resolving the promise until the session is loaded. | |
684 promise_id_for_emulated_loadsession_ = promise_id; | |
685 | |
686 // Use the address of |session_id_for_emulated_loadsession_| as the timer | |
687 // context so that we can call LoadLoadableSession() when the timer expires. | |
688 host_->SetTimer(kDelayToLoadSessionMs, &session_id_for_emulated_loadsession_); | |
689 } | |
690 | |
691 void ClearKeyCdm::OnSessionLoadFailed(uint32 promise_id, | |
692 MediaKeys::Exception exception_code, | |
693 uint32 system_code, | |
694 const std::string& error_message) { | |
695 RejectPromise(promise_id, exception_code, system_code, error_message); | |
696 } | |
697 | |
698 void ClearKeyCdm::OnSessionUpdated(uint32 promise_id, | |
699 const std::string& web_session_id) { | |
700 // OnSessionReady() only called as success for UpdateSession(). However, | |
701 // UpdateSession() also called to finish loading sessions, so handle | |
702 // appropriately. | |
703 if (web_session_id == session_id_for_emulated_loadsession_) { | |
704 session_id_for_emulated_loadsession_ = std::string(); | |
705 // |promise_id| is the LoadSession() promise, so resolve appropriately. | |
706 host_->OnResolveNewSessionPromise( | |
707 promise_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId)); | |
708 host_->OnSessionReady(kLoadableWebSessionId, strlen(kLoadableWebSessionId)); | |
709 return; | |
584 } | 710 } |
585 | 711 |
586 host_->OnSessionReady(session_id); | 712 host_->OnResolvePromise(promise_id); |
587 } | 713 } |
588 | 714 |
589 void ClearKeyCdm::OnSessionClosed(uint32 session_id) { | 715 void ClearKeyCdm::OnSessionUpdateFailed(uint32 promise_id, |
590 host_->OnSessionClosed(session_id); | 716 MediaKeys::Exception exception_code, |
717 uint32 system_code, | |
718 const std::string& error_message) { | |
719 RejectPromise(promise_id, exception_code, system_code, error_message); | |
591 } | 720 } |
592 | 721 |
593 void ClearKeyCdm::OnSessionError(uint32 session_id, | 722 void ClearKeyCdm::OnSessionReleased(uint32 promise_id, |
594 media::MediaKeys::KeyError error_code, | 723 const std::string& web_session_id) { |
595 uint32 system_code) { | 724 host_->OnResolvePromise(promise_id); |
596 host_->OnSessionError( | 725 } |
597 session_id, static_cast<cdm::MediaKeyError>(error_code), system_code); | 726 |
727 void ClearKeyCdm::OnSessionReleaseFailed(uint32 promise_id, | |
728 MediaKeys::Exception exception_code, | |
729 uint32 system_code, | |
730 const std::string& error_message) { | |
731 RejectPromise(promise_id, exception_code, system_code, error_message); | |
732 } | |
dmichael (off chromium)
2014/06/05 18:55:30
You have 4 methods that look just like this... it
jrummell
2014/06/05 20:59:54
Not needed anymore. Combined into 1 method.
| |
733 | |
734 void ClearKeyCdm::RejectPromise(uint32 promise_id, | |
735 MediaKeys::Exception exception_code, | |
736 uint32 system_code, | |
737 const std::string& error_message) { | |
738 host_->OnRejectPromise(promise_id, | |
739 ConvertException(exception_code), | |
740 system_code, | |
741 error_message.data(), | |
742 error_message.length()); | |
598 } | 743 } |
599 | 744 |
600 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) | 745 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) |
601 int64 ClearKeyCdm::CurrentTimeStampInMicroseconds() const { | 746 int64 ClearKeyCdm::CurrentTimeStampInMicroseconds() const { |
602 return output_timestamp_base_in_microseconds_ + | 747 return output_timestamp_base_in_microseconds_ + |
603 base::Time::kMicrosecondsPerSecond * | 748 base::Time::kMicrosecondsPerSecond * |
604 total_samples_generated_ / samples_per_second_; | 749 total_samples_generated_ / samples_per_second_; |
605 } | 750 } |
606 | 751 |
607 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration( | 752 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration( |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
659 void ClearKeyCdm::StartFileIOTest() { | 804 void ClearKeyCdm::StartFileIOTest() { |
660 file_io_test_runner_.reset(new FileIOTestRunner( | 805 file_io_test_runner_.reset(new FileIOTestRunner( |
661 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_)))); | 806 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_)))); |
662 file_io_test_runner_->RunAllTests( | 807 file_io_test_runner_->RunAllTests( |
663 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this))); | 808 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this))); |
664 } | 809 } |
665 | 810 |
666 void ClearKeyCdm::OnFileIOTestComplete(bool success) { | 811 void ClearKeyCdm::OnFileIOTestComplete(bool success) { |
667 DVLOG(1) << __FUNCTION__ << ": " << success; | 812 DVLOG(1) << __FUNCTION__ << ": " << success; |
668 std::string message = GetFileIOTestResultMessage(success); | 813 std::string message = GetFileIOTestResultMessage(success); |
669 host_->OnSessionMessage( | 814 host_->OnSessionMessage(last_session_id_.data(), |
670 last_session_id_, message.data(), message.size(), NULL, 0); | 815 last_session_id_.length(), |
816 message.data(), | |
817 message.length(), | |
818 NULL, | |
819 0); | |
671 file_io_test_runner_.reset(); | 820 file_io_test_runner_.reset(); |
672 } | 821 } |
673 | 822 |
674 } // namespace media | 823 } // namespace media |
OLD | NEW |