Chromium Code Reviews| 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 |