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

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: cdm_promise template 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(kIndexSizeError,
55 MEDIA_KEYS_EXCEPTION_INDEX_SIZE_ERROR);
56 COMPILE_ASSERT_MATCHING_ENUM(kHierarchyRequestError,
57 MEDIA_KEYS_EXCEPTION_HIERARCHY_REQUEST_ERROR);
58 COMPILE_ASSERT_MATCHING_ENUM(kWrongDocumentError,
59 MEDIA_KEYS_EXCEPTION_WRONG_DOCUMENT_ERROR);
60 COMPILE_ASSERT_MATCHING_ENUM(kInvalidCharacterError,
61 MEDIA_KEYS_EXCEPTION_INVALID_CHARACTER_ERROR);
62 COMPILE_ASSERT_MATCHING_ENUM(
63 kNoModificationAllowedError,
64 MEDIA_KEYS_EXCEPTION_NO_MODIFICATION_ALLOWED_ERROR);
65 COMPILE_ASSERT_MATCHING_ENUM(kNotFoundError,
66 MEDIA_KEYS_EXCEPTION_NOT_FOUND_ERROR);
67 COMPILE_ASSERT_MATCHING_ENUM(kNotSupportedError,
68 MEDIA_KEYS_EXCEPTION_NOT_SUPPORTED_ERROR);
69 COMPILE_ASSERT_MATCHING_ENUM(kInvalidStateError,
70 MEDIA_KEYS_EXCEPTION_INVALID_STATE_ERROR);
71 COMPILE_ASSERT_MATCHING_ENUM(kSyntaxError, MEDIA_KEYS_EXCEPTION_SYNTAX_ERROR);
72 COMPILE_ASSERT_MATCHING_ENUM(kInvalidModificationError,
73 MEDIA_KEYS_EXCEPTION_INVALID_MODIFICATION_ERROR);
74 COMPILE_ASSERT_MATCHING_ENUM(kNamespaceError,
75 MEDIA_KEYS_EXCEPTION_NAMESPACE_ERROR);
76 COMPILE_ASSERT_MATCHING_ENUM(kInvalidAccessError,
77 MEDIA_KEYS_EXCEPTION_INVALID_ACCESS_ERROR);
78 COMPILE_ASSERT_MATCHING_ENUM(kSecurityError,
79 MEDIA_KEYS_EXCEPTION_SECURITY_ERROR);
80 COMPILE_ASSERT_MATCHING_ENUM(kNetworkError, MEDIA_KEYS_EXCEPTION_NETWORK_ERROR);
81 COMPILE_ASSERT_MATCHING_ENUM(kAbortError, MEDIA_KEYS_EXCEPTION_ABORT_ERROR);
82 COMPILE_ASSERT_MATCHING_ENUM(kUrlMismatchError,
83 MEDIA_KEYS_EXCEPTION_URL_MISMATCH_ERROR);
84 COMPILE_ASSERT_MATCHING_ENUM(kQuotaExceededError,
85 MEDIA_KEYS_EXCEPTION_QUOTA_EXCEEDED_ERROR);
86 COMPILE_ASSERT_MATCHING_ENUM(kTimeoutError, MEDIA_KEYS_EXCEPTION_TIMEOUT_ERROR);
87 COMPILE_ASSERT_MATCHING_ENUM(kInvalidNodeTypeError,
88 MEDIA_KEYS_EXCEPTION_INVALID_NODE_TYPE_ERROR);
89 COMPILE_ASSERT_MATCHING_ENUM(kDataCloneError,
90 MEDIA_KEYS_EXCEPTION_DATA_CLONE_ERROR);
91 COMPILE_ASSERT_MATCHING_ENUM(kEncodingError,
92 MEDIA_KEYS_EXCEPTION_ENCODING_ERROR);
93 COMPILE_ASSERT_MATCHING_ENUM(kNotReadableError,
94 MEDIA_KEYS_EXCEPTION_NOT_READABLE_ERROR);
95 COMPILE_ASSERT_MATCHING_ENUM(kDataError, MEDIA_KEYS_EXCEPTION_DATA_ERROR);
96 COMPILE_ASSERT_MATCHING_ENUM(kOperationError,
97 MEDIA_KEYS_EXCEPTION_OPERATION_ERROR);
98 COMPILE_ASSERT_MATCHING_ENUM(kVersionError, MEDIA_KEYS_EXCEPTION_VERSION_ERROR);
99 COMPILE_ASSERT_MATCHING_ENUM(kMediaKeyErrorUnknownError,
100 MEDIA_KEYS_EXCEPTION_UNKNOWN_ERROR);
101 COMPILE_ASSERT_MATCHING_ENUM(kMediaKeyErrorClientError,
102 MEDIA_KEYS_EXCEPTION_CLIENT_ERROR);
103 COMPILE_ASSERT_MATCHING_ENUM(kMediaKeyErrorOutputError,
104 MEDIA_KEYS_EXCEPTION_OUTPUT_ERROR);
105 #undef COMPILE_ASSERT_MATCHING_ENUM
106
44 // TODO(tomfinegan): When COMPONENT_BUILD is not defined an AtExitManager must 107 // TODO(tomfinegan): When COMPONENT_BUILD is not defined an AtExitManager must
45 // exist before the call to InitializeFFmpegLibraries(). This should no longer 108 // 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 109 // be required after http://crbug.com/91970 because we'll be able to get rid of
47 // InitializeFFmpegLibraries(). 110 // InitializeFFmpegLibraries().
48 #if !defined COMPONENT_BUILD 111 #if !defined COMPONENT_BUILD
49 static base::AtExitManager g_at_exit_manager; 112 static base::AtExitManager g_at_exit_manager;
50 #endif 113 #endif
51 114
52 // TODO(tomfinegan): InitializeFFmpegLibraries() and |g_cdm_module_initialized| 115 // TODO(tomfinegan): InitializeFFmpegLibraries() and |g_cdm_module_initialized|
53 // are required for running in the sandbox, and should no longer be required 116 // 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 } 243 }
181 244
182 const char* GetCdmVersion() { 245 const char* GetCdmVersion() {
183 return kClearKeyCdmVersion; 246 return kClearKeyCdmVersion;
184 } 247 }
185 248
186 namespace media { 249 namespace media {
187 250
188 ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system) 251 ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host, const std::string& key_system)
189 : decryptor_( 252 : decryptor_(
190 base::Bind(&ClearKeyCdm::OnSessionCreated, base::Unretained(this)), 253 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), 254 host_(host),
196 key_system_(key_system), 255 key_system_(key_system),
197 last_session_id_(MediaKeys::kInvalidSessionId),
198 session_id_for_emulated_loadsession_(MediaKeys::kInvalidSessionId),
199 timer_delay_ms_(kInitialTimerDelayMs), 256 timer_delay_ms_(kInitialTimerDelayMs),
200 heartbeat_timer_set_(false) { 257 heartbeat_timer_set_(false) {
201 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 258 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
202 channel_count_ = 0; 259 channel_count_ = 0;
203 bits_per_channel_ = 0; 260 bits_per_channel_ = 0;
204 samples_per_second_ = 0; 261 samples_per_second_ = 0;
205 output_timestamp_base_in_microseconds_ = kNoTimestamp; 262 output_timestamp_base_in_microseconds_ = kNoTimestamp;
206 total_samples_generated_ = 0; 263 total_samples_generated_ = 0;
207 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER 264 #endif // CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER
208 } 265 }
209 266
210 ClearKeyCdm::~ClearKeyCdm() {} 267 ClearKeyCdm::~ClearKeyCdm() {}
211 268
212 void ClearKeyCdm::CreateSession(uint32 session_id, 269 void ClearKeyCdm::CreateSession(uint32 promise_id,
213 const char* type, 270 const char* init_data_type,
214 uint32 type_size, 271 uint32 init_data_type_size,
215 const uint8* init_data, 272 const uint8* init_data,
216 uint32 init_data_size) { 273 uint32 init_data_size,
274 cdm::SessionType session_type) {
217 DVLOG(1) << __FUNCTION__; 275 DVLOG(1) << __FUNCTION__;
218 decryptor_.CreateSession(
219 session_id, std::string(type, type_size), init_data, init_data_size);
220 276
221 // Save the latest session ID for heartbeat and file IO test messages. 277 scoped_ptr<media::CdmPromise<std::string> > promise(
222 last_session_id_ = session_id; 278 new media::CdmPromise<std::string>(
279 base::Bind(&ClearKeyCdm::OnSessionCreated,
280 base::Unretained(this),
281 promise_id),
282 base::Bind(&ClearKeyCdm::OnSessionCreateFailed,
283 base::Unretained(this),
284 promise_id)));
285 decryptor_.CreateSession(std::string(init_data_type, init_data_type_size),
286 init_data,
287 init_data_size,
288 static_cast<MediaKeys::SessionType>(session_type),
289 promise.Pass());
223 290
224 if (key_system_ == kExternalClearKeyFileIOTestKeySystem) 291 if (key_system_ == kExternalClearKeyFileIOTestKeySystem)
225 StartFileIOTest(); 292 StartFileIOTest();
226 } 293 }
227 294
228 // Loads a emulated stored session. Currently only |kLoadableWebSessionId| 295 // Loads a emulated stored session. Currently only |kLoadableWebSessionId|
229 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is 296 // (containing a |kLoadableSessionKey| for |kLoadableSessionKeyId|) is
230 // supported. 297 // supported.
231 void ClearKeyCdm::LoadSession(uint32_t session_id, 298 void ClearKeyCdm::LoadSession(uint32 promise_id,
232 const char* web_session_id, 299 const char* web_session_id,
233 uint32_t web_session_id_length) { 300 uint32_t web_session_id_length) {
234 DVLOG(1) << __FUNCTION__; 301 DVLOG(1) << __FUNCTION__;
235 302
236 if (std::string(kLoadableWebSessionId) != 303 if (std::string(kLoadableWebSessionId) !=
237 std::string(web_session_id, web_session_id_length)) { 304 std::string(web_session_id, web_session_id_length)) {
238 // TODO(xhwang): Report "NotFoundError" when we support DOMError style. 305 std::string message("Incorrect session id specified for LoadSession().");
239 OnSessionError(session_id, MediaKeys::kUnknownError, 0); 306 host_->OnRejectPromise(
307 promise_id, cdm::kNotFoundError, 0, message.data(), message.length());
240 return; 308 return;
241 } 309 }
242 310
243 session_id_for_emulated_loadsession_ = session_id; 311 scoped_ptr<media::CdmPromise<std::string> > promise(
244 312 new media::CdmPromise<std::string>(
245 decryptor_.CreateSession(session_id, kLoadableSessionContentType, NULL, 0); 313 base::Bind(&ClearKeyCdm::OnSessionLoaded,
314 base::Unretained(this),
315 promise_id),
316 base::Bind(&ClearKeyCdm::OnSessionLoadFailed,
317 base::Unretained(this),
318 promise_id)));
319 decryptor_.CreateSession(std::string(kLoadableSessionContentType),
320 NULL,
321 0,
322 MediaKeys::SESSION_TYPE_TEMPORARY,
323 promise.Pass());
246 } 324 }
247 325
248 void ClearKeyCdm::UpdateSession(uint32 session_id, 326 void ClearKeyCdm::UpdateSession(uint32 promise_id,
327 const char* web_session_id,
328 uint32_t web_session_id_size,
249 const uint8* response, 329 const uint8* response,
250 uint32 response_size) { 330 uint32 response_size) {
251 DVLOG(1) << __FUNCTION__; 331 DVLOG(1) << __FUNCTION__;
252 decryptor_.UpdateSession(session_id, response, response_size); 332 std::string web_session_str(web_session_id, web_session_id_size);
333
334 scoped_ptr<media::CdmPromise<void> > promise(new media::CdmPromise<void>(
335 base::Bind(&ClearKeyCdm::OnSessionUpdated,
336 base::Unretained(this),
337 promise_id,
338 web_session_str),
339 base::Bind(&ClearKeyCdm::OnSessionUpdateFailed,
340 base::Unretained(this),
341 promise_id)));
342 decryptor_.UpdateSession(
343 web_session_str, response, response_size, promise.Pass());
253 344
254 if (!heartbeat_timer_set_) { 345 if (!heartbeat_timer_set_) {
255 ScheduleNextHeartBeat(); 346 ScheduleNextHeartBeat();
256 heartbeat_timer_set_ = true; 347 heartbeat_timer_set_ = true;
257 } 348 }
258 } 349 }
259 350
260 void ClearKeyCdm::ReleaseSession(uint32 session_id) { 351 void ClearKeyCdm::ReleaseSession(uint32 promise_id,
352 const char* web_session_id,
353 uint32_t web_session_id_size) {
261 DVLOG(1) << __FUNCTION__; 354 DVLOG(1) << __FUNCTION__;
262 decryptor_.ReleaseSession(session_id); 355 std::string web_session_str(web_session_id, web_session_id_size);
356
357 scoped_ptr<media::CdmPromise<void> > promise(new media::CdmPromise<void>(
358 base::Bind(&ClearKeyCdm::OnSessionReleased,
359 base::Unretained(this),
360 promise_id,
361 web_session_str),
362 base::Bind(&ClearKeyCdm::OnSessionReleaseFailed,
363 base::Unretained(this),
364 promise_id)));
365 decryptor_.ReleaseSession(web_session_str, promise.Pass());
366 }
367
368 void ClearKeyCdm::SetServerCertificate(uint32 promise_id,
369 const uint8_t* server_certificate_data,
370 uint32_t server_certificate_data_size) {
371 // ClearKey doesn't use a server certificate.
372 host_->OnResolvePromise(promise_id);
263 } 373 }
264 374
265 void ClearKeyCdm::TimerExpired(void* context) { 375 void ClearKeyCdm::TimerExpired(void* context) {
266 if (context == &session_id_for_emulated_loadsession_) { 376 if (context == &session_id_for_emulated_loadsession_) {
267 LoadLoadableSession(); 377 LoadLoadableSession();
268 return; 378 return;
269 } 379 }
270 380
271 DCHECK(heartbeat_timer_set_); 381 DCHECK(heartbeat_timer_set_);
272 std::string heartbeat_message; 382 std::string heartbeat_message;
273 if (!next_heartbeat_message_.empty() && 383 if (!next_heartbeat_message_.empty() &&
274 context == &next_heartbeat_message_[0]) { 384 context == &next_heartbeat_message_[0]) {
275 heartbeat_message = next_heartbeat_message_; 385 heartbeat_message = next_heartbeat_message_;
276 } else { 386 } else {
277 heartbeat_message = "ERROR: Invalid timer context found!"; 387 heartbeat_message = "ERROR: Invalid timer context found!";
278 } 388 }
279 389
280 // This URL is only used for testing the code path for defaultURL. 390 // 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. 391 // There is no service at this URL, so applications should ignore it.
282 const char url[] = "http://test.externalclearkey.chromium.org"; 392 const char url[] = "http://test.externalclearkey.chromium.org";
283 393
284 host_->OnSessionMessage(last_session_id_, 394 host_->OnSessionMessage(last_session_id_.data(),
395 last_session_id_.length(),
285 heartbeat_message.data(), 396 heartbeat_message.data(),
286 heartbeat_message.size(), 397 heartbeat_message.length(),
287 url, 398 url,
288 arraysize(url) - 1); 399 arraysize(url) - 1);
289 400
290 ScheduleNextHeartBeat(); 401 ScheduleNextHeartBeat();
291 } 402 }
292 403
293 static void CopyDecryptResults( 404 static void CopyDecryptResults(
294 media::Decryptor::Status* status_copy, 405 media::Decryptor::Status* status_copy,
295 scoped_refptr<media::DecoderBuffer>* buffer_copy, 406 scoped_refptr<media::DecoderBuffer>* buffer_copy,
296 media::Decryptor::Status status, 407 media::Decryptor::Status status,
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 NOTIMPLEMENTED(); 639 NOTIMPLEMENTED();
529 }; 640 };
530 641
531 void ClearKeyCdm::LoadLoadableSession() { 642 void ClearKeyCdm::LoadLoadableSession() {
532 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey, 643 std::string jwk_set = GenerateJWKSet(kLoadableSessionKey,
533 sizeof(kLoadableSessionKey), 644 sizeof(kLoadableSessionKey),
534 kLoadableSessionKeyId, 645 kLoadableSessionKeyId,
535 sizeof(kLoadableSessionKeyId) - 1); 646 sizeof(kLoadableSessionKeyId) - 1);
536 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support, 647 // TODO(xhwang): This triggers OnSessionUpdated(). For prefixed EME support,
537 // this is okay. Check WD EME support. 648 // this is okay. Check WD EME support.
649 scoped_ptr<media::CdmPromise<void> > promise(new media::CdmPromise<void>(
650 base::Bind(&ClearKeyCdm::OnSessionUpdated,
651 base::Unretained(this),
652 promise_id_for_emulated_loadsession_,
653 session_id_for_emulated_loadsession_),
654 base::Bind(&ClearKeyCdm::OnSessionUpdateFailed,
655 base::Unretained(this),
656 promise_id_for_emulated_loadsession_)));
538 decryptor_.UpdateSession(session_id_for_emulated_loadsession_, 657 decryptor_.UpdateSession(session_id_for_emulated_loadsession_,
539 reinterpret_cast<const uint8*>(jwk_set.data()), 658 reinterpret_cast<const uint8*>(jwk_set.data()),
540 jwk_set.size()); 659 jwk_set.size(),
660 promise.Pass());
541 } 661 }
542 662
543 void ClearKeyCdm::OnSessionCreated(uint32 session_id, 663 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, 664 const std::vector<uint8>& message,
565 const std::string& destination_url) { 665 const std::string& destination_url) {
566 DVLOG(1) << "OnSessionMessage: " << message.size(); 666 DVLOG(1) << "OnSessionMessage: " << message.size();
567 667
568 // Ignore the message when we are waiting to update the loadable session. 668 // Ignore the message when we are waiting to update the loadable session.
569 if (session_id == session_id_for_emulated_loadsession_) 669 if (web_session_id == session_id_for_emulated_loadsession_)
570 return; 670 return;
571 671
572 host_->OnSessionMessage(session_id, 672 // OnSessionMessage() only called during CreateSession(), so no promise
673 // involved (OnSessionCreated() called to resolve the CreateSession()
674 // promise).
675 host_->OnSessionMessage(web_session_id.data(),
676 web_session_id.length(),
573 reinterpret_cast<const char*>(message.data()), 677 reinterpret_cast<const char*>(message.data()),
574 message.size(), 678 message.size(),
575 destination_url.data(), 679 destination_url.data(),
576 destination_url.size()); 680 destination_url.length());
577 } 681 }
578 682
579 void ClearKeyCdm::OnSessionReady(uint32 session_id) { 683 void ClearKeyCdm::OnSessionCreated(uint32 promise_id,
580 if (session_id == session_id_for_emulated_loadsession_) { 684 const std::string& web_session_id) {
581 session_id_for_emulated_loadsession_ = MediaKeys::kInvalidSessionId; 685 // Save the latest session ID for heartbeat and file IO test messages.
582 host_->OnSessionCreated( 686 last_session_id_ = web_session_id;
583 session_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId)); 687
688 host_->OnResolveNewSessionPromise(
689 promise_id, web_session_id.data(), web_session_id.length());
690 }
691
692 void ClearKeyCdm::OnSessionCreateFailed(
693 uint32 promise_id,
694 MediaKeys::MediaKeysException exception_code,
695 uint32 system_code,
696 const std::string& error_message) {
697 RejectPromise(promise_id, exception_code, system_code, error_message);
698 }
699
700 void ClearKeyCdm::OnSessionLoaded(uint32 promise_id,
701 const std::string& web_session_id) {
702 // Save the latest session ID for heartbeat and file IO test messages.
703 last_session_id_ = web_session_id;
704
705 // |decryptor_| created some session as |web_session_id|, but going forward
706 // we need to map that to |kLoadableWebSessionId|, as that is what callers
707 // expect.
708 session_id_for_emulated_loadsession_ = web_session_id;
709
710 // Delay LoadLoadableSession() to test the case where Decrypt*() calls are
711 // made before the session is fully loaded.
712 const int64 kDelayToLoadSessionMs = 500;
713
714 // Defer resolving the promise until the session is loaded.
715 promise_id_for_emulated_loadsession_ = promise_id;
716
717 // Use the address of |session_id_for_emulated_loadsession_| as the timer
718 // context so that we can call LoadLoadableSession() when the timer expires.
719 host_->SetTimer(kDelayToLoadSessionMs, &session_id_for_emulated_loadsession_);
720 }
721
722 void ClearKeyCdm::OnSessionLoadFailed(
723 uint32 promise_id,
724 MediaKeys::MediaKeysException exception_code,
725 uint32 system_code,
726 const std::string& error_message) {
727 RejectPromise(promise_id, exception_code, system_code, error_message);
728 }
729
730 void ClearKeyCdm::OnSessionUpdated(uint32 promise_id,
731 const std::string& web_session_id) {
732 // OnSessionReady() only called as success for UpdateSession(). However,
733 // UpdateSession() also called to finish loading sessions, so handle
734 // appropriately.
735 if (web_session_id == session_id_for_emulated_loadsession_) {
736 session_id_for_emulated_loadsession_ = std::string();
737 // |promise_id| is the LoadSession() promise, so resolve appropriately.
738 host_->OnResolveNewSessionPromise(
739 promise_id, kLoadableWebSessionId, strlen(kLoadableWebSessionId));
740 host_->OnSessionReady(kLoadableWebSessionId, strlen(kLoadableWebSessionId));
741 return;
584 } 742 }
585 743
586 host_->OnSessionReady(session_id); 744 host_->OnResolvePromise(promise_id);
587 } 745 }
588 746
589 void ClearKeyCdm::OnSessionClosed(uint32 session_id) { 747 void ClearKeyCdm::OnSessionUpdateFailed(
590 host_->OnSessionClosed(session_id); 748 uint32 promise_id,
749 MediaKeys::MediaKeysException exception_code,
750 uint32 system_code,
751 const std::string& error_message) {
752 RejectPromise(promise_id, exception_code, system_code, error_message);
591 } 753 }
592 754
593 void ClearKeyCdm::OnSessionError(uint32 session_id, 755 void ClearKeyCdm::OnSessionReleased(uint32 promise_id,
594 media::MediaKeys::KeyError error_code, 756 const std::string& web_session_id) {
595 uint32 system_code) { 757 host_->OnResolvePromise(promise_id);
596 host_->OnSessionError( 758 }
597 session_id, static_cast<cdm::MediaKeyError>(error_code), system_code); 759
760 void ClearKeyCdm::OnSessionReleaseFailed(
761 uint32 promise_id,
762 MediaKeys::MediaKeysException exception_code,
763 uint32 system_code,
764 const std::string& error_message) {
765 RejectPromise(promise_id, exception_code, system_code, error_message);
766 }
767
768 void ClearKeyCdm::RejectPromise(uint32 promise_id,
769 MediaKeys::MediaKeysException exception_code,
770 uint32 system_code,
771 const std::string& error_message) {
772 host_->OnRejectPromise(promise_id,
773 static_cast<cdm::MediaKeyException>(exception_code),
774 system_code,
775 error_message.data(),
776 error_message.length());
598 } 777 }
599 778
600 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER) 779 #if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
601 int64 ClearKeyCdm::CurrentTimeStampInMicroseconds() const { 780 int64 ClearKeyCdm::CurrentTimeStampInMicroseconds() const {
602 return output_timestamp_base_in_microseconds_ + 781 return output_timestamp_base_in_microseconds_ +
603 base::Time::kMicrosecondsPerSecond * 782 base::Time::kMicrosecondsPerSecond *
604 total_samples_generated_ / samples_per_second_; 783 total_samples_generated_ / samples_per_second_;
605 } 784 }
606 785
607 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration( 786 int ClearKeyCdm::GenerateFakeAudioFramesFromDuration(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
659 void ClearKeyCdm::StartFileIOTest() { 838 void ClearKeyCdm::StartFileIOTest() {
660 file_io_test_runner_.reset(new FileIOTestRunner( 839 file_io_test_runner_.reset(new FileIOTestRunner(
661 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_)))); 840 base::Bind(&ClearKeyCdmHost::CreateFileIO, base::Unretained(host_))));
662 file_io_test_runner_->RunAllTests( 841 file_io_test_runner_->RunAllTests(
663 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this))); 842 base::Bind(&ClearKeyCdm::OnFileIOTestComplete, base::Unretained(this)));
664 } 843 }
665 844
666 void ClearKeyCdm::OnFileIOTestComplete(bool success) { 845 void ClearKeyCdm::OnFileIOTestComplete(bool success) {
667 DVLOG(1) << __FUNCTION__ << ": " << success; 846 DVLOG(1) << __FUNCTION__ << ": " << success;
668 std::string message = GetFileIOTestResultMessage(success); 847 std::string message = GetFileIOTestResultMessage(success);
669 host_->OnSessionMessage( 848 host_->OnSessionMessage(last_session_id_.data(),
670 last_session_id_, message.data(), message.size(), NULL, 0); 849 last_session_id_.length(),
850 message.data(),
851 message.length(),
852 NULL,
853 0);
671 file_io_test_runner_.reset(); 854 file_io_test_runner_.reset();
672 } 855 }
673 856
674 } // namespace media 857 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698