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