Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: media/cdm/ppapi/external_clear_key/clear_key_cdm.cc

Issue 265993002: Add Promises for EME (Chromium side) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: updates Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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::EXCEPTION_NO_MODIFICATION_ALLOWED_ERROR:
140 return cdm::kNoModificationAllowedError;
141 case media::MediaKeys::EXCEPTION_NOT_FOUND_ERROR:
142 return cdm::kNotFoundError;
143 case media::MediaKeys::EXCEPTION_NOT_SUPPORTED_ERROR:
144 return cdm::kNotSupportedError;
145 case media::MediaKeys::EXCEPTION_INVALID_STATE_ERROR:
146 return cdm::kInvalidStateError;
147 case media::MediaKeys::EXCEPTION_SYNTAX_ERROR:
148 return cdm::kSyntaxError;
149 case media::MediaKeys::EXCEPTION_INVALID_MODIFICATION_ERROR:
150 return cdm::kInvalidModificationError;
151 case media::MediaKeys::EXCEPTION_INVALID_ACCESS_ERROR:
152 return cdm::kInvalidAccessError;
153 case media::MediaKeys::EXCEPTION_SECURITY_ERROR:
154 return cdm::kSecurityError;
155 case media::MediaKeys::EXCEPTION_ABORT_ERROR:
156 return cdm::kAbortError;
157 case media::MediaKeys::EXCEPTION_QUOTA_EXCEEDED_ERROR:
158 return cdm::kQuotaExceededError;
159 case media::MediaKeys::EXCEPTION_TIMEOUT_ERROR:
160 return cdm::kTimeoutError;
161 case media::MediaKeys::EXCEPTION_NOT_READABLE_ERROR:
162 return cdm::kNotReadableError;
163 case media::MediaKeys::EXCEPTION_DATA_ERROR:
164 return cdm::kDataError;
165 case media::MediaKeys::EXCEPTION_OPERATION_ERROR:
166 return cdm::kOperationError;
167 case media::MediaKeys::EXCEPTION_VERSION_ERROR:
168 return cdm::kVersionError;
169 case media::MediaKeys::EXCEPTION_UNKNOWN_ERROR:
170 return cdm::kUnknownError;
171 case media::MediaKeys::EXCEPTION_CLIENT_ERROR:
172 return cdm::kClientError;
173 case media::MediaKeys::EXCEPTION_OUTPUT_ERROR:
174 return cdm::kOutputError;
175 }
176 }
177
178 static media::MediaKeys::SessionType ConvertSessionType(
179 cdm::SessionType session_type) {
180 switch (session_type) {
181 case cdm::kPersistent:
182 return media::MediaKeys::SESSION_TYPE_PERSISTENT;
183 case cdm::kTemporary:
184 return media::MediaKeys::SESSION_TYPE_TEMPORARY;
185 }
186 }
187
136 template<typename Type> 188 template<typename Type>
137 class ScopedResetter { 189 class ScopedResetter {
138 public: 190 public:
139 explicit ScopedResetter(Type* object) : object_(object) {} 191 explicit ScopedResetter(Type* object) : object_(object) {}
140 ~ScopedResetter() { object_->Reset(); } 192 ~ScopedResetter() { object_->Reset(); }
141 193
142 private: 194 private:
143 Type* const object_; 195 Type* const object_;
144 }; 196 };
145 197
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 } 232 }
181 233
182 const char* GetCdmVersion() { 234 const char* GetCdmVersion() {
183 return kClearKeyCdmVersion; 235 return kClearKeyCdmVersion;
184 } 236 }
185 237
186 namespace media { 238 namespace media {
187 239
188 ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system) 240 ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system)
189 : decryptor_( 241 : decryptor_(
190 base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this)), 242 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), 243 host_(host),
196 key_system_(key_system), 244 key_system_(key_system),
197 last_session_id_(MediaKeys::kInvalidSessionId),
198 session_id_for_emulated_loadsession_(MediaKeys::kInvalidSessionId),
199 timer_delay_ms_(kInitialTimerDelayMs), 245 timer_delay_ms_(kInitialTimerDelayMs),
200 heartbeat_timer_set_(false) { 246 heartbeat_timer_set_(false) {
201 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 247 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
202 channel_count_ = 0; 248 channel_count_ = 0;
203 bits_per_channel_ = 0; 249 bits_per_channel_ = 0;
204 samples_per_second_ = 0; 250 samples_per_second_ = 0;
205 output_timestamp_base_in_microseconds_ = kNoTimestamp; 251 output_timestamp_base_in_microseconds_ = kNoTimestamp;
206 total_samples_generated_ = 0; 252 total_samples_generated_ = 0;
207 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 253 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
208 } 254 }
209 255
210 ClearKeyCdm::~ClearKeyCdm() {} 256 ClearKeyCdm::~ClearKeyCdm() {}
211 257
212 void ClearKeyCdm::CreateSession(uint32 session_id, 258 void ClearKeyCdm::CreateSession(uint32 promise_id,
213 const char* type, 259 const char* init_data_type,
214 uint32 type_size, 260 uint32 init_data_type_size,
215 const uint8* init_data, 261 const uint8* init_data,
216 uint32 init_data_size) { 262 uint32 init_data_size,
263 cdm::SessionType session_type) {
217 DVLOG(1) << __FUNCTION__; 264 DVLOG(1) << __FUNCTION__;
218 decryptor_.CreateSession(
219 session_id, std::string(type, type_size), init_data, init_data_size);
220 265
221 // Save the latest session ID for heartbeat and file IO test messages. 266 scoped_ptr<media::NewSessionCdmPromise> promise(
222 last_session_id_ = session_id; 267 new media::NewSessionCdmPromise(
268 base::Bind(&ClearKeyCdm::OnSessionCreated,
269 base::Unretained(this),
270 promise_id),
271 base::Bind(&ClearKeyCdm::OnSessionCreateFailed,
272 base::Unretained(this),
273 promise_id)));
274 decryptor_.CreateSession(std::string(init_data_type, init_data_type_size),
275 init_data,
276 init_data_size,
277 ConvertSessionType(session_type),
278 promise.Pass());
223 279
224 if (key_system_ == kExternalClearKeyFileIOTestKeySystem) 280 if (key_system_ == kExternalClearKeyFileIOTestKeySystem)
225 StartFileIOTest(); 281 StartFileIOTest();
226 } 282 }
227 283
228 // Loads a emulated stored session. Currently only |kLoadableWebSessionId| 284 // Loads a emulated stored session. Currently only |kLoadableWebSessionId|
229 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is 285 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is
230 // supported. 286 // supported.
231 void ClearKeyCdm::LoadSession(uint32_t session_id, 287 void ClearKeyCdm::LoadSession(uint32 promise_id,
232 const char* web_session_id, 288 const char* web_session_id,
233 uint32_t web_session_id_length) { 289 uint32_t web_session_id_length) {
234 DVLOG(1) << __FUNCTION__; 290 DVLOG(1) << __FUNCTION__;
235 291
236 if (std::string(kLoadableWebSessionId) != 292 if (std::string(kLoadableWebSessionId) !=
237 std::string(web_session_id, web_session_id_length)) { 293 std::string(web_session_id, web_session_id_length)) {
238 // TODO(xhwang): Report "NotFoundError" when we support DOMError style. 294 std::string message("Incorrect session id specified for LoadSession().");
239 OnSessionError(session_id, MediaKeys::kUnknownError, 0); 295 host_->OnRejectPromise(
296 promise_id, cdm::kNotFoundError, 0, message.data(), message.length());
240 return; 297 return;
241 } 298 }
242 299
243 session_id_for_emulated_loadsession_ = session_id; 300 scoped_ptr<media::NewSessionCdmPromise> promise(
244 301 new media::NewSessionCdmPromise(
245 decryptor_.CreateSession(session_id, kLoadableSessionContentType, NULL, 0); 302 base::Bind(&ClearKeyCdm::OnSessionLoaded,
303 base::Unretained(this),
304 promise_id),
305 base::Bind(&ClearKeyCdm::OnSessionLoadFailed,
306 base::Unretained(this),
307 promise_id)));
308 decryptor_.CreateSession(std::string(kLoadableSessionContentType),
309 NULL,
310 0,
311 MediaKeys::SESSION_TYPE_TEMPORARY,
312 promise.Pass());
246 } 313 }
247 314
248 void ClearKeyCdm::UpdateSession(uint32 session_id, 315 void ClearKeyCdm::UpdateSession(uint32 promise_id,
316 const char* web_session_id,
317 uint32_t web_session_id_size,
249 const uint8* response, 318 const uint8* response,
250 uint32 response_size) { 319 uint32 response_size) {
251 DVLOG(1) << __FUNCTION__; 320 DVLOG(1) << __FUNCTION__;
252 decryptor_.UpdateSession(session_id, response, response_size); 321 std::string web_session_str(web_session_id, web_session_id_size);
322
323 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise(
324 base::Bind(&ClearKeyCdm::OnSessionUpdated,
325 base::Unretained(this),
326 promise_id,
327 web_session_str),
328 base::Bind(&ClearKeyCdm::OnSessionUpdateFailed,
329 base::Unretained(this),
330 promise_id)));
331 decryptor_.UpdateSession(
332 web_session_str, response, response_size, promise.Pass());
253 333
254 if (!heartbeat_timer_set_) { 334 if (!heartbeat_timer_set_) {
255 ScheduleNextHeartBeat(); 335 ScheduleNextHeartBeat();
256 heartbeat_timer_set_ = true; 336 heartbeat_timer_set_ = true;
257 } 337 }
258 } 338 }
259 339
260 void ClearKeyCdm::ReleaseSession(uint32 session_id) { 340 void ClearKeyCdm::ReleaseSession(uint32 promise_id,
341 const char* web_session_id,
342 uint32_t web_session_id_size) {
261 DVLOG(1) << __FUNCTION__; 343 DVLOG(1) << __FUNCTION__;
262 decryptor_.ReleaseSession(session_id); 344 std::string web_session_str(web_session_id, web_session_id_size);
345
346 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise(
347 base::Bind(&ClearKeyCdm::OnSessionReleased,
348 base::Unretained(this),
349 promise_id,
350 web_session_str),
351 base::Bind(&ClearKeyCdm::OnSessionReleaseFailed,
352 base::Unretained(this),
353 promise_id)));
354 decryptor_.ReleaseSession(web_session_str, promise.Pass());
355 }
356
357 void ClearKeyCdm::SetServerCertificate(uint32 promise_id,
358 const uint8_t* server_certificate_data,
359 uint32_t server_certificate_data_size) {
360 // ClearKey doesn't use a server certificate.
361 host_->OnResolvePromise(promise_id);
263 } 362 }
264 363
265 void ClearKeyCdm::TimerExpired(void* context) { 364 void ClearKeyCdm::TimerExpired(void* context) {
266 if (context == &session_id_for_emulated_loadsession_) { 365 if (context == &session_id_for_emulated_loadsession_) {
267 LoadLoadableSession(); 366 LoadLoadableSession();
268 return; 367 return;
269 } 368 }
270 369
271 DCHECK(heartbeat_timer_set_); 370 DCHECK(heartbeat_timer_set_);
272 std::string heartbeat_message; 371 std::string heartbeat_message;
273 if (!next_heartbeat_message_.empty() && 372 if (!next_heartbeat_message_.empty() &&
274 context == &next_heartbeat_message_[0]) { 373 context == &next_heartbeat_message_[0]) {
275 heartbeat_message = next_heartbeat_message_; 374 heartbeat_message = next_heartbeat_message_;
276 } else { 375 } else {
277 heartbeat_message = "ERROR: Invalid timer context found!"; 376 heartbeat_message = "ERROR: Invalid timer context found!";
278 } 377 }
279 378
280 // This URL is only used for testing the code path for defaultURL. 379 // 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. 380 // There is no service at this URL, so applications should ignore it.
282 const char url[] = "http://test.externalclearkey.chromium.org"; 381 const char url[] = "http://test.externalclearkey.chromium.org";
283 382
284 host_->OnSessionMessage(last_session_id_, 383 host_->OnSessionMessage(last_session_id_.data(),
384 last_session_id_.length(),
285 heartbeat_message.data(), 385 heartbeat_message.data(),
286 heartbeat_message.size(), 386 heartbeat_message.length(),
287 url, 387 url,
288 arraysize(url) - 1); 388 arraysize(url) - 1);
289 389
290 ScheduleNextHeartBeat(); 390 ScheduleNextHeartBeat();
291 } 391 }
292 392
293 static void CopyDecryptResults( 393 static void CopyDecryptResults(
294 media::Decryptor::Status* status_copy, 394 media::Decryptor::Status* status_copy,
295 scoped_refptr<media::DecoderBuffer>* buffer_copy, 395 scoped_refptr<media::DecoderBuffer>* buffer_copy,
296 media::Decryptor::Status status, 396 media::Decryptor::Status status,
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 569
470 void ClearKeyCdm::Destroy() { 570 void ClearKeyCdm::Destroy() {
471 DVLOG(1) << "Destroy()"; 571 DVLOG(1) << "Destroy()";
472 delete this; 572 delete this;
473 } 573 }
474 574
475 void ClearKeyCdm::ScheduleNextHeartBeat() { 575 void ClearKeyCdm::ScheduleNextHeartBeat() {
476 // Prepare the next heartbeat message and set timer. 576 // Prepare the next heartbeat message and set timer.
477 std::ostringstream msg_stream; 577 std::ostringstream msg_stream;
478 msg_stream << kHeartBeatHeader << " from ClearKey CDM set at time " 578 msg_stream << kHeartBeatHeader << " from ClearKey CDM set at time "
479 << host_->GetCurrentWallTimeInSeconds() << "."; 579 << host_->GetCurrentTime() << ".";
480 next_heartbeat_message_ = msg_stream.str(); 580 next_heartbeat_message_ = msg_stream.str();
481 581
482 host_->SetTimer(timer_delay_ms_, &next_heartbeat_message_[0]); 582 host_->SetTimer(timer_delay_ms_, &next_heartbeat_message_[0]);
483 583
484 // Use a smaller timer delay at start-up to facilitate testing. Increase the 584 // Use a smaller timer delay at start-up to facilitate testing. Increase the
485 // timer delay up to a limit to avoid message spam. 585 // timer delay up to a limit to avoid message spam.
486 if (timer_delay_ms_ < kMaxTimerDelayMs) 586 if (timer_delay_ms_ < kMaxTimerDelayMs)
487 timer_delay_ms_ = std::min(2 * timer_delay_ms_, kMaxTimerDelayMs); 587 timer_delay_ms_ = std::min(2 * timer_delay_ms_, kMaxTimerDelayMs);
488 } 588 }
489 589
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 NOTIMPLEMENTED(); 628 NOTIMPLEMENTED();
529 }; 629 };
530 630
531 void ClearKeyCdm::LoadLoadableSession() { 631 void ClearKeyCdm::LoadLoadableSession() {
532 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey, 632 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey,
533 sizeof(kLoadableSessionKey), 633 sizeof(kLoadableSessionKey),
534 kLoadableSessionKeyId, 634 kLoadableSessionKeyId,
535 sizeof(kLoadableSessionKeyId) - 1); 635 sizeof(kLoadableSessionKeyId) - 1);
536 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support, 636 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support,
537 // this is okay. Check WD EME support. 637 // this is okay. Check WD EME support.
638 scoped_ptr<media::SimpleCdmPromise> promise(new media::SimpleCdmPromise(
639 base::Bind(&ClearKeyCdm::OnSessionUpdated,
640 base::Unretained(this),
641 promise_id_for_emulated_loadsession_,
642 session_id_for_emulated_loadsession_),
643 base::Bind(&ClearKeyCdm::OnSessionUpdateFailed,
644 base::Unretained(this),
645 promise_id_for_emulated_loadsession_)));
538 decryptor_.UpdateSession(session_id_for_emulated_loadsession_, 646 decryptor_.UpdateSession(session_id_for_emulated_loadsession_,
539 reinterpret_cast<const uint8*>(jwk_set.data()), 647 reinterpret_cast<const uint8*>(jwk_set.data()),
540 jwk_set.size()); 648 jwk_set.size(),
649 promise.Pass());
541 } 650 }
542 651
543 void ClearKeyCdm::OnSessionCreated(uint32 session_id, 652 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, 653 const std::vector<uint8>& message,
565 const std::string& destination_url) { 654 const std::string& destination_url) {
566 DVLOG(1) << "OnSessionMessage: " << message.size(); 655 DVLOG(1) << "OnSessionMessage: " << message.size();
567 656
568 // Ignore the message when we are waiting to update the loadable session. 657 // Ignore the message when we are waiting to update the loadable session.
569 if (session_id == session_id_for_emulated_loadsession_) 658 if (web_session_id == session_id_for_emulated_loadsession_)
570 return; 659 return;
571 660
572 host_->OnSessionMessage(session_id, 661 // OnSessionMessage() only called during CreateSession(), so no promise
662 // involved (OnSessionCreated() called to resolve the CreateSession()
663 // promise).
664 host_->OnSessionMessage(web_session_id.data(),
665 web_session_id.length(),
573 reinterpret_cast<const char*>(message.data()), 666 reinterpret_cast<const char*>(message.data()),
574 message.size(), 667 message.size(),
575 destination_url.data(), 668 destination_url.data(),
576 destination_url.size()); 669 destination_url.length());
577 } 670 }
578 671
579 void ClearKeyCdm::OnSessionReady(uint32 session_id) { 672 void ClearKeyCdm::OnSessionCreated(uint32 promise_id,
580 if (session_id == session_id_for_emulated_loadsession_) { 673 const std::string& web_session_id) {
581 session_id_for_emulated_loadsession_ = MediaKeys::kInvalidSessionId; 674 // Save the latest session ID for heartbeat and file IO test messages.
582 host_->OnSessionCreated( 675 last_session_id_ = web_session_id;
583 session_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId)); 676
677 host_->OnResolveNewSessionPromise(
678 promise_id, web_session_id.data(), web_session_id.length());
679 }
680
681 void ClearKeyCdm::OnSessionCreateFailed(uint32 promise_id,
682 MediaKeys::Exception exception_code,
683 uint32 system_code,
684 const std::string& error_message) {
685 RejectPromise(promise_id, exception_code, system_code, error_message);
686 }
687
688 void ClearKeyCdm::OnSessionLoaded(uint32 promise_id,
689 const std::string& web_session_id) {
690 // Save the latest session ID for heartbeat and file IO test messages.
691 last_session_id_ = web_session_id;
692
693 // |decryptor_| created some session as |web_session_id|, but going forward
694 // we need to map that to |kLoadableWebSessionId|, as that is what callers
695 // expect.
696 session_id_for_emulated_loadsession_ = web_session_id;
697
698 // Delay LoadLoadableSession() to test the case where Decrypt*() calls are
699 // made before the session is fully loaded.
700 const int64 kDelayToLoadSessionMs = 500;
701
702 // Defer resolving the promise until the session is loaded.
703 promise_id_for_emulated_loadsession_ = promise_id;
704
705 // Use the address of |session_id_for_emulated_loadsession_| as the timer
706 // context so that we can call LoadLoadableSession() when the timer expires.
707 host_->SetTimer(kDelayToLoadSessionMs, &session_id_for_emulated_loadsession_);
708 }
709
710 void ClearKeyCdm::OnSessionLoadFailed(uint32 promise_id,
711 MediaKeys::Exception exception_code,
712 uint32 system_code,
713 const std::string& error_message) {
714 RejectPromise(promise_id, exception_code, system_code, error_message);
715 }
716
717 void ClearKeyCdm::OnSessionUpdated(uint32 promise_id,
718 const std::string& web_session_id) {
719 // OnSessionReady() only called as success for UpdateSession(). However,
720 // UpdateSession() also called to finish loading sessions, so handle
721 // appropriately.
722 if (web_session_id == session_id_for_emulated_loadsession_) {
723 session_id_for_emulated_loadsession_ = std::string();
724 // |promise_id| is the LoadSession() promise, so resolve appropriately.
725 host_->OnResolveNewSessionPromise(
726 promise_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId));
727 host_->OnSessionReady(kLoadableWebSessionId, strlen(kLoadableWebSessionId));
728 return;
584 } 729 }
585 730
586 host_->OnSessionReady(session_id); 731 host_->OnResolvePromise(promise_id);
587 } 732 }
588 733
589 void ClearKeyCdm::OnSessionClosed(uint32 session_id) { 734 void ClearKeyCdm::OnSessionUpdateFailed(uint32 promise_id,
590 host_->OnSessionClosed(session_id); 735 MediaKeys::Exception exception_code,
736 uint32 system_code,
737 const std::string& error_message) {
738 RejectPromise(promise_id, exception_code, system_code, error_message);
591 } 739 }
592 740
593 void ClearKeyCdm::OnSessionError(uint32 session_id, 741 void ClearKeyCdm::OnSessionReleased(uint32 promise_id,
594 media::MediaKeys::KeyError error_code, 742 const std::string& web_session_id) {
595 uint32 system_code) { 743 host_->OnResolvePromise(promise_id);
596 host_->OnSessionError( 744 }
597 session_id, static_cast<cdm::MediaKeyError>(error_code), system_code); 745
746 void ClearKeyCdm::OnSessionReleaseFailed(uint32 promise_id,
747 MediaKeys::Exception exception_code,
748 uint32 system_code,
749 const std::string& error_message) {
750 RejectPromise(promise_id, exception_code, system_code, error_message);
751 }
752
753 void ClearKeyCdm::RejectPromise(uint32 promise_id,
754 MediaKeys::Exception exception_code,
755 uint32 system_code,
756 const std::string& error_message) {
757 host_->OnRejectPromise(promise_id,
758 ConvertException(exception_code),
759 system_code,
760 error_message.data(),
761 error_message.length());
598 } 762 }
599 763
600 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 764 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
601 int64 ClearKeyCdm::CurrentTimeStampInMicroseconds() const { 765 int64 ClearKeyCdm::CurrentTimeStampInMicroseconds() const {
602 return output_timestamp_base_in_microseconds_ + 766 return output_timestamp_base_in_microseconds_ +
603 base::Time::kMicrosecondsPerSecond * 767 base::Time::kMicrosecondsPerSecond *
604 total_samples_generated_ / samples_per_second_; 768 total_samples_generated_ / samples_per_second_;
605 } 769 }
606 770
607 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration( 771 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 void ClearKeyCdm::StartFileIOTest() { 823 void ClearKeyCdm::StartFileIOTest() {
660 file_io_test_runner_.reset(new FileIOTestRunner( 824 file_io_test_runner_.reset(new FileIOTestRunner(
661 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_)))); 825 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_))));
662 file_io_test_runner_->RunAllTests( 826 file_io_test_runner_->RunAllTests(
663 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this))); 827 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this)));
664 } 828 }
665 829
666 void ClearKeyCdm::OnFileIOTestComplete(bool success) { 830 void ClearKeyCdm::OnFileIOTestComplete(bool success) {
667 DVLOG(1) << __FUNCTION__ << ": " << success; 831 DVLOG(1) << __FUNCTION__ << ": " << success;
668 std::string message = GetFileIOTestResultMessage(success); 832 std::string message = GetFileIOTestResultMessage(success);
669 host_->OnSessionMessage( 833 host_->OnSessionMessage(last_session_id_.data(),
670 last_session_id_, message.data(), message.size(), NULL, 0); 834 last_session_id_.length(),
835 message.data(),
836 message.length(),
837 NULL,
838 0);
671 file_io_test_runner_.reset(); 839 file_io_test_runner_.reset();
672 } 840 }
673 841
674 } // namespace media 842 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698