OLD | NEW |
---|---|
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/metrics/sparse_histogram.h" | 10 #include "base/metrics/sparse_histogram.h" |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 return media::kUnknownSampleFormat; | 254 return media::kUnknownSampleFormat; |
255 } | 255 } |
256 } | 256 } |
257 | 257 |
258 PP_SessionType MediaSessionTypeToPpSessionType( | 258 PP_SessionType MediaSessionTypeToPpSessionType( |
259 MediaKeys::SessionType session_type) { | 259 MediaKeys::SessionType session_type) { |
260 switch (session_type) { | 260 switch (session_type) { |
261 case MediaKeys::TEMPORARY_SESSION: | 261 case MediaKeys::TEMPORARY_SESSION: |
262 return PP_SESSIONTYPE_TEMPORARY; | 262 return PP_SESSIONTYPE_TEMPORARY; |
263 case MediaKeys::PERSISTENT_SESSION: | 263 case MediaKeys::PERSISTENT_SESSION: |
264 return PP_SESSIONTYPE_PERSISTENT; | 264 return PP_SESSIONTYPE_PERSISTENT_LICENSE; |
ddorwin
2014/12/17 01:01:14
Add the new type too. I guess a TODO for now.
jrummell
2014/12/17 19:17:19
Done.
| |
265 default: | 265 default: |
266 NOTREACHED(); | 266 NOTREACHED(); |
267 return PP_SESSIONTYPE_TEMPORARY; | 267 return PP_SESSIONTYPE_TEMPORARY; |
268 } | 268 } |
269 } | 269 } |
270 | 270 |
271 MediaKeys::Exception PpExceptionTypeToMediaException( | 271 MediaKeys::Exception PpExceptionTypeToMediaException( |
272 PP_CdmExceptionCode exception_code) { | 272 PP_CdmExceptionCode exception_code) { |
273 switch (exception_code) { | 273 switch (exception_code) { |
274 case PP_CDMEXCEPTIONCODE_NOTSUPPORTEDERROR: | 274 case PP_CDMEXCEPTIONCODE_NOTSUPPORTEDERROR: |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
314 audio_channel_layout_(media::CHANNEL_LAYOUT_NONE), | 314 audio_channel_layout_(media::CHANNEL_LAYOUT_NONE), |
315 next_promise_id_(1), | 315 next_promise_id_(1), |
316 weak_ptr_factory_(this) { | 316 weak_ptr_factory_(this) { |
317 weak_this_ = weak_ptr_factory_.GetWeakPtr(); | 317 weak_this_ = weak_ptr_factory_.GetWeakPtr(); |
318 } | 318 } |
319 | 319 |
320 ContentDecryptorDelegate::~ContentDecryptorDelegate() { | 320 ContentDecryptorDelegate::~ContentDecryptorDelegate() { |
321 SatisfyAllPendingCallbacksOnError(); | 321 SatisfyAllPendingCallbacksOnError(); |
322 } | 322 } |
323 | 323 |
324 // TODO(jrummell): Remove |session_ready_cb| and |session_keys_change_cb|. | |
324 void ContentDecryptorDelegate::Initialize( | 325 void ContentDecryptorDelegate::Initialize( |
325 const std::string& key_system, | 326 const std::string& key_system, |
326 const media::SessionMessageCB& session_message_cb, | 327 const media::SessionMessageCB& session_message_cb, |
327 const media::SessionReadyCB& session_ready_cb, | 328 const media::SessionReadyCB& session_ready_cb, |
328 const media::SessionClosedCB& session_closed_cb, | 329 const media::SessionClosedCB& session_closed_cb, |
329 const media::SessionErrorCB& session_error_cb, | 330 const media::SessionErrorCB& session_error_cb, |
330 const media::SessionKeysChangeCB& session_keys_change_cb, | 331 const media::SessionKeysChangeCB& session_keys_change_cb, |
331 const media::SessionExpirationUpdateCB& session_expiration_update_cb, | 332 const media::SessionExpirationUpdateCB& session_expiration_update_cb, |
332 const base::Closure& fatal_plugin_error_cb) { | 333 const base::Closure& fatal_plugin_error_cb) { |
333 DCHECK(!key_system.empty()); | 334 DCHECK(!key_system.empty()); |
(...skipping 30 matching lines...) Expand all Loading... | |
364 } | 365 } |
365 | 366 |
366 uint32_t promise_id = SavePromise(promise.Pass()); | 367 uint32_t promise_id = SavePromise(promise.Pass()); |
367 PP_Var certificate_array = | 368 PP_Var certificate_array = |
368 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 369 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
369 certificate_length, certificate); | 370 certificate_length, certificate); |
370 plugin_decryption_interface_->SetServerCertificate( | 371 plugin_decryption_interface_->SetServerCertificate( |
371 pp_instance_, promise_id, certificate_array); | 372 pp_instance_, promise_id, certificate_array); |
372 } | 373 } |
373 | 374 |
375 // TODO(jrummell): Rename method and reorder parameter list. | |
374 void ContentDecryptorDelegate::CreateSession( | 376 void ContentDecryptorDelegate::CreateSession( |
375 const std::string& init_data_type, | 377 const std::string& init_data_type, |
376 const uint8* init_data, | 378 const uint8* init_data, |
377 int init_data_length, | 379 int init_data_length, |
378 MediaKeys::SessionType session_type, | 380 MediaKeys::SessionType session_type, |
379 scoped_ptr<NewSessionCdmPromise> promise) { | 381 scoped_ptr<NewSessionCdmPromise> promise) { |
380 uint32_t promise_id = SavePromise(promise.Pass()); | 382 uint32_t promise_id = SavePromise(promise.Pass()); |
381 PP_Var init_data_array = | 383 PP_Var init_data_array = |
382 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 384 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
383 init_data_length, init_data); | 385 init_data_length, init_data); |
384 plugin_decryption_interface_->CreateSession( | 386 plugin_decryption_interface_->CreateSessionAndGenerateRequest( |
385 pp_instance_, | 387 pp_instance_, promise_id, MediaSessionTypeToPpSessionType(session_type), |
386 promise_id, | 388 StringVar::StringToPPVar(init_data_type), init_data_array); |
387 StringVar::StringToPPVar(init_data_type), | |
388 init_data_array, | |
389 MediaSessionTypeToPpSessionType(session_type)); | |
390 } | 389 } |
391 | 390 |
391 // TODO(jrummell): Pass |session_type| to this method. | |
392 void ContentDecryptorDelegate::LoadSession( | 392 void ContentDecryptorDelegate::LoadSession( |
393 const std::string& web_session_id, | 393 const std::string& web_session_id, |
394 scoped_ptr<NewSessionCdmPromise> promise) { | 394 scoped_ptr<NewSessionCdmPromise> promise) { |
395 uint32_t promise_id = SavePromise(promise.Pass()); | 395 uint32_t promise_id = SavePromise(promise.Pass()); |
396 plugin_decryption_interface_->LoadSession( | 396 plugin_decryption_interface_->LoadSession( |
397 pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id)); | 397 pp_instance_, promise_id, PP_SESSIONTYPE_TEMPORARY, |
ddorwin
2014/12/17 01:01:15
PP_SESSIONTYPE_PERSISTENT_LICENSE
jrummell
2014/12/17 19:17:19
Done.
| |
398 StringVar::StringToPPVar(web_session_id)); | |
398 } | 399 } |
399 | 400 |
400 void ContentDecryptorDelegate::UpdateSession( | 401 void ContentDecryptorDelegate::UpdateSession( |
401 const std::string& web_session_id, | 402 const std::string& web_session_id, |
402 const uint8* response, | 403 const uint8* response, |
403 int response_length, | 404 int response_length, |
404 scoped_ptr<SimpleCdmPromise> promise) { | 405 scoped_ptr<SimpleCdmPromise> promise) { |
405 uint32_t promise_id = SavePromise(promise.Pass()); | 406 uint32_t promise_id = SavePromise(promise.Pass()); |
406 PP_Var response_array = | 407 PP_Var response_array = |
407 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( | 408 PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar( |
(...skipping 26 matching lines...) Expand all Loading... | |
434 promise->reject( | 435 promise->reject( |
435 media::MediaKeys::INVALID_ACCESS_ERROR, 0, "Incorrect session."); | 436 media::MediaKeys::INVALID_ACCESS_ERROR, 0, "Incorrect session."); |
436 return; | 437 return; |
437 } | 438 } |
438 | 439 |
439 uint32_t promise_id = SavePromise(promise.Pass()); | 440 uint32_t promise_id = SavePromise(promise.Pass()); |
440 plugin_decryption_interface_->RemoveSession( | 441 plugin_decryption_interface_->RemoveSession( |
441 pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id)); | 442 pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id)); |
442 } | 443 } |
443 | 444 |
445 // TODO(jrummell): Remove this method. | |
444 void ContentDecryptorDelegate::GetUsableKeyIds( | 446 void ContentDecryptorDelegate::GetUsableKeyIds( |
445 const std::string& web_session_id, | 447 const std::string& web_session_id, |
446 scoped_ptr<media::KeyIdsPromise> promise) { | 448 scoped_ptr<media::KeyIdsPromise> promise) { |
447 if (web_session_id.length() > media::limits::kMaxWebSessionIdLength) { | 449 NOTREACHED(); |
448 promise->reject( | |
449 media::MediaKeys::INVALID_ACCESS_ERROR, 0, "Incorrect session."); | |
450 return; | |
451 } | |
452 | |
453 uint32_t promise_id = SavePromise(promise.Pass()); | |
454 plugin_decryption_interface_->GetUsableKeyIds( | |
455 pp_instance_, promise_id, StringVar::StringToPPVar(web_session_id)); | |
456 } | 450 } |
457 | 451 |
458 // TODO(xhwang): Remove duplication of code in Decrypt(), | 452 // TODO(xhwang): Remove duplication of code in Decrypt(), |
459 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). | 453 // DecryptAndDecodeAudio() and DecryptAndDecodeVideo(). |
460 bool ContentDecryptorDelegate::Decrypt( | 454 bool ContentDecryptorDelegate::Decrypt( |
461 Decryptor::StreamType stream_type, | 455 Decryptor::StreamType stream_type, |
462 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, | 456 const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, |
463 const Decryptor::DecryptCB& decrypt_cb) { | 457 const Decryptor::DecryptCB& decrypt_cb) { |
464 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; | 458 DVLOG(3) << "Decrypt() - stream_type: " << stream_type; |
465 | 459 |
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
722 } | 716 } |
723 | 717 |
724 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); | 718 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); |
725 DCHECK(web_session_id_string); | 719 DCHECK(web_session_id_string); |
726 | 720 |
727 NewSessionCdmPromise* session_promise = | 721 NewSessionCdmPromise* session_promise = |
728 static_cast<NewSessionCdmPromise*>(promise.get()); | 722 static_cast<NewSessionCdmPromise*>(promise.get()); |
729 session_promise->resolve(web_session_id_string->value()); | 723 session_promise->resolve(web_session_id_string->value()); |
730 } | 724 } |
731 | 725 |
732 void ContentDecryptorDelegate::OnPromiseResolvedWithKeyIds( | |
733 uint32 promise_id, | |
734 PP_Var key_ids_array) { | |
735 scoped_ptr<CdmPromise> promise = TakePromise(promise_id); | |
736 | |
737 ArrayVar* key_ids = ArrayVar::FromPPVar(key_ids_array); | |
738 DCHECK(key_ids && key_ids->GetLength() <= media::limits::kMaxKeyIds); | |
739 media::KeyIdsVector key_ids_vector; | |
740 if (key_ids && key_ids->GetLength() <= media::limits::kMaxKeyIds) { | |
741 for (size_t i = 0; i < key_ids->GetLength(); ++i) { | |
742 ArrayBufferVar* array_buffer = ArrayBufferVar::FromPPVar(key_ids->Get(i)); | |
743 | |
744 if (!array_buffer || | |
745 array_buffer->ByteLength() < media::limits::kMinKeyIdLength || | |
746 array_buffer->ByteLength() > media::limits::kMaxKeyIdLength) { | |
747 NOTREACHED(); | |
748 continue; | |
749 } | |
750 | |
751 std::vector<uint8> key_id; | |
752 const uint8* data = static_cast<const uint8*>(array_buffer->Map()); | |
753 key_id.assign(data, data + array_buffer->ByteLength()); | |
754 key_ids_vector.push_back(key_id); | |
755 } | |
756 } | |
757 | |
758 if (!promise || | |
759 promise->GetResolveParameterType() != | |
760 media::CdmPromise::KEY_IDS_VECTOR_TYPE) { | |
761 NOTREACHED(); | |
762 return; | |
763 } | |
764 | |
765 KeyIdsPromise* key_ids_promise(static_cast<KeyIdsPromise*>(promise.get())); | |
766 key_ids_promise->resolve(key_ids_vector); | |
767 } | |
768 | |
769 void ContentDecryptorDelegate::OnPromiseRejected( | 726 void ContentDecryptorDelegate::OnPromiseRejected( |
770 uint32 promise_id, | 727 uint32 promise_id, |
771 PP_CdmExceptionCode exception_code, | 728 PP_CdmExceptionCode exception_code, |
772 uint32 system_code, | 729 uint32 system_code, |
773 PP_Var error_description) { | 730 PP_Var error_description) { |
774 ReportSystemCodeUMA(key_system_, system_code); | 731 ReportSystemCodeUMA(key_system_, system_code); |
775 | 732 |
776 StringVar* error_description_string = StringVar::FromPPVar(error_description); | 733 StringVar* error_description_string = StringVar::FromPPVar(error_description); |
777 DCHECK(error_description_string); | 734 DCHECK(error_description_string); |
778 | 735 |
779 scoped_ptr<CdmPromise> promise = TakePromise(promise_id); | 736 scoped_ptr<CdmPromise> promise = TakePromise(promise_id); |
780 DCHECK(promise); | 737 DCHECK(promise); |
781 if (promise) { | 738 if (promise) { |
782 promise->reject(PpExceptionTypeToMediaException(exception_code), | 739 promise->reject(PpExceptionTypeToMediaException(exception_code), |
783 system_code, | 740 system_code, |
784 error_description_string->value()); | 741 error_description_string->value()); |
785 } | 742 } |
786 } | 743 } |
787 | 744 |
745 // TODO(jrummell): Pass |message_type| to the callback. | |
788 void ContentDecryptorDelegate::OnSessionMessage(PP_Var web_session_id, | 746 void ContentDecryptorDelegate::OnSessionMessage(PP_Var web_session_id, |
789 PP_Var message, | 747 PP_MessageType message_type, |
790 PP_Var destination_url) { | 748 PP_Var message) { |
791 if (session_message_cb_.is_null()) | 749 if (session_message_cb_.is_null()) |
792 return; | 750 return; |
793 | 751 |
794 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); | 752 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); |
795 DCHECK(web_session_id_string); | 753 DCHECK(web_session_id_string); |
796 | 754 |
797 ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message); | 755 ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message); |
798 std::vector<uint8> message_vector; | 756 std::vector<uint8> message_vector; |
799 if (message_array_buffer) { | 757 if (message_array_buffer) { |
800 const uint8* data = static_cast<const uint8*>(message_array_buffer->Map()); | 758 const uint8* data = static_cast<const uint8*>(message_array_buffer->Map()); |
801 message_vector.assign(data, data + message_array_buffer->ByteLength()); | 759 message_vector.assign(data, data + message_array_buffer->ByteLength()); |
802 } | 760 } |
803 | 761 |
804 StringVar* destination_url_string = StringVar::FromPPVar(destination_url); | 762 session_message_cb_.Run(web_session_id_string->value(), message_vector, |
805 DCHECK(destination_url_string); | 763 GURL::EmptyGURL()); |
806 | |
807 GURL verified_gurl = GURL(destination_url_string->value()); | |
808 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) { | |
809 DLOG(WARNING) << "SessionMessage default_url is invalid : " | |
810 << verified_gurl.possibly_invalid_spec(); | |
811 verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url. | |
812 } | |
813 | |
814 session_message_cb_.Run( | |
815 web_session_id_string->value(), message_vector, verified_gurl); | |
816 } | 764 } |
817 | 765 |
766 // TODO(jrummell): Decode |key_information| and pass it to the callback. | |
818 void ContentDecryptorDelegate::OnSessionKeysChange( | 767 void ContentDecryptorDelegate::OnSessionKeysChange( |
819 PP_Var web_session_id, | 768 PP_Var web_session_id, |
820 PP_Bool has_additional_usable_key) { | 769 PP_Bool has_additional_usable_key, |
770 PP_Var key_information) { | |
821 if (session_keys_change_cb_.is_null()) | 771 if (session_keys_change_cb_.is_null()) |
822 return; | 772 return; |
823 | 773 |
824 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); | 774 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); |
825 DCHECK(web_session_id_string); | 775 DCHECK(web_session_id_string); |
826 | 776 |
827 session_keys_change_cb_.Run(web_session_id_string->value(), | 777 session_keys_change_cb_.Run(web_session_id_string->value(), |
828 PP_ToBool(has_additional_usable_key)); | 778 PP_ToBool(has_additional_usable_key)); |
829 } | 779 } |
830 | 780 |
831 void ContentDecryptorDelegate::OnSessionExpirationChange( | 781 void ContentDecryptorDelegate::OnSessionExpirationChange( |
832 PP_Var web_session_id, | 782 PP_Var web_session_id, |
833 PP_Time new_expiry_time) { | 783 PP_Time new_expiry_time) { |
834 if (session_expiration_update_cb_.is_null()) | 784 if (session_expiration_update_cb_.is_null()) |
835 return; | 785 return; |
836 | 786 |
837 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); | 787 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); |
838 DCHECK(web_session_id_string); | 788 DCHECK(web_session_id_string); |
839 | 789 |
840 session_expiration_update_cb_.Run(web_session_id_string->value(), | 790 session_expiration_update_cb_.Run(web_session_id_string->value(), |
841 ppapi::PPTimeToTime(new_expiry_time)); | 791 ppapi::PPTimeToTime(new_expiry_time)); |
842 } | 792 } |
843 | 793 |
844 void ContentDecryptorDelegate::OnSessionReady(PP_Var web_session_id) { | |
845 if (session_ready_cb_.is_null()) | |
846 return; | |
847 | |
848 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); | |
849 DCHECK(web_session_id_string); | |
850 | |
851 session_ready_cb_.Run(web_session_id_string->value()); | |
852 } | |
853 | |
854 void ContentDecryptorDelegate::OnSessionClosed(PP_Var web_session_id) { | 794 void ContentDecryptorDelegate::OnSessionClosed(PP_Var web_session_id) { |
855 if (session_closed_cb_.is_null()) | 795 if (session_closed_cb_.is_null()) |
856 return; | 796 return; |
857 | 797 |
858 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); | 798 StringVar* web_session_id_string = StringVar::FromPPVar(web_session_id); |
859 DCHECK(web_session_id_string); | 799 DCHECK(web_session_id_string); |
860 | 800 |
861 session_closed_cb_.Run(web_session_id_string->value()); | 801 session_closed_cb_.Run(web_session_id_string->value()); |
862 } | 802 } |
863 | 803 |
(...skipping 460 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1324 | 1264 |
1325 scoped_ptr<CdmPromise> ContentDecryptorDelegate::TakePromise( | 1265 scoped_ptr<CdmPromise> ContentDecryptorDelegate::TakePromise( |
1326 uint32_t promise_id) { | 1266 uint32_t promise_id) { |
1327 PromiseMap::iterator it = promises_.find(promise_id); | 1267 PromiseMap::iterator it = promises_.find(promise_id); |
1328 if (it == promises_.end()) | 1268 if (it == promises_.end()) |
1329 return scoped_ptr<CdmPromise>(); | 1269 return scoped_ptr<CdmPromise>(); |
1330 return promises_.take_and_erase(it); | 1270 return promises_.take_and_erase(it); |
1331 } | 1271 } |
1332 | 1272 |
1333 } // namespace content | 1273 } // namespace content |
OLD | NEW |