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

Side by Side Diff: content/renderer/pepper/content_decryptor_delegate.cc

Issue 265993002: Add Promises for EME (Chromium side) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: comments + fewer error codes Created 6 years, 6 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/renderer/pepper/content_decryptor_delegate.h" 5 #include "content/renderer/pepper/content_decryptor_delegate.h"
6 6
7 #include "base/callback_helpers.h" 7 #include "base/callback_helpers.h"
8 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/message_loop/message_loop_proxy.h" 9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/numerics/safe_conversions.h" 10 #include "base/numerics/safe_conversions.h"
11 #include "content/renderer/pepper/ppb_buffer_impl.h" 11 #include "content/renderer/pepper/ppb_buffer_impl.h"
12 #include "media/base/audio_buffer.h" 12 #include "media/base/audio_buffer.h"
13 #include "media/base/audio_decoder_config.h" 13 #include "media/base/audio_decoder_config.h"
14 #include "media/base/bind_to_current_loop.h" 14 #include "media/base/bind_to_current_loop.h"
15 #include "media/base/cdm_promise.h"
15 #include "media/base/channel_layout.h" 16 #include "media/base/channel_layout.h"
16 #include "media/base/data_buffer.h" 17 #include "media/base/data_buffer.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/base/video_decoder_config.h" 20 #include "media/base/video_decoder_config.h"
20 #include "media/base/video_frame.h" 21 #include "media/base/video_frame.h"
21 #include "media/base/video_util.h" 22 #include "media/base/video_util.h"
22 #include "ppapi/shared_impl/scoped_pp_resource.h" 23 #include "ppapi/shared_impl/scoped_pp_resource.h"
23 #include "ppapi/shared_impl/var.h" 24 #include "ppapi/shared_impl/var.h"
24 #include "ppapi/shared_impl/var_tracker.h" 25 #include "ppapi/shared_impl/var_tracker.h"
25 #include "ppapi/thunk/enter.h" 26 #include "ppapi/thunk/enter.h"
26 #include "ppapi/thunk/ppb_buffer_api.h" 27 #include "ppapi/thunk/ppb_buffer_api.h"
27 #include "ui/gfx/rect.h" 28 #include "ui/gfx/rect.h"
28 29
30 using media::CdmPromise;
29 using media::Decryptor; 31 using media::Decryptor;
32 using media::MediaKeys;
33 using media::NewSessionCdmPromise;
34 using media::SimpleCdmPromise;
30 using ppapi::ArrayBufferVar; 35 using ppapi::ArrayBufferVar;
31 using ppapi::PpapiGlobals; 36 using ppapi::PpapiGlobals;
32 using ppapi::ScopedPPResource; 37 using ppapi::ScopedPPResource;
33 using ppapi::StringVar; 38 using ppapi::StringVar;
34 using ppapi::thunk::EnterResourceNoLock; 39 using ppapi::thunk::EnterResourceNoLock;
35 using ppapi::thunk::PPB_Buffer_API; 40 using ppapi::thunk::PPB_Buffer_API;
36 41
37 namespace content { 42 namespace content {
38 43
39 namespace { 44 namespace {
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_S16: 243 case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_S16:
239 return media::kSampleFormatPlanarS16; 244 return media::kSampleFormatPlanarS16;
240 case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_F32: 245 case PP_DECRYPTEDSAMPLEFORMAT_PLANAR_F32:
241 return media::kSampleFormatPlanarF32; 246 return media::kSampleFormatPlanarF32;
242 default: 247 default:
243 NOTREACHED(); 248 NOTREACHED();
244 return media::kUnknownSampleFormat; 249 return media::kUnknownSampleFormat;
245 } 250 }
246 } 251 }
247 252
253 PP_SessionType MediaSessionTypeToPpSessionType(
254 MediaKeys::SessionType session_type) {
255 switch (session_type) {
256 case MediaKeys::TEMPORARY_SESSION:
257 return PP_SESSIONTYPE_TEMPORARY;
258 case MediaKeys::PERSISTENT_SESSION:
259 return PP_SESSIONTYPE_PERSISTENT;
260 default:
261 NOTREACHED();
262 return PP_SESSIONTYPE_TEMPORARY;
263 }
264 }
265
266 MediaKeys::Exception PpExceptionTypeToMediaException(
267 PP_ExceptionCode exception_code) {
268 switch (exception_code) {
269 case PP_EXCEPTIONCODE_NOTSUPPORTEDERROR:
270 return MediaKeys::NOT_SUPPORTED_ERROR;
271 case PP_EXCEPTIONCODE_INVALIDSTATEERROR:
272 return MediaKeys::INVALID_STATE_ERROR;
273 case PP_EXCEPTIONCODE_INVALIDACCESSERROR:
274 return MediaKeys::INVALID_ACCESS_ERROR;
275 case PP_EXCEPTIONCODE_QUOTAEXCEEDEDERROR:
276 return MediaKeys::QUOTA_EXCEEDED_ERROR;
277 case PP_EXCEPTIONCODE_UNKNOWNERROR:
278 return MediaKeys::UNKNOWN_ERROR;
279 case PP_EXCEPTIONCODE_CLIENTERROR:
280 return MediaKeys::CLIENT_ERROR;
281 case PP_EXCEPTIONCODE_OUTPUTERROR:
282 return MediaKeys::OUTPUT_ERROR;
283 default:
284 NOTREACHED();
285 return MediaKeys::UNKNOWN_ERROR;
286 }
287 }
288
248 } // namespace 289 } // namespace
249 290
250 ContentDecryptorDelegate::ContentDecryptorDelegate( 291 ContentDecryptorDelegate::ContentDecryptorDelegate(
251 PP_Instance pp_instance, 292 PP_Instance pp_instance,
252 const PPP_ContentDecryptor_Private* plugin_decryption_interface) 293 const PPP_ContentDecryptor_Private* plugin_decryption_interface)
253 : pp_instance_(pp_instance), 294 : pp_instance_(pp_instance),
254 plugin_decryption_interface_(plugin_decryption_interface), 295 plugin_decryption_interface_(plugin_decryption_interface),
255 next_decryption_request_id_(1), 296 next_decryption_request_id_(1),
256 audio_samples_per_second_(0), 297 audio_samples_per_second_(0),
257 audio_channel_count_(0), 298 audio_channel_count_(0),
258 audio_channel_layout_(media::CHANNEL_LAYOUT_NONE), 299 audio_channel_layout_(media::CHANNEL_LAYOUT_NONE),
300 next_promise_id_(0),
259 weak_ptr_factory_(this) { 301 weak_ptr_factory_(this) {
260 weak_this_ = weak_ptr_factory_.GetWeakPtr(); 302 weak_this_ = weak_ptr_factory_.GetWeakPtr();
261 } 303 }
262 304
263 ContentDecryptorDelegate::~ContentDecryptorDelegate() { 305 ContentDecryptorDelegate::~ContentDecryptorDelegate() {
264 SatisfyAllPendingCallbacksOnError(); 306 SatisfyAllPendingCallbacksOnError();
265 } 307 }
266 308
267 void ContentDecryptorDelegate::Initialize( 309 void ContentDecryptorDelegate::Initialize(
268 const std::string& key_system, 310 const std::string& key_system,
269 const media::SessionCreatedCB& session_created_cb,
270 const media::SessionMessageCB& session_message_cb, 311 const media::SessionMessageCB& session_message_cb,
271 const media::SessionReadyCB& session_ready_cb, 312 const media::SessionReadyCB& session_ready_cb,
272 const media::SessionClosedCB& session_closed_cb, 313 const media::SessionClosedCB& session_closed_cb,
273 const media::SessionErrorCB& session_error_cb, 314 const media::SessionErrorCB& session_error_cb,
274 const base::Closure& fatal_plugin_error_cb) { 315 const base::Closure& fatal_plugin_error_cb) {
275 DCHECK(!key_system.empty()); 316 DCHECK(!key_system.empty());
276 DCHECK(key_system_.empty()); 317 DCHECK(key_system_.empty());
277 key_system_ = key_system; 318 key_system_ = key_system;
278 319
279 session_created_cb_ = session_created_cb;
280 session_message_cb_ = session_message_cb; 320 session_message_cb_ = session_message_cb;
281 session_ready_cb_ = session_ready_cb; 321 session_ready_cb_ = session_ready_cb;
282 session_closed_cb_ = session_closed_cb; 322 session_closed_cb_ = session_closed_cb;
283 session_error_cb_ = session_error_cb; 323 session_error_cb_ = session_error_cb;
284 fatal_plugin_error_cb_ = fatal_plugin_error_cb; 324 fatal_plugin_error_cb_ = fatal_plugin_error_cb;
285 325
286 plugin_decryption_interface_->Initialize( 326 plugin_decryption_interface_->Initialize(
287 pp_instance_, StringVar::StringToPPVar(key_system_)); 327 pp_instance_, StringVar::StringToPPVar(key_system_));
288 } 328 }
289 329
290 void ContentDecryptorDelegate::InstanceCrashed() { 330 void ContentDecryptorDelegate::InstanceCrashed() {
291 fatal_plugin_error_cb_.Run(); 331 fatal_plugin_error_cb_.Run();
292 SatisfyAllPendingCallbacksOnError(); 332 SatisfyAllPendingCallbacksOnError();
293 } 333 }
294 334
295 bool ContentDecryptorDelegate::CreateSession(uint32 session_id, 335 void ContentDecryptorDelegate::CreateSession(
296 const std::string& content_type, 336 const std::string& init_data_type,
297 const uint8* init_data, 337 const uint8* init_data,
298 int init_data_length) { 338 int init_data_length,
339 MediaKeys::SessionType session_type,
340 scoped_ptr<NewSessionCdmPromise> promise) {
341 uint32_t promise_id = SavePromise(promise.PassAs<CdmPromise>());
299 PP_Var init_data_array = 342 PP_Var init_data_array =
300 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( 343 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
301 init_data_length, init_data); 344 init_data_length, init_data);
302
303 plugin_decryption_interface_->CreateSession( 345 plugin_decryption_interface_->CreateSession(
304 pp_instance_, 346 pp_instance_,
305 session_id, 347 promise_id,
306 StringVar::StringToPPVar(content_type), 348 StringVar::StringToPPVar(init_data_type),
307 init_data_array); 349 init_data_array,
308 return true; 350 MediaSessionTypeToPpSessionType(session_type));
309 } 351 }
310 352
311 void ContentDecryptorDelegate::LoadSession(uint32 session_id, 353 void ContentDecryptorDelegate::LoadSession(
312 const std::string& web_session_id) { 354 const std::string& web_session_id,
355 scoped_ptr<NewSessionCdmPromise> promise) {
356 uint32_t promise_id = SavePromise(promise.PassAs<CdmPromise>());
313 plugin_decryption_interface_->LoadSession( 357 plugin_decryption_interface_->LoadSession(
314 pp_instance_, session_id, StringVar::StringToPPVar(web_session_id)); 358 pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id));
315 } 359 }
316 360
317 bool ContentDecryptorDelegate::UpdateSession(uint32 session_id, 361 void ContentDecryptorDelegate::UpdateSession(
318 const uint8* response, 362 const std::string& web_session_id,
319 int response_length) { 363 const uint8* response,
364 int response_length,
365 scoped_ptr<SimpleCdmPromise> promise) {
366 uint32_t promise_id = SavePromise(promise.PassAs<CdmPromise>());
320 PP_Var response_array = 367 PP_Var response_array =
321 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( 368 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
322 response_length, response); 369 response_length, response);
323 plugin_decryption_interface_->UpdateSession( 370 plugin_decryption_interface_->UpdateSession(
324 pp_instance_, session_id, response_array); 371 pp_instance_,
325 return true; 372 promise_id,
373 StringVar::StringToPPVar(web_session_id),
374 response_array);
326 } 375 }
327 376
328 bool ContentDecryptorDelegate::ReleaseSession(uint32 session_id) { 377 void ContentDecryptorDelegate::ReleaseSession(
329 plugin_decryption_interface_->ReleaseSession(pp_instance_, session_id); 378 const std::string& web_session_id,
330 return true; 379 scoped_ptr<SimpleCdmPromise> promise) {
380 uint32_t promise_id = SavePromise(promise.PassAs<CdmPromise>());
381 plugin_decryption_interface_->ReleaseSession(
382 pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id));
331 } 383 }
332 384
333 // TODO(xhwang): Remove duplication of code in Decrypt(), 385 // TODO(xhwang): Remove duplication of code in Decrypt(),
334 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). 386 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo().
335 bool ContentDecryptorDelegate::Decrypt( 387 bool ContentDecryptorDelegate::Decrypt(
336 Decryptor::StreamType stream_type, 388 Decryptor::StreamType stream_type,
337 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, 389 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer,
338 const Decryptor::DecryptCB& decrypt_cb) { 390 const Decryptor::DecryptCB& decrypt_cb) {
339 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; 391 DVLOG(3) << "Decrypt() - stream_type: " << stream_type;
340 392
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
566 // buffer. 618 // buffer.
567 video_decode_cb_.Set(request_id, video_decode_cb); 619 video_decode_cb_.Set(request_id, video_decode_cb);
568 620
569 // TODO(tomfinegan): Need to get stream type from media stack. 621 // TODO(tomfinegan): Need to get stream type from media stack.
570 ScopedPPResource pp_resource(encrypted_resource.get()); 622 ScopedPPResource pp_resource(encrypted_resource.get());
571 plugin_decryption_interface_->DecryptAndDecode( 623 plugin_decryption_interface_->DecryptAndDecode(
572 pp_instance_, PP_DECRYPTORSTREAMTYPE_VIDEO, pp_resource, &block_info); 624 pp_instance_, PP_DECRYPTORSTREAMTYPE_VIDEO, pp_resource, &block_info);
573 return true; 625 return true;
574 } 626 }
575 627
576 void ContentDecryptorDelegate::OnSessionCreated(uint32 session_id, 628 void ContentDecryptorDelegate::OnPromiseResolved(uint32 promise_id) {
577 PP_Var web_session_id_var) { 629 scoped_ptr<CdmPromise> promise = TakePromise(promise_id);
578 if (session_created_cb_.is_null()) 630 if (promise) {
579 return; 631 SimpleCdmPromise* simple_promise(
580 632 static_cast<SimpleCdmPromise*>(promise.get()));
581 StringVar* session_id_string = StringVar::FromPPVar(web_session_id_var); 633 simple_promise->resolve();
582
583 if (!session_id_string) {
584 OnSessionError(session_id, media::MediaKeys::kUnknownError, 0);
585 return;
586 } 634 }
587
588 session_created_cb_.Run(session_id, session_id_string->value());
589 } 635 }
590 636
591 void ContentDecryptorDelegate::OnSessionMessage(uint32 session_id, 637 void ContentDecryptorDelegate::OnPromiseResolvedWithSession(
592 PP_Var message_var, 638 uint32 promise_id,
593 PP_Var default_url_var) { 639 PP_Var web_session_id) {
594 // TODO(amogh.bihani): Replace all the default_url with destination_url. 640 scoped_ptr<CdmPromise> promise = TakePromise(promise_id);
641
642 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id);
643 DCHECK(web_session_id_string);
644
645 if (promise) {
646 NewSessionCdmPromise* session_promise(
647 static_cast<NewSessionCdmPromise*>(promise.get()));
648 session_promise->resolve(web_session_id_string->value());
649 }
650 }
651
652 void ContentDecryptorDelegate::OnPromiseRejected(
653 uint32 promise_id,
654 PP_ExceptionCode exception_code,
655 uint32 system_code,
656 PP_Var error_description) {
657 StringVar* error_description_string = StringVar::FromPPVar(error_description);
658 DCHECK(error_description_string);
659
660 scoped_ptr<CdmPromise> promise = TakePromise(promise_id);
661 if (promise) {
662 promise->reject(PpExceptionTypeToMediaException(exception_code),
663 system_code,
664 error_description_string->value());
665 }
666 }
667
668 void ContentDecryptorDelegate::OnSessionMessage(PP_Var web_session_id,
669 PP_Var message,
670 PP_Var destination_url) {
595 if (session_message_cb_.is_null()) 671 if (session_message_cb_.is_null())
596 return; 672 return;
597 673
598 ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message_var); 674 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id);
675 DCHECK(web_session_id_string);
599 676
600 std::vector<uint8> message; 677 ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message);
678 std::vector<uint8> message_vector;
601 if (message_array_buffer) { 679 if (message_array_buffer) {
602 const uint8* data = static_cast<const uint8*>(message_array_buffer->Map()); 680 const uint8* data = static_cast<const uint8*>(message_array_buffer->Map());
603 message.assign(data, data + message_array_buffer->ByteLength()); 681 message_vector.assign(data, data + message_array_buffer->ByteLength());
604 } 682 }
605 683
606 StringVar* default_url_string = StringVar::FromPPVar(default_url_var); 684 StringVar* destination_url_string = StringVar::FromPPVar(destination_url);
685 DCHECK(destination_url_string);
607 686
608 if (!default_url_string) { 687 GURL verified_gurl = GURL(destination_url_string->value());
609 OnSessionError(session_id, media::MediaKeys::kUnknownError, 0);
610 return;
611 }
612
613 GURL verified_gurl = GURL(default_url_string->value());
614 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) { 688 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) {
615 DLOG(WARNING) << "SessionMessage default_url is invalid : " 689 DLOG(WARNING) << "SessionMessage default_url is invalid : "
616 << verified_gurl.possibly_invalid_spec(); 690 << verified_gurl.possibly_invalid_spec();
617 verified_gurl = GURL::EmptyGURL(); // Replace invalid default_url. 691 verified_gurl = GURL::EmptyGURL(); // Replace invalid default_url.
618 } 692 }
619 693
620 session_message_cb_.Run(session_id, message, verified_gurl); 694 session_message_cb_.Run(
695 web_session_id_string->value(), message_vector, verified_gurl);
621 } 696 }
622 697
623 void ContentDecryptorDelegate::OnSessionReady(uint32 session_id) { 698 void ContentDecryptorDelegate::OnSessionReady(PP_Var web_session_id) {
624 if (session_ready_cb_.is_null()) 699 if (session_ready_cb_.is_null())
625 return; 700 return;
626 701
627 session_ready_cb_.Run(session_id); 702 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id);
703 DCHECK(web_session_id_string);
704
705 session_ready_cb_.Run(web_session_id_string->value());
628 } 706 }
629 707
630 void ContentDecryptorDelegate::OnSessionClosed(uint32 session_id) { 708 void ContentDecryptorDelegate::OnSessionClosed(PP_Var web_session_id) {
631 if (session_closed_cb_.is_null()) 709 if (session_closed_cb_.is_null())
632 return; 710 return;
633 711
634 session_closed_cb_.Run(session_id); 712 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id);
713 DCHECK(web_session_id_string);
714
715 session_closed_cb_.Run(web_session_id_string->value());
635 } 716 }
636 717
637 void ContentDecryptorDelegate::OnSessionError(uint32 session_id, 718 void ContentDecryptorDelegate::OnSessionError(PP_Var web_session_id,
638 int32_t media_error, 719 PP_ExceptionCode exception_code,
639 uint32_t system_code) { 720 uint32 system_code,
721 PP_Var error_description) {
640 if (session_error_cb_.is_null()) 722 if (session_error_cb_.is_null())
641 return; 723 return;
642 724
643 session_error_cb_.Run(session_id, 725 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id);
644 static_cast<media::MediaKeys::KeyError>(media_error), 726 DCHECK(web_session_id_string);
645 system_code); 727
728 StringVar* error_description_string = StringVar::FromPPVar(error_description);
729 DCHECK(error_description_string);
730
731 session_error_cb_.Run(web_session_id_string->value(),
732 PpExceptionTypeToMediaException(exception_code),
733 system_code,
734 error_description_string->value());
646 } 735 }
647 736
648 void ContentDecryptorDelegate::DecoderInitializeDone( 737 void ContentDecryptorDelegate::DecoderInitializeDone(
649 PP_DecryptorStreamType decoder_type, 738 PP_DecryptorStreamType decoder_type,
650 uint32_t request_id, 739 uint32_t request_id,
651 PP_Bool success) { 740 PP_Bool success) {
652 if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) { 741 if (decoder_type == PP_DECRYPTORSTREAMTYPE_AUDIO) {
653 // If the request ID is not valid or does not match what's saved, do 742 // If the request ID is not valid or does not match what's saved, do
654 // nothing. 743 // nothing.
655 if (request_id == 0 || !audio_decoder_init_cb_.Matches(request_id)) 744 if (request_id == 0 || !audio_decoder_init_cb_.Matches(request_id))
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
1061 video_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); 1150 video_decrypt_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL);
1062 1151
1063 if (!audio_decode_cb_.is_null()) { 1152 if (!audio_decode_cb_.is_null()) {
1064 const media::Decryptor::AudioBuffers empty_frames; 1153 const media::Decryptor::AudioBuffers empty_frames;
1065 audio_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, 1154 audio_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError,
1066 empty_frames); 1155 empty_frames);
1067 } 1156 }
1068 1157
1069 if (!video_decode_cb_.is_null()) 1158 if (!video_decode_cb_.is_null())
1070 video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL); 1159 video_decode_cb_.ResetAndReturn().Run(media::Decryptor::kError, NULL);
1160
1161 // TODO(jrummell): Reject all outstanding promises. Currently some tests
1162 // (ECKEncryptedMediaTest.CDMExpectedCrash and CDMCrashDuringDecode)
1163 // trigger a crash in the CDM, and don't handle the response to the pending
1164 // request. Once blink:: uses promises, this will be required.
1165 }
1166
1167 uint32_t ContentDecryptorDelegate::SavePromise(scoped_ptr<CdmPromise> promise) {
1168 uint32_t promise_id = ++next_promise_id_;
xhwang 2014/05/29 23:44:38 When we use next_promise_id_, we usually do next_p
jrummell 2014/05/30 18:04:25 Done. 0 is not invalid, but it is probably best to
1169 promises_.add(promise_id, promise.Pass());
1170 return promise_id;
1171 }
1172
1173 scoped_ptr<CdmPromise> ContentDecryptorDelegate::TakePromise(
1174 uint32_t promise_id) {
xhwang 2014/05/29 23:44:38 nit: does this fit in one line now?
jrummell 2014/05/30 18:04:25 Nope. 3 characters too long.
1175 PromiseMap::iterator it = promises_.find(promise_id);
1176 if (it == promises_.end())
1177 return scoped_ptr<CdmPromise>();
1178 return promises_.take_and_erase(it).Pass();
1071 } 1179 }
1072 1180
1073 } // namespace content 1181 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698