Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |