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

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: Sanity checks. Created 7 years, 3 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 bool challenge_in_progress_;
643 #endif
644
609 PpbBufferAllocator allocator_; 645 PpbBufferAllocator allocator_;
610 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_; 646 pp::CompletionCallbackFactory<CdmWrapper> callback_factory_;
611 cdm::ContentDecryptionModule* cdm_; 647 cdm::ContentDecryptionModule* cdm_;
612 std::string key_system_; 648 std::string key_system_;
613 649
614 DISALLOW_COPY_AND_ASSIGN(CdmWrapper); 650 DISALLOW_COPY_AND_ASSIGN(CdmWrapper);
615 }; 651 };
616 652
617 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module) 653 CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module)
618 : pp::Instance(instance), 654 : pp::Instance(instance),
619 pp::ContentDecryptor_Private(this), 655 pp::ContentDecryptor_Private(this),
656 #if defined(OS_CHROMEOS)
657 platform_verification_(this),
658 // Err on the side of the most common case...
659 can_challenge_platform_(true),
660 challenge_in_progress_(false),
661 #endif
620 allocator_(this), 662 allocator_(this),
621 cdm_(NULL) { 663 cdm_(NULL) {
622 callback_factory_.Initialize(this); 664 callback_factory_.Initialize(this);
665 #if defined(OS_CHROMEOS)
666 // Preemptively retrieve the platform challenge status. It will not change.
667 platform_verification_.CanChallengePlatform(
668 callback_factory_.NewCallbackWithOutput(
669 &CdmWrapper::CanChallengePlatformDone));
670 #endif
623 } 671 }
624 672
625 CdmWrapper::~CdmWrapper() { 673 CdmWrapper::~CdmWrapper() {
626 if (cdm_) 674 if (cdm_)
627 cdm_->Destroy(); 675 cdm_->Destroy();
628 } 676 }
629 677
630 bool CdmWrapper::CreateCdmInstance(const std::string& key_system) { 678 bool CdmWrapper::CreateCdmInstance(const std::string& key_system) {
631 PP_DCHECK(!cdm_); 679 PP_DCHECK(!cdm_);
632 cdm_ = static_cast<cdm::ContentDecryptionModule*>( 680 cdm_ = static_cast<cdm::ContentDecryptionModule*>(
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 int32_t session_id_length, 977 int32_t session_id_length,
930 cdm::MediaKeyError error_code, 978 cdm::MediaKeyError error_code,
931 uint32_t system_code) { 979 uint32_t system_code) {
932 SendKeyErrorInternal(key_system_, 980 SendKeyErrorInternal(key_system_,
933 std::string(session_id, session_id_length), 981 std::string(session_id, session_id_length),
934 error_code, 982 error_code,
935 system_code); 983 system_code);
936 } 984 }
937 985
938 void CdmWrapper::GetPrivateData(int32_t* instance, 986 void CdmWrapper::GetPrivateData(int32_t* instance,
939 cdm::Host::GetPrivateInterface* get_interface) { 987 GetPrivateInterface* get_interface) {
940 *instance = pp_instance(); 988 *instance = pp_instance();
941 *get_interface = pp::Module::Get()->get_browser_interface(); 989 *get_interface = pp::Module::Get()->get_browser_interface();
942 } 990 }
943 991
944 void CdmWrapper::SendUnknownKeyError(const std::string& key_system, 992 void CdmWrapper::SendUnknownKeyError(const std::string& key_system,
945 const std::string& session_id) { 993 const std::string& session_id) {
946 SendKeyErrorInternal(key_system, session_id, cdm::kUnknownError, 0); 994 SendKeyErrorInternal(key_system, session_id, cdm::kUnknownError, 0);
947 } 995 }
948 996
949 void CdmWrapper::SendKeyAdded(const std::string& key_system, 997 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); 1196 static_cast<cdm::VideoFrame::VideoPlane>(i);
1149 if (ppb_buffer->Size() < video_frame->PlaneOffset(plane) + 1197 if (ppb_buffer->Size() < video_frame->PlaneOffset(plane) +
1150 plane_height * video_frame->Stride(plane)) { 1198 plane_height * video_frame->Stride(plane)) {
1151 return false; 1199 return false;
1152 } 1200 }
1153 } 1201 }
1154 1202
1155 return true; 1203 return true;
1156 } 1204 }
1157 1205
1206 bool CdmWrapper::CanChallengePlatform() {
1207 #if defined(OS_CHROMEOS)
1208 return can_challenge_platform_;
1209 #else
1210 return false;
1211 #endif
1212 }
1213
1214 void CdmWrapper::SendPlatformChallenge(
1215 const char* service_id, int32_t service_id_length,
1216 const char* challenge, int32_t challenge_length) {
1217 #if defined(OS_CHROMEOS)
1218 PP_DCHECK(!challenge_in_progress_);
1219
1220 // Ensure member variables are in a clean state.
ddorwin 2013/09/24 23:53:51 maybe (to be a bit clearer): ... variables set by
DaleCurtis 2013/10/04 23:15:16 Done.
1221 signed_data_output_ = pp::Var();
1222 signed_data_signature_output_ = pp::Var();
1223 platform_key_certificate_output_ = pp::Var();
1224
1225 pp::VarArrayBuffer challenge_var(challenge_length);
1226 uint8_t* var_data = static_cast<uint8_t*>(challenge_var.Map());
1227 memcpy(var_data, challenge, challenge_length);
1228
1229 std::string service_id_str(service_id, service_id_length);
1230 int32_t result = platform_verification_.ChallengePlatform(
1231 pp::Var(service_id_str), challenge_var, &signed_data_output_,
1232 &signed_data_signature_output_, &platform_key_certificate_output_,
1233 callback_factory_.NewCallback(&CdmWrapper::SendPlatformChallengeDone));
1234 challenge_var.Unmap();
1235 if (result == PP_OK_COMPLETIONPENDING) {
1236 challenge_in_progress_ = true;
1237 return;
1238 }
1239
1240 // Fall through on error and issue an empty OnPlatformChallengeResponse().
1241 PP_DCHECK(result != PP_OK);
1242 #endif
1243
1244 cdm::PlatformChallengeResponse response = {};
1245 cdm_->OnPlatformChallengeResponse(response);
1246 }
1247
1248 #if defined(OS_CHROMEOS)
1249 void CdmWrapper::CanChallengePlatformDone(int32_t result,
1250 bool can_challenge_platform) {
1251 can_challenge_platform_ = (result == PP_OK) ? can_challenge_platform : false;
1252 }
1253
1254 void CdmWrapper::SendPlatformChallengeDone(int32_t result) {
1255 challenge_in_progress_ = false;
1256
1257 if (result != PP_OK) {
1258 cdm::PlatformChallengeResponse response = {};
1259 cdm_->OnPlatformChallengeResponse(response);
1260 return;
1261 }
1262
1263 pp::VarArrayBuffer signed_data_var(signed_data_output_);
1264 pp::VarArrayBuffer signed_data_signature_var(signed_data_signature_output_);
1265 std::string platform_key_certificate_string =
1266 platform_key_certificate_output_.AsString();
1267
1268 cdm::PlatformChallengeResponse response = {
1269 static_cast<uint8_t*>(signed_data_var.Map()),
1270 signed_data_var.ByteLength(),
1271
1272 static_cast<uint8_t*>(signed_data_signature_var.Map()),
1273 signed_data_signature_var.ByteLength(),
1274
1275 reinterpret_cast<const uint8_t*>(platform_key_certificate_string.c_str()),
1276 platform_key_certificate_string.length()
1277 };
1278 cdm_->OnPlatformChallengeResponse(response);
1279
1280 signed_data_var.Unmap();
1281 signed_data_signature_var.Unmap();
1282 }
1283 #endif
1284
1285 void CdmWrapper::EnableOutputProtection(uint32_t desired_protection_mask) {
1286 // TODO(dalecurtis): Add implementation once PPAPI has landed.
1287 cdm_->OnQueryOutputProtectionStatus(0, 0);
1288 }
1289
1290 void CdmWrapper::QueryOutputProtectionStatus() {
1291 // TODO(dalecurtis): Add implementation once PPAPI has landed.
1292 cdm_->OnQueryOutputProtectionStatus(0, 0);
1293 }
1294
1158 void* GetCdmHost(int host_interface_version, void* user_data) { 1295 void* GetCdmHost(int host_interface_version, void* user_data) {
1159 if (!host_interface_version || !user_data) 1296 if (!host_interface_version || !user_data)
1160 return NULL; 1297 return NULL;
1161 1298
1162 if (host_interface_version != cdm::kHostInterfaceVersion)
1163 return NULL;
1164
1165 CdmWrapper* cdm_wrapper = static_cast<CdmWrapper*>(user_data); 1299 CdmWrapper* cdm_wrapper = static_cast<CdmWrapper*>(user_data);
1166 return static_cast<cdm::Host*>(cdm_wrapper); 1300 switch (host_interface_version) {
1301 case cdm::kHostInterfaceVersion_1:
1302 return static_cast<cdm::Host_1*>(cdm_wrapper);
1303 case cdm::kHostInterfaceVersion_2:
1304 return static_cast<cdm::Host_2*>(cdm_wrapper);
1305 default:
1306 PP_NOTREACHED();
1307 return NULL;
1308 }
1167 } 1309 }
1168 1310
1169 // This object is the global object representing this plugin library as long 1311 // This object is the global object representing this plugin library as long
1170 // as it is loaded. 1312 // as it is loaded.
1171 class CdmWrapperModule : public pp::Module { 1313 class CdmWrapperModule : public pp::Module {
1172 public: 1314 public:
1173 CdmWrapperModule() : pp::Module() { 1315 CdmWrapperModule() : pp::Module() {
1174 // This function blocks the renderer thread (PluginInstance::Initialize()). 1316 // This function blocks the renderer thread (PluginInstance::Initialize()).
1175 // Move this call to other places if this may be a concern in the future. 1317 // Move this call to other places if this may be a concern in the future.
1176 INITIALIZE_CDM_MODULE(); 1318 INITIALIZE_CDM_MODULE();
(...skipping 10 matching lines...) Expand all
1187 } // namespace media 1329 } // namespace media
1188 1330
1189 namespace pp { 1331 namespace pp {
1190 1332
1191 // Factory function for your specialization of the Module object. 1333 // Factory function for your specialization of the Module object.
1192 Module* CreateModule() { 1334 Module* CreateModule() {
1193 return new media::CdmWrapperModule(); 1335 return new media::CdmWrapperModule();
1194 } 1336 }
1195 1337
1196 } // namespace pp 1338 } // 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