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

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: latest CDM_5 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
27 28
28 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER) 29 #if defined(CLEAR_KEY_CDM_USE_FFMPEG_DECODER)
29 #include "base/at_exit.h" 30 #include "base/at_exit.h"
30 #include "base/files/file_path.h" 31 #include "base/files/file_path.h"
31 #include "base/path_service.h" 32 #include "base/path_service.h"
32 #include "media/base/media.h" 33 #include "media/base/media.h"
33 #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.h" 34 #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_audio_decoder.h"
34 #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_video_decoder.h" 35 #include "media/cdm/ppapi/external_clear_key/ffmpeg_cdm_video_decoder.h"
35 36
36 // Include FFmpeg avformat.h for av_register_all(). 37 // Include FFmpeg avformat.h for av_register_all().
37 extern "C" { 38 extern "C" {
38 // Temporarily disable possible loss of data warning. 39 // Temporarily disable possible loss of data warning.
39 MSVC_PUSH_DISABLE_WARNING(4244); 40 MSVC_PUSH_DISABLE_WARNING(4244);
40 #include <libavformat/avformat.h> 41 #include <libavformat/avformat.h>
41 MSVC_POP_WARNING(); 42 MSVC_POP_WARNING();
42 } // extern "C" 43 } // extern "C"
43 44
45 #define COMPILE_ASSERT_MATCHING_ENUM(cdm_name, media_name) \
46 COMPILE_ASSERT(static_cast<int>(cdm::cdm_name) == \
47 static_cast<int>(media::MediaKeys::media_name), \
48 mismatching_enums)
49 // Validate cdm::SessionType and MediaKeys::SessionType
50 COMPILE_ASSERT_MATCHING_ENUM(kTemporary, SESSION_TYPE_TEMPORARY);
51 COMPILE_ASSERT_MATCHING_ENUM(kPersistent, SESSION_TYPE_PERSISTENT);
52
53 // Validate cdm::MediaKeyException and MediaKeys::MediaKeysException
54 COMPILE_ASSERT_MATCHING_ENUM(
55 kNoModificationAllowedError,
56 MEDIA_KEYS_EXCEPTION_NO_MODIFICATION_ALLOWED_ERROR);
57 COMPILE_ASSERT_MATCHING_ENUM(kNotFoundError,
58 MEDIA_KEYS_EXCEPTION_NOT_FOUND_ERROR);
59 COMPILE_ASSERT_MATCHING_ENUM(kNotSupportedError,
60 MEDIA_KEYS_EXCEPTION_NOT_SUPPORTED_ERROR);
61 COMPILE_ASSERT_MATCHING_ENUM(kInvalidStateError,
62 MEDIA_KEYS_EXCEPTION_INVALID_STATE_ERROR);
63 COMPILE_ASSERT_MATCHING_ENUM(kSyntaxError, MEDIA_KEYS_EXCEPTION_SYNTAX_ERROR);
64 COMPILE_ASSERT_MATCHING_ENUM(kInvalidModificationError,
65 MEDIA_KEYS_EXCEPTION_INVALID_MODIFICATION_ERROR);
66 COMPILE_ASSERT_MATCHING_ENUM(kInvalidAccessError,
67 MEDIA_KEYS_EXCEPTION_INVALID_ACCESS_ERROR);
68 COMPILE_ASSERT_MATCHING_ENUM(kSecurityError,
69 MEDIA_KEYS_EXCEPTION_SECURITY_ERROR);
70 COMPILE_ASSERT_MATCHING_ENUM(kAbortError, MEDIA_KEYS_EXCEPTION_ABORT_ERROR);
71 COMPILE_ASSERT_MATCHING_ENUM(kQuotaExceededError,
72 MEDIA_KEYS_EXCEPTION_QUOTA_EXCEEDED_ERROR);
73 COMPILE_ASSERT_MATCHING_ENUM(kTimeoutError, MEDIA_KEYS_EXCEPTION_TIMEOUT_ERROR);
74 COMPILE_ASSERT_MATCHING_ENUM(kNotReadableError,
75 MEDIA_KEYS_EXCEPTION_NOT_READABLE_ERROR);
76 COMPILE_ASSERT_MATCHING_ENUM(kDataError, MEDIA_KEYS_EXCEPTION_DATA_ERROR);
77 COMPILE_ASSERT_MATCHING_ENUM(kOperationError,
78 MEDIA_KEYS_EXCEPTION_OPERATION_ERROR);
79 COMPILE_ASSERT_MATCHING_ENUM(kVersionError, MEDIA_KEYS_EXCEPTION_VERSION_ERROR);
80 COMPILE_ASSERT_MATCHING_ENUM(kUnknownError, MEDIA_KEYS_EXCEPTION_UNKNOWN_ERROR);
81 COMPILE_ASSERT_MATCHING_ENUM(kClientError, MEDIA_KEYS_EXCEPTION_CLIENT_ERROR);
82 COMPILE_ASSERT_MATCHING_ENUM(kOutputError, MEDIA_KEYS_EXCEPTION_OUTPUT_ERROR);
83 #undef COMPILE_ASSERT_MATCHING_ENUM
84
44 // TODO(tomfinegan): When COMPONENT_BUILD is not defined an AtExitManager must 85 // TODO(tomfinegan): When COMPONENT_BUILD is not defined an AtExitManager must
45 // exist before the call to InitializeFFmpegLibraries(). This should no longer 86 // exist before the call to InitializeFFmpegLibraries(). This should no longer
46 // be required after http://crbug.com/91970 because we'll be able to get rid of 87 // be required after http://crbug.com/91970 because we'll be able to get rid of
47 // InitializeFFmpegLibraries(). 88 // InitializeFFmpegLibraries().
48 #if !defined COMPONENT_BUILD 89 #if !defined COMPONENT_BUILD
49 static base::AtExitManager g_at_exit_manager; 90 static base::AtExitManager g_at_exit_manager;
50 #endif 91 #endif
51 92
52 // TODO(tomfinegan): InitializeFFmpegLibraries() and |g_cdm_module_initialized| 93 // TODO(tomfinegan): InitializeFFmpegLibraries() and |g_cdm_module_initialized|
53 // are required for running in the sandbox, and should no longer be required 94 // are required for running in the sandbox, and should no longer be required
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 } 221 }
181 222
182 const char* GetCdmVersion() { 223 const char* GetCdmVersion() {
183 return kClearKeyCdmVersion; 224 return kClearKeyCdmVersion;
184 } 225 }
185 226
186 namespace media { 227 namespace media {
187 228
188 ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system) 229 ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system)
189 : decryptor_( 230 : decryptor_(
190 base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this)), 231 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), 232 host_(host),
196 key_system_(key_system), 233 key_system_(key_system),
197 last_session_id_(MediaKeys::kInvalidSessionId),
198 session_id_for_emulated_loadsession_(MediaKeys::kInvalidSessionId),
199 timer_delay_ms_(kInitialTimerDelayMs), 234 timer_delay_ms_(kInitialTimerDelayMs),
200 heartbeat_timer_set_(false) { 235 heartbeat_timer_set_(false) {
201 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 236 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
202 channel_count_ = 0; 237 channel_count_ = 0;
203 bits_per_channel_ = 0; 238 bits_per_channel_ = 0;
204 samples_per_second_ = 0; 239 samples_per_second_ = 0;
205 output_timestamp_base_in_microseconds_ = kNoTimestamp; 240 output_timestamp_base_in_microseconds_ = kNoTimestamp;
206 total_samples_generated_ = 0; 241 total_samples_generated_ = 0;
207 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 242 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
208 } 243 }
209 244
210 ClearKeyCdm::~ClearKeyCdm() {} 245 ClearKeyCdm::~ClearKeyCdm() {}
211 246
212 void ClearKeyCdm::CreateSession(uint32 session_id, 247 void ClearKeyCdm::CreateSession(uint32 promise_id,
213 const char* type, 248 const char* init_data_type,
214 uint32 type_size, 249 uint32 init_data_type_size,
215 const uint8* init_data, 250 const uint8* init_data,
216 uint32 init_data_size) { 251 uint32 init_data_size,
252 cdm::SessionType session_type) {
217 DVLOG(1) << __FUNCTION__; 253 DVLOG(1) << __FUNCTION__;
218 decryptor_.CreateSession(
219 session_id, std::string(type, type_size), init_data, init_data_size);
220 254
221 // Save the latest session ID for heartbeat and file IO test messages. 255 scoped_ptr<media::CdmNewSessionPromise> promise(
222 last_session_id_ = session_id; 256 new media::CdmNewSessionPromise(
257 base::Bind(&ClearKeyCdm::OnSessionCreated,
258 base::Unretained(this),
259 promise_id),
260 base::Bind(&ClearKeyCdm::OnSessionCreateFailed,
261 base::Unretained(this),
262 promise_id)));
263 decryptor_.CreateSession(std::string(init_data_type, init_data_type_size),
264 init_data,
265 init_data_size,
266 static_cast<MediaKeys::SessionType>(session_type),
267 promise.Pass());
223 268
224 if (key_system_ == kExternalClearKeyFileIOTestKeySystem) 269 if (key_system_ == kExternalClearKeyFileIOTestKeySystem)
225 StartFileIOTest(); 270 StartFileIOTest();
226 } 271 }
227 272
228 // Loads a emulated stored session. Currently only |kLoadableWebSessionId| 273 // Loads a emulated stored session. Currently only |kLoadableWebSessionId|
229 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is 274 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is
230 // supported. 275 // supported.
231 void ClearKeyCdm::LoadSession(uint32_t session_id, 276 void ClearKeyCdm::LoadSession(uint32 promise_id,
232 const char* web_session_id, 277 const char* web_session_id,
233 uint32_t web_session_id_length) { 278 uint32_t web_session_id_length) {
234 DVLOG(1) << __FUNCTION__; 279 DVLOG(1) << __FUNCTION__;
235 280
236 if (std::string(kLoadableWebSessionId) != 281 if (std::string(kLoadableWebSessionId) !=
237 std::string(web_session_id, web_session_id_length)) { 282 std::string(web_session_id, web_session_id_length)) {
238 // TODO(xhwang): Report "NotFoundError" when we support DOMError style. 283 std::string message("Incorrect session id specified for LoadSession().");
239 OnSessionError(session_id, MediaKeys::kUnknownError, 0); 284 host_->OnRejectPromise(
285 promise_id, cdm::kNotFoundError, 0, message.data(), message.length());
240 return; 286 return;
241 } 287 }
242 288
243 session_id_for_emulated_loadsession_ = session_id; 289 scoped_ptr<media::CdmNewSessionPromise> promise(
244 290 new media::CdmNewSessionPromise(
245 decryptor_.CreateSession(session_id, kLoadableSessionContentType, NULL, 0); 291 base::Bind(&ClearKeyCdm::OnSessionLoaded,
292 base::Unretained(this),
293 promise_id),
294 base::Bind(&ClearKeyCdm::OnSessionLoadFailed,
295 base::Unretained(this),
296 promise_id)));
297 decryptor_.CreateSession(std::string(kLoadableSessionContentType),
298 NULL,
299 0,
300 MediaKeys::SESSION_TYPE_TEMPORARY,
301 promise.Pass());
246 } 302 }
247 303
248 void ClearKeyCdm::UpdateSession(uint32 session_id, 304 void ClearKeyCdm::UpdateSession(uint32 promise_id,
305 const char* web_session_id,
306 uint32_t web_session_id_size,
249 const uint8* response, 307 const uint8* response,
250 uint32 response_size) { 308 uint32 response_size) {
251 DVLOG(1) << __FUNCTION__; 309 DVLOG(1) << __FUNCTION__;
252 decryptor_.UpdateSession(session_id, response, response_size); 310 std::string web_session_str(web_session_id, web_session_id_size);
311
312 scoped_ptr<media::CdmChangeSessionPromise> promise(
313 new media::CdmChangeSessionPromise(
314 base::Bind(&ClearKeyCdm::OnSessionUpdated,
315 base::Unretained(this),
316 promise_id,
317 web_session_str),
318 base::Bind(&ClearKeyCdm::OnSessionUpdateFailed,
319 base::Unretained(this),
320 promise_id)));
321 decryptor_.UpdateSession(
322 web_session_str, response, response_size, promise.Pass());
253 323
254 if (!heartbeat_timer_set_) { 324 if (!heartbeat_timer_set_) {
255 ScheduleNextHeartBeat(); 325 ScheduleNextHeartBeat();
256 heartbeat_timer_set_ = true; 326 heartbeat_timer_set_ = true;
257 } 327 }
258 } 328 }
259 329
260 void ClearKeyCdm::ReleaseSession(uint32 session_id) { 330 void ClearKeyCdm::ReleaseSession(uint32 promise_id,
331 const char* web_session_id,
332 uint32_t web_session_id_size) {
261 DVLOG(1) << __FUNCTION__; 333 DVLOG(1) << __FUNCTION__;
262 decryptor_.ReleaseSession(session_id); 334 std::string web_session_str(web_session_id, web_session_id_size);
335
336 scoped_ptr<media::CdmChangeSessionPromise> promise(
337 new media::CdmChangeSessionPromise(
338 base::Bind(&ClearKeyCdm::OnSessionReleased,
339 base::Unretained(this),
340 promise_id,
341 web_session_str),
342 base::Bind(&ClearKeyCdm::OnSessionReleaseFailed,
343 base::Unretained(this),
344 promise_id)));
345 decryptor_.ReleaseSession(web_session_str, promise.Pass());
346 }
347
348 void ClearKeyCdm::SetServerCertificate(uint32 promise_id,
349 const uint8_t* server_certificate_data,
350 uint32_t server_certificate_data_size) {
351 // ClearKey doesn't use a server certificate.
352 host_->OnResolvePromise(promise_id);
263 } 353 }
264 354
265 void ClearKeyCdm::TimerExpired(void* context) { 355 void ClearKeyCdm::TimerExpired(void* context) {
266 if (context == &session_id_for_emulated_loadsession_) { 356 if (context == &session_id_for_emulated_loadsession_) {
267 LoadLoadableSession(); 357 LoadLoadableSession();
268 return; 358 return;
269 } 359 }
270 360
271 DCHECK(heartbeat_timer_set_); 361 DCHECK(heartbeat_timer_set_);
272 std::string heartbeat_message; 362 std::string heartbeat_message;
273 if (!next_heartbeat_message_.empty() && 363 if (!next_heartbeat_message_.empty() &&
274 context == &next_heartbeat_message_[0]) { 364 context == &next_heartbeat_message_[0]) {
275 heartbeat_message = next_heartbeat_message_; 365 heartbeat_message = next_heartbeat_message_;
276 } else { 366 } else {
277 heartbeat_message = "ERROR: Invalid timer context found!"; 367 heartbeat_message = "ERROR: Invalid timer context found!";
278 } 368 }
279 369
280 // This URL is only used for testing the code path for defaultURL. 370 // 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. 371 // There is no service at this URL, so applications should ignore it.
282 const char url[] = "http://test.externalclearkey.chromium.org"; 372 const char url[] = "http://test.externalclearkey.chromium.org";
283 373
284 host_->OnSessionMessage(last_session_id_, 374 host_->OnSessionMessage(last_session_id_.data(),
375 last_session_id_.length(),
285 heartbeat_message.data(), 376 heartbeat_message.data(),
286 heartbeat_message.size(), 377 heartbeat_message.length(),
287 url, 378 url,
288 arraysize(url) - 1); 379 arraysize(url) - 1);
289 380
290 ScheduleNextHeartBeat(); 381 ScheduleNextHeartBeat();
291 } 382 }
292 383
293 static void CopyDecryptResults( 384 static void CopyDecryptResults(
294 media::Decryptor::Status* status_copy, 385 media::Decryptor::Status* status_copy,
295 scoped_refptr<media::DecoderBuffer>* buffer_copy, 386 scoped_refptr<media::DecoderBuffer>* buffer_copy,
296 media::Decryptor::Status status, 387 media::Decryptor::Status status,
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
469 560
470 void ClearKeyCdm::Destroy() { 561 void ClearKeyCdm::Destroy() {
471 DVLOG(1) << "Destroy()"; 562 DVLOG(1) << "Destroy()";
472 delete this; 563 delete this;
473 } 564 }
474 565
475 void ClearKeyCdm::ScheduleNextHeartBeat() { 566 void ClearKeyCdm::ScheduleNextHeartBeat() {
476 // Prepare the next heartbeat message and set timer. 567 // Prepare the next heartbeat message and set timer.
477 std::ostringstream msg_stream; 568 std::ostringstream msg_stream;
478 msg_stream << kHeartBeatHeader << " from ClearKey CDM set at time " 569 msg_stream << kHeartBeatHeader << " from ClearKey CDM set at time "
479 << host_->GetCurrentWallTimeInSeconds() << "."; 570 << host_->GetCurrentTime() << ".";
480 next_heartbeat_message_ = msg_stream.str(); 571 next_heartbeat_message_ = msg_stream.str();
481 572
482 host_->SetTimer(timer_delay_ms_, &next_heartbeat_message_[0]); 573 host_->SetTimer(timer_delay_ms_, &next_heartbeat_message_[0]);
483 574
484 // Use a smaller timer delay at start-up to facilitate testing. Increase the 575 // Use a smaller timer delay at start-up to facilitate testing. Increase the
485 // timer delay up to a limit to avoid message spam. 576 // timer delay up to a limit to avoid message spam.
486 if (timer_delay_ms_ < kMaxTimerDelayMs) 577 if (timer_delay_ms_ < kMaxTimerDelayMs)
487 timer_delay_ms_ = std::min(2 * timer_delay_ms_, kMaxTimerDelayMs); 578 timer_delay_ms_ = std::min(2 * timer_delay_ms_, kMaxTimerDelayMs);
488 } 579 }
489 580
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 NOTIMPLEMENTED(); 619 NOTIMPLEMENTED();
529 }; 620 };
530 621
531 void ClearKeyCdm::LoadLoadableSession() { 622 void ClearKeyCdm::LoadLoadableSession() {
532 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey, 623 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey,
533 sizeof(kLoadableSessionKey), 624 sizeof(kLoadableSessionKey),
534 kLoadableSessionKeyId, 625 kLoadableSessionKeyId,
535 sizeof(kLoadableSessionKeyId) - 1); 626 sizeof(kLoadableSessionKeyId) - 1);
536 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support, 627 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support,
537 // this is okay. Check WD EME support. 628 // this is okay. Check WD EME support.
629 scoped_ptr<media::CdmChangeSessionPromise> promise(
630 new media::CdmChangeSessionPromise(
631 base::Bind(&ClearKeyCdm::OnSessionUpdated,
632 base::Unretained(this),
633 promise_id_for_emulated_loadsession_,
634 session_id_for_emulated_loadsession_),
635 base::Bind(&ClearKeyCdm::OnSessionUpdateFailed,
636 base::Unretained(this),
637 promise_id_for_emulated_loadsession_)));
538 decryptor_.UpdateSession(session_id_for_emulated_loadsession_, 638 decryptor_.UpdateSession(session_id_for_emulated_loadsession_,
539 reinterpret_cast<const uint8*>(jwk_set.data()), 639 reinterpret_cast<const uint8*>(jwk_set.data()),
540 jwk_set.size()); 640 jwk_set.size(),
641 promise.Pass());
541 } 642 }
542 643
543 void ClearKeyCdm::OnSessionCreated(uint32 session_id, 644 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, 645 const std::vector<uint8>& message,
565 const std::string& destination_url) { 646 const std::string& destination_url) {
566 DVLOG(1) << "OnSessionMessage: " << message.size(); 647 DVLOG(1) << "OnSessionMessage: " << message.size();
567 648
568 // Ignore the message when we are waiting to update the loadable session. 649 // Ignore the message when we are waiting to update the loadable session.
569 if (session_id == session_id_for_emulated_loadsession_) 650 if (web_session_id == session_id_for_emulated_loadsession_)
570 return; 651 return;
571 652
572 host_->OnSessionMessage(session_id, 653 // OnSessionMessage() only called during CreateSession(), so no promise
654 // involved (OnSessionCreated() called to resolve the CreateSession()
655 // promise).
656 host_->OnSessionMessage(web_session_id.data(),
657 web_session_id.length(),
573 reinterpret_cast<const char*>(message.data()), 658 reinterpret_cast<const char*>(message.data()),
574 message.size(), 659 message.size(),
575 destination_url.data(), 660 destination_url.data(),
576 destination_url.size()); 661 destination_url.length());
577 } 662 }
578 663
579 void ClearKeyCdm::OnSessionReady(uint32 session_id) { 664 void ClearKeyCdm::OnSessionCreated(uint32 promise_id,
580 if (session_id == session_id_for_emulated_loadsession_) { 665 const std::string& web_session_id) {
581 session_id_for_emulated_loadsession_ = MediaKeys::kInvalidSessionId; 666 // Save the latest session ID for heartbeat and file IO test messages.
582 host_->OnSessionCreated( 667 last_session_id_ = web_session_id;
583 session_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId)); 668
669 host_->OnResolveNewSessionPromise(
670 promise_id, web_session_id.data(), web_session_id.length());
671 }
672
673 void ClearKeyCdm::OnSessionCreateFailed(
674 uint32 promise_id,
675 MediaKeys::MediaKeysException exception_code,
676 uint32 system_code,
677 const std::string& error_message) {
678 RejectPromise(promise_id, exception_code, system_code, error_message);
679 }
680
681 void ClearKeyCdm::OnSessionLoaded(uint32 promise_id,
682 const std::string& web_session_id) {
683 // Save the latest session ID for heartbeat and file IO test messages.
684 last_session_id_ = web_session_id;
685
686 // |decryptor_| created some session as |web_session_id|, but going forward
687 // we need to map that to |kLoadableWebSessionId|, as that is what callers
688 // expect.
689 session_id_for_emulated_loadsession_ = web_session_id;
690
691 // Delay LoadLoadableSession() to test the case where Decrypt*() calls are
692 // made before the session is fully loaded.
693 const int64 kDelayToLoadSessionMs = 500;
694
695 // Defer resolving the promise until the session is loaded.
696 promise_id_for_emulated_loadsession_ = promise_id;
697
698 // Use the address of |session_id_for_emulated_loadsession_| as the timer
699 // context so that we can call LoadLoadableSession() when the timer expires.
700 host_->SetTimer(kDelayToLoadSessionMs, &session_id_for_emulated_loadsession_);
701 }
702
703 void ClearKeyCdm::OnSessionLoadFailed(
704 uint32 promise_id,
705 MediaKeys::MediaKeysException exception_code,
706 uint32 system_code,
707 const std::string& error_message) {
708 RejectPromise(promise_id, exception_code, system_code, error_message);
709 }
710
711 void ClearKeyCdm::OnSessionUpdated(uint32 promise_id,
712 const std::string& web_session_id) {
713 // OnSessionReady() only called as success for UpdateSession(). However,
714 // UpdateSession() also called to finish loading sessions, so handle
715 // appropriately.
716 if (web_session_id == session_id_for_emulated_loadsession_) {
717 session_id_for_emulated_loadsession_ = std::string();
718 // |promise_id| is the LoadSession() promise, so resolve appropriately.
719 host_->OnResolveNewSessionPromise(
720 promise_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId));
721 host_->OnSessionReady(kLoadableWebSessionId, strlen(kLoadableWebSessionId));
722 return;
584 } 723 }
585 724
586 host_->OnSessionReady(session_id); 725 host_->OnResolvePromise(promise_id);
587 } 726 }
588 727
589 void ClearKeyCdm::OnSessionClosed(uint32 session_id) { 728 void ClearKeyCdm::OnSessionUpdateFailed(
590 host_->OnSessionClosed(session_id); 729 uint32 promise_id,
730 MediaKeys::MediaKeysException exception_code,
731 uint32 system_code,
732 const std::string& error_message) {
733 RejectPromise(promise_id, exception_code, system_code, error_message);
591 } 734 }
592 735
593 void ClearKeyCdm::OnSessionError(uint32 session_id, 736 void ClearKeyCdm::OnSessionReleased(uint32 promise_id,
594 media::MediaKeys::KeyError error_code, 737 const std::string& web_session_id) {
595 uint32 system_code) { 738 host_->OnResolvePromise(promise_id);
596 host_->OnSessionError( 739 }
597 session_id, static_cast<cdm::MediaKeyError>(error_code), system_code); 740
741 void ClearKeyCdm::OnSessionReleaseFailed(
742 uint32 promise_id,
743 MediaKeys::MediaKeysException exception_code,
744 uint32 system_code,
745 const std::string& error_message) {
746 RejectPromise(promise_id, exception_code, system_code, error_message);
747 }
748
749 void ClearKeyCdm::RejectPromise(uint32 promise_id,
750 MediaKeys::MediaKeysException exception_code,
751 uint32 system_code,
752 const std::string& error_message) {
753 host_->OnRejectPromise(promise_id,
754 static_cast<cdm::Error>(exception_code),
755 system_code,
756 error_message.data(),
757 error_message.length());
598 } 758 }
599 759
600 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 760 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
601 int64 ClearKeyCdm::CurrentTimeStampInMicroseconds() const { 761 int64 ClearKeyCdm::CurrentTimeStampInMicroseconds() const {
602 return output_timestamp_base_in_microseconds_ + 762 return output_timestamp_base_in_microseconds_ +
603 base::Time::kMicrosecondsPerSecond * 763 base::Time::kMicrosecondsPerSecond *
604 total_samples_generated_ / samples_per_second_; 764 total_samples_generated_ / samples_per_second_;
605 } 765 }
606 766
607 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration( 767 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 void ClearKeyCdm::StartFileIOTest() { 819 void ClearKeyCdm::StartFileIOTest() {
660 file_io_test_runner_.reset(new FileIOTestRunner( 820 file_io_test_runner_.reset(new FileIOTestRunner(
661 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_)))); 821 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_))));
662 file_io_test_runner_->RunAllTests( 822 file_io_test_runner_->RunAllTests(
663 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this))); 823 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this)));
664 } 824 }
665 825
666 void ClearKeyCdm::OnFileIOTestComplete(bool success) { 826 void ClearKeyCdm::OnFileIOTestComplete(bool success) {
667 DVLOG(1) << __FUNCTION__ << ": " << success; 827 DVLOG(1) << __FUNCTION__ << ": " << success;
668 std::string message = GetFileIOTestResultMessage(success); 828 std::string message = GetFileIOTestResultMessage(success);
669 host_->OnSessionMessage( 829 host_->OnSessionMessage(last_session_id_.data(),
670 last_session_id_, message.data(), message.size(), NULL, 0); 830 last_session_id_.length(),
831 message.data(),
832 message.length(),
833 NULL,
834 0);
671 file_io_test_runner_.reset(); 835 file_io_test_runner_.reset();
672 } 836 }
673 837
674 } // namespace media 838 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698