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

Side by Side Diff: media/cdm/ppapi/cdm_wrapper.cc

Issue 23546014: Plumb PPAPI PlatformVerification into CDM.h (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove delayed requests. Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | media/cdm/ppapi/clear_key_cdm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <cstring> 5 #include <cstring>
6 #include <map> 6 #include <map>
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/basictypes.h" 11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h" 12 #include "base/compiler_specific.h"
13 #include "build/build_config.h"
13 #include "media/cdm/ppapi/api/content_decryption_module.h" 14 #include "media/cdm/ppapi/api/content_decryption_module.h"
14 #include "media/cdm/ppapi/linked_ptr.h" 15 #include "media/cdm/ppapi/linked_ptr.h"
15 #include "ppapi/c/pp_errors.h" 16 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/c/pp_stdint.h" 17 #include "ppapi/c/pp_stdint.h"
17 #include "ppapi/c/private/pp_content_decryptor.h" 18 #include "ppapi/c/private/pp_content_decryptor.h"
18 #include "ppapi/cpp/completion_callback.h" 19 #include "ppapi/cpp/completion_callback.h"
19 #include "ppapi/cpp/core.h" 20 #include "ppapi/cpp/core.h"
20 #include "ppapi/cpp/dev/buffer_dev.h" 21 #include "ppapi/cpp/dev/buffer_dev.h"
21 #include "ppapi/cpp/instance.h" 22 #include "ppapi/cpp/instance.h"
22 #include "ppapi/cpp/logging.h" 23 #include "ppapi/cpp/logging.h"
23 #include "ppapi/cpp/module.h" 24 #include "ppapi/cpp/module.h"
24 #include "ppapi/cpp/pass_ref.h" 25 #include "ppapi/cpp/pass_ref.h"
25 #include "ppapi/cpp/private/content_decryptor_private.h" 26 #include "ppapi/cpp/private/content_decryptor_private.h"
26 #include "ppapi/cpp/resource.h" 27 #include "ppapi/cpp/resource.h"
27 #include "ppapi/cpp/var.h" 28 #include "ppapi/cpp/var.h"
28 #include "ppapi/cpp/var_array_buffer.h" 29 #include "ppapi/cpp/var_array_buffer.h"
29 #include "ppapi/utility/completion_callback_factory.h" 30 #include "ppapi/utility/completion_callback_factory.h"
30 31
31 #if defined(CHECK_DOCUMENT_URL) 32 #if defined(CHECK_DOCUMENT_URL)
32 #include "ppapi/cpp/dev/url_util_dev.h" 33 #include "ppapi/cpp/dev/url_util_dev.h"
33 #include "ppapi/cpp/instance_handle.h" 34 #include "ppapi/cpp/instance_handle.h"
34 #endif // defined(CHECK_DOCUMENT_URL) 35 #endif // defined(CHECK_DOCUMENT_URL)
35 36
37 #if defined(OS_CHROMEOS)
38 #include "ppapi/cpp/private/platform_verification.h"
39 #endif
40
36 namespace { 41 namespace {
37 42
38 bool IsMainThread() { 43 bool IsMainThread() {
39 return pp::Module::Get()->core()->IsMainThread(); 44 return pp::Module::Get()->core()->IsMainThread();
40 } 45 }
41 46
42 // Posts a task to run |cb| on the main thread. The task is posted even if the 47 // Posts a task to run |cb| on the main thread. The task is posted even if the
43 // current thread is the main thread. 48 // current thread is the main thread.
44 void PostOnMain(pp::CompletionCallback cb) { 49 void PostOnMain(pp::CompletionCallback cb) {
45 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK); 50 pp::Module::Get()->core()->CallOnMainThread(0, cb, PP_OK);
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after
478 DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl); 483 DISALLOW_COPY_AND_ASSIGN(AudioFramesImpl);
479 }; 484 };
480 485
481 // GetCdmHostFunc implementation. 486 // GetCdmHostFunc implementation.
482 void* GetCdmHost(int host_interface_version, void* user_data); 487 void* GetCdmHost(int host_interface_version, void* user_data);
483 488
484 // A wrapper class for abstracting away PPAPI interaction and threading for a 489 // A wrapper class for abstracting away PPAPI interaction and threading for a
485 // Content Decryption Module (CDM). 490 // Content Decryption Module (CDM).
486 class CdmWrapper : public pp::Instance, 491 class CdmWrapper : public pp::Instance,
487 public pp::ContentDecryptor_Private, 492 public pp::ContentDecryptor_Private,
488 public cdm::Host { 493 public cdm::Host_1,
494 public cdm::Host_2 {
489 public: 495 public:
490 CdmWrapper(PP_Instance instance, pp::Module* module); 496 CdmWrapper(PP_Instance instance, pp::Module* module);
491 virtual ~CdmWrapper(); 497 virtual ~CdmWrapper();
492 498
493 // pp::Instance implementation. 499 // pp::Instance implementation.
494 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) { 500 virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]) {
495 return true; 501 return true;
496 } 502 }
497 503
498 // PPP_ContentDecryptor_Private implementation. 504 // PPP_ContentDecryptor_Private implementation.
(...skipping 18 matching lines...) Expand all
517 pp::Buffer_Dev extra_data_buffer) OVERRIDE; 523 pp::Buffer_Dev extra_data_buffer) OVERRIDE;
518 virtual void DeinitializeDecoder(PP_DecryptorStreamType decoder_type, 524 virtual void DeinitializeDecoder(PP_DecryptorStreamType decoder_type,
519 uint32_t request_id) OVERRIDE; 525 uint32_t request_id) OVERRIDE;
520 virtual void ResetDecoder(PP_DecryptorStreamType decoder_type, 526 virtual void ResetDecoder(PP_DecryptorStreamType decoder_type,
521 uint32_t request_id) OVERRIDE; 527 uint32_t request_id) OVERRIDE;
522 virtual void DecryptAndDecode( 528 virtual void DecryptAndDecode(
523 PP_DecryptorStreamType decoder_type, 529 PP_DecryptorStreamType decoder_type,
524 pp::Buffer_Dev encrypted_buffer, 530 pp::Buffer_Dev encrypted_buffer,
525 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; 531 const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
526 532
527 // cdm::Host implementation. 533 // cdm::Host_1 implementation.
528 virtual cdm::Buffer* Allocate(int32_t capacity) OVERRIDE; 534 virtual cdm::Buffer* Allocate(int32_t capacity) OVERRIDE;
529 virtual void SetTimer(int64_t delay_ms, void* context) OVERRIDE; 535 virtual void SetTimer(int64_t delay_ms, void* context) OVERRIDE;
530 virtual double GetCurrentWallTimeInSeconds() OVERRIDE; 536 virtual double GetCurrentWallTimeInSeconds() OVERRIDE;
531 virtual void SendKeyMessage( 537 virtual void SendKeyMessage(
532 const char* session_id, int32_t session_id_length, 538 const char* session_id, int32_t session_id_length,
533 const char* message, int32_t message_length, 539 const char* message, int32_t message_length,
534 const char* default_url, int32_t default_url_length) OVERRIDE; 540 const char* default_url, int32_t default_url_length) OVERRIDE;
535 virtual void SendKeyError(const char* session_id, 541 virtual void SendKeyError(const char* session_id,
536 int32_t session_id_length, 542 int32_t session_id_length,
537 cdm::MediaKeyError error_code, 543 cdm::MediaKeyError error_code,
538 uint32_t system_code) OVERRIDE; 544 uint32_t system_code) OVERRIDE;
539 virtual void GetPrivateData(int32_t* instance, 545 virtual void GetPrivateData(int32_t* instance,
540 GetPrivateInterface* get_interface) OVERRIDE; 546 GetPrivateInterface* get_interface) OVERRIDE;
541 547
548 // cdm::Host_2 implementation.
549 virtual void SendPlatformChallenge(
550 const char* service_id, int32_t service_id_length,
551 const char* challenge, int32_t challenge_length) OVERRIDE;
552 virtual void EnableOutputProtection(
553 uint32_t desired_protection_mask) OVERRIDE;
554 virtual void QueryOutputProtectionStatus() OVERRIDE;
555
542 private: 556 private:
543 struct SessionInfo { 557 struct SessionInfo {
544 SessionInfo(const std::string& key_system_in, 558 SessionInfo(const std::string& key_system_in,
545 const std::string& session_id_in) 559 const std::string& session_id_in)
546 : key_system(key_system_in), 560 : key_system(key_system_in),
547 session_id(session_id_in) {} 561 session_id(session_id_in) {}
548 const std::string key_system; 562 const std::string key_system;
549 const std::string session_id; 563 const std::string session_id;
550 }; 564 };
551 565
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 void DeliverSamples(int32_t result, 613 void DeliverSamples(int32_t result,
600 const cdm::Status& status, 614 const cdm::Status& status,
601 const LinkedAudioFrames& audio_frames, 615 const LinkedAudioFrames& audio_frames,
602 const PP_DecryptTrackingInfo& tracking_info); 616 const PP_DecryptTrackingInfo& tracking_info);
603 617
604 // Helper for SetTimer(). 618 // Helper for SetTimer().
605 void TimerExpired(int32_t result, void* context); 619 void TimerExpired(int32_t result, void* context);
606 620
607 bool IsValidVideoFrame(const LinkedVideoFrame& video_frame); 621 bool IsValidVideoFrame(const LinkedVideoFrame& video_frame);
608 622
623 #if defined(OS_CHROMEOS)
624 bool CanChallengePlatform();
625 void CanChallengePlatformDone(int32_t result, bool can_challenge_platform);
626 void SendPlatformChallengeDone(int32_t result);
627
628 pp::PlatformVerification platform_verification_;
629
630 // |can_challenge_platform_| is currently set asynchronously, return the value
631 // if we have it, otherwise guess "true" for the most common case...
632 // TODO(jrummell): This stinks. The value should be delivered via the
633 // Initialize() method once plumbed.
634 bool can_challenge_platform_;
635
636 // Since PPAPI doesn't provide handlers for CompletionCallbacks w/ more than
637 // one output we need to manage our own. These values are only read by
638 // SendPlatformChallengeDone().
639 pp::Var signed_data_output_;
640 pp::Var signed_data_signature_output_;
641 pp::Var platform_key_certificate_output_;
642 #endif
643
609 PpbBufferAllocator allocator_; 644 PpbBufferAllocator allocator_;
610 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; 645 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_;
611 cdm::ContentDecryptionModule* cdm_; 646 cdm::ContentDecryptionModule* cdm_;
612 std::string key_system_; 647 std::string key_system_;
613 648
614 DISALLOW_COPY_AND_ASSIGN(CdmWrapper); 649 DISALLOW_COPY_AND_ASSIGN(CdmWrapper);
615 }; 650 };
616 651
617 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) 652 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module)
618 : pp::Instance(instance), 653 : pp::Instance(instance),
619 pp::ContentDecryptor_Private(this), 654 pp::ContentDecryptor_Private(this),
655 #if defined(OS_CHROMEOS)
656 platform_verification_(this),
657 // Err on the side of the most common case...
658 can_challenge_platform_(true),
659 #endif
620 allocator_(this), 660 allocator_(this),
621 cdm_(NULL) { 661 cdm_(NULL) {
622 callback_factory_.Initialize(this); 662 callback_factory_.Initialize(this);
663 #if defined(OS_CHROMEOS)
664 // Preemptively retrieve the platform challenge status. It will not change.
665 platform_verification_.CanChallengePlatform(
666 callback_factory_.NewCallbackWithOutput(
667 &CdmWrapper::CanChallengePlatformDone));
668 #endif
623 } 669 }
624 670
625 CdmWrapper::~CdmWrapper() { 671 CdmWrapper::~CdmWrapper() {
626 if (cdm_) 672 if (cdm_)
627 cdm_->Destroy(); 673 cdm_->Destroy();
628 } 674 }
629 675
630 bool CdmWrapper::CreateCdmInstance(const std::string& key_system) { 676 bool CdmWrapper::CreateCdmInstance(const std::string& key_system) {
631 PP_DCHECK(!cdm_); 677 PP_DCHECK(!cdm_);
632 cdm_ = static_cast<cdm::ContentDecryptionModule*>( 678 cdm_ = static_cast<cdm::ContentDecryptionModule*>(
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 int32_t session_id_length, 975 int32_t session_id_length,
930 cdm::MediaKeyError error_code, 976 cdm::MediaKeyError error_code,
931 uint32_t system_code) { 977 uint32_t system_code) {
932 SendKeyErrorInternal(key_system_, 978 SendKeyErrorInternal(key_system_,
933 std::string(session_id, session_id_length), 979 std::string(session_id, session_id_length),
934 error_code, 980 error_code,
935 system_code); 981 system_code);
936 } 982 }
937 983
938 void CdmWrapper::GetPrivateData(int32_t* instance, 984 void CdmWrapper::GetPrivateData(int32_t* instance,
939 cdm::Host::GetPrivateInterface* get_interface) { 985 GetPrivateInterface* get_interface) {
940 *instance = pp_instance(); 986 *instance = pp_instance();
941 *get_interface = pp::Module::Get()->get_browser_interface(); 987 *get_interface = pp::Module::Get()->get_browser_interface();
942 } 988 }
943 989
944 void CdmWrapper::SendUnknownKeyError(const std::string& key_system, 990 void CdmWrapper::SendUnknownKeyError(const std::string& key_system,
945 const std::string& session_id) { 991 const std::string& session_id) {
946 SendKeyErrorInternal(key_system, session_id, cdm::kUnknownError, 0); 992 SendKeyErrorInternal(key_system, session_id, cdm::kUnknownError, 0);
947 } 993 }
948 994
949 void CdmWrapper::SendKeyAdded(const std::string& key_system, 995 void CdmWrapper::SendKeyAdded(const std::string& key_system,
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 static_cast<cdm::VideoFrame::VideoPlane>(i); 1194 static_cast<cdm::VideoFrame::VideoPlane>(i);
1149 if (ppb_buffer->Size() < video_frame->PlaneOffset(plane) + 1195 if (ppb_buffer->Size() < video_frame->PlaneOffset(plane) +
1150 plane_height * video_frame->Stride(plane)) { 1196 plane_height * video_frame->Stride(plane)) {
1151 return false; 1197 return false;
1152 } 1198 }
1153 } 1199 }
1154 1200
1155 return true; 1201 return true;
1156 } 1202 }
1157 1203
1204 bool CdmWrapper::CanChallengePlatform() {
1205 #if defined(OS_CHROMEOS)
1206 return can_challenge_platform_;
1207 #else
1208 return false;
1209 #endif
1210 }
1211
1212 void CdmWrapper::SendPlatformChallenge(
1213 const char* service_id, int32_t service_id_length,
1214 const char* challenge, int32_t challenge_length) {
1215 #if defined(OS_CHROMEOS)
1216 pp::VarArrayBuffer challenge_var(challenge_length);
1217 uint8_t* var_data = static_cast<uint8_t*>(challenge_var.Map());
1218 memcpy(var_data, challenge, challenge_length);
1219
1220 std::string service_id_str(service_id, service_id_length);
1221 int32_t result = platform_verification_.ChallengePlatform(
1222 pp::Var(service_id_str), challenge_var, &signed_data_output_,
1223 &signed_data_signature_output_, &platform_key_certificate_output_,
1224 callback_factory_.NewCallback(&CdmWrapper::SendPlatformChallengeDone));
1225 challenge_var.Unmap();
1226 if (result == PP_OK_COMPLETIONPENDING)
1227 return;
1228
1229 // Fall through on error and issue an empty OnPlatformChallengeResponse().
ddorwin 2013/09/24 06:19:45 DCHECK != PP_OK?
DaleCurtis 2013/09/24 19:55:54 Done.
1230 #endif
1231
1232 cdm::PlatformChallengeResponse response = {};
1233 cdm_->OnPlatformChallengeResponse(response);
1234 }
1235
1236 #if defined(OS_CHROMEOS)
1237 void CdmWrapper::CanChallengePlatformDone(int32_t result,
1238 bool can_challenge_platform) {
1239 can_challenge_platform_ = (result == PP_OK) ? can_challenge_platform : false;
1240 }
1241
1242 void CdmWrapper::SendPlatformChallengeDone(int32_t result) {
1243 if (result != PP_OK) {
1244 cdm::PlatformChallengeResponse response = {};
1245 cdm_->OnPlatformChallengeResponse(response);
1246 return;
1247 }
1248
1249 pp::VarArrayBuffer signed_data_var(signed_data_output_);
1250 pp::VarArrayBuffer signed_data_signature_var(signed_data_signature_output_);
1251 std::string platform_key_certificate_string =
1252 platform_key_certificate_output_.AsString();
1253
1254 cdm::PlatformChallengeResponse response = {
1255 static_cast<uint8_t*>(signed_data_var.Map()),
1256 signed_data_var.ByteLength(),
1257
1258 static_cast<uint8_t*>(signed_data_signature_var.Map()),
1259 signed_data_signature_var.ByteLength(),
1260
1261 reinterpret_cast<const uint8_t*>(platform_key_certificate_string.c_str()),
1262 platform_key_certificate_string.length()
1263 };
1264 cdm_->OnPlatformChallengeResponse(response);
1265
1266 signed_data_var.Unmap();
1267 signed_data_signature_var.Unmap();
1268
1269 // Reset member variables for future ChallengePlatform() calls.
ddorwin 2013/09/24 06:19:45 Do we rely on the CDM to not call ChallengePlatfor
DaleCurtis 2013/09/24 19:55:54 Good idea. Done. I also realized its messy to acc
1270 signed_data_output_ = pp::Var();
1271 signed_data_signature_output_ = pp::Var();
1272 platform_key_certificate_output_ = pp::Var();
1273 }
1274 #endif
1275
1276 void CdmWrapper::EnableOutputProtection(uint32_t desired_protection_mask) {
1277 // TODO(dalecurtis): Add implementation once PPAPI has landed.
1278 cdm_->OnQueryOutputProtectionStatus(0, 0);
1279 }
1280
1281 void CdmWrapper::QueryOutputProtectionStatus() {
1282 // TODO(dalecurtis): Add implementation once PPAPI has landed.
1283 cdm_->OnQueryOutputProtectionStatus(0, 0);
1284 }
1285
1158 void* GetCdmHost(int host_interface_version, void* user_data) { 1286 void* GetCdmHost(int host_interface_version, void* user_data) {
1159 if (!host_interface_version || !user_data) 1287 if (!host_interface_version || !user_data)
1160 return NULL; 1288 return NULL;
1161 1289
1162 if (host_interface_version != cdm::kHostInterfaceVersion)
1163 return NULL;
1164
1165 CdmWrapper* cdm_wrapper = static_cast<CdmWrapper*>(user_data); 1290 CdmWrapper* cdm_wrapper = static_cast<CdmWrapper*>(user_data);
1166 return static_cast<cdm::Host*>(cdm_wrapper); 1291 switch (host_interface_version) {
1292 case cdm::kHostInterfaceVersion_1:
1293 return static_cast<cdm::Host_1*>(cdm_wrapper);
1294 case cdm::kHostInterfaceVersion_2:
1295 return static_cast<cdm::Host_2*>(cdm_wrapper);
1296 default:
1297 PP_NOTREACHED();
1298 return NULL;
1299 }
1167 } 1300 }
1168 1301
1169 // This object is the global object representing this plugin library as long 1302 // This object is the global object representing this plugin library as long
1170 // as it is loaded. 1303 // as it is loaded.
1171 class CdmWrapperModule : public pp::Module { 1304 class CdmWrapperModule : public pp::Module {
1172 public: 1305 public:
1173 CdmWrapperModule() : pp::Module() { 1306 CdmWrapperModule() : pp::Module() {
1174 // This function blocks the renderer thread (PluginInstance::Initialize()). 1307 // This function blocks the renderer thread (PluginInstance::Initialize()).
1175 // Move this call to other places if this may be a concern in the future. 1308 // Move this call to other places if this may be a concern in the future.
1176 INITIALIZE_CDM_MODULE(); 1309 INITIALIZE_CDM_MODULE();
(...skipping 10 matching lines...) Expand all
1187 } // namespace media 1320 } // namespace media
1188 1321
1189 namespace pp { 1322 namespace pp {
1190 1323
1191 // Factory function for your specialization of the Module object. 1324 // Factory function for your specialization of the Module object.
1192 Module* CreateModule() { 1325 Module* CreateModule() {
1193 return new media::CdmWrapperModule(); 1326 return new media::CdmWrapperModule();
1194 } 1327 }
1195 1328
1196 } // namespace pp 1329 } // namespace pp
OLDNEW
« no previous file with comments | « no previous file | media/cdm/ppapi/clear_key_cdm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698