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

Unified 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: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | media/cdm/ppapi/clear_key_cdm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/cdm/ppapi/cdm_wrapper.cc
diff --git a/media/cdm/ppapi/cdm_wrapper.cc b/media/cdm/ppapi/cdm_wrapper.cc
index 6348f1954d0e9b8c30d724e2f6bbce62a1ccb1d9..a91636546a5e3190cf75014bda339d104c6167f3 100644
--- a/media/cdm/ppapi/cdm_wrapper.cc
+++ b/media/cdm/ppapi/cdm_wrapper.cc
@@ -10,6 +10,7 @@
#include "base/basictypes.h"
#include "base/compiler_specific.h"
+#include "build/build_config.h"
#include "media/cdm/ppapi/api/content_decryption_module.h"
ddorwin 2013/09/17 05:26:46 You need a DEPS roll in this CL. (Make sure it's b
#include "media/cdm/ppapi/linked_ptr.h"
#include "ppapi/c/pp_errors.h"
@@ -33,6 +34,10 @@
#include "ppapi/cpp/instance_handle.h"
#endif // defined(CHECK_DOCUMENT_URL)
+#if defined(OS_CHROMEOS)
+#include "ppapi/cpp/private/platform_verification.h"
+#endif
+
namespace {
bool IsMainThread() {
@@ -485,7 +490,8 @@ void* GetCdmHost(int host_interface_version, void* user_data);
// Content Decryption Module (CDM).
class CdmWrapper : public pp::Instance,
public pp::ContentDecryptor_Private,
- public cdm::Host {
+ public cdm::Host_1,
+ public cdm::Host_2 {
dmichael (off chromium) 2013/09/17 20:10:46 Is this just temporary to deal with DEPS? If so, f
DaleCurtis 2013/09/17 20:18:51 Temporary IIUC. Host_1 can be removed in favor of
ddorwin 2013/09/17 23:24:39 Correct. Also, _2 is a version of the Host interfa
public:
CdmWrapper(PP_Instance instance, pp::Module* module);
virtual ~CdmWrapper();
@@ -523,7 +529,7 @@ class CdmWrapper : public pp::Instance,
pp::Buffer_Dev encrypted_buffer,
const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE;
- // cdm::Host implementation.
+ // cdm::Host_1 implementation.
virtual cdm::Buffer* Allocate(int32_t capacity) OVERRIDE;
virtual void SetTimer(int64_t delay_ms, void* context) OVERRIDE;
virtual double GetCurrentWallTimeInSeconds() OVERRIDE;
@@ -538,6 +544,14 @@ class CdmWrapper : public pp::Instance,
virtual void GetPrivateData(int32_t* instance,
GetPrivateInterface* get_interface) OVERRIDE;
+ // cdm::Host_2 implementation.
+ virtual void SendPlatformChallenge(
+ const char* service_id, int32_t service_id_length,
+ const char* challenge, int32_t challenge_length) OVERRIDE;
+ virtual void EnableOutputProtection(
+ uint32_t desired_protection_mask) OVERRIDE;
+ virtual void QueryOutputProtectionStatus() OVERRIDE;
+
private:
struct SessionInfo {
SessionInfo(const std::string& key_system_in,
@@ -605,10 +619,40 @@ class CdmWrapper : public pp::Instance,
bool IsValidVideoFrame(const LinkedVideoFrame& video_frame);
+#if defined(OS_CHROMEOS)
+ bool CanChallengePlatform();
+ void CanChallengePlatformDone(int32_t result, bool can_challenge_platform);
ddorwin 2013/09/17 05:26:46 OnCan... ?
DaleCurtis 2013/09/17 18:49:33 Style elsewhere in the file is XxxDone; i.e., Deco
+ void SendPlatformChallengeDone(int32_t result);
+
+ // Since CanChallengePlatform() needs to return its value immediately, we need
+ // to delay GenerateKeyRequest() until its value is available.
+ // TODO(dalecurtis): This stinks. We need to find a way to deliver the value
+ // synchronously. Potentially as part of the new Initialize(), see
+ // http://crbug.com/250049
+ void DelayedGenerateKeyRequest(int32_t result,
+ const std::string& key_system,
+ const std::string& type,
+ pp::VarArrayBuffer init_data);
+
+ pp::PlatformVerification platform_verification_;
+ bool is_can_challenge_platform_set_;
ddorwin 2013/09/17 05:26:46 It's not clear from the name what this does. _init
DaleCurtis 2013/09/23 18:30:57 Done.
+ pp::CompletionCallback delayed_gkr_;
+
+ // Since PPAPI doesn't provide handlers for CompleteCallbacks w/ more than one
ddorwin 2013/09/17 05:26:46 CompletionC...
DaleCurtis 2013/09/23 18:30:57 Done.
+ // output we need to manage our own. These values are read only by
ddorwin 2013/09/17 05:26:46 nit: since this order could be ambiguous, swap rea
DaleCurtis 2013/09/23 18:30:57 Done.
+ // SendPlatformChallengeDone().
+ // TODO(dalecurtis): CompletionCallbackFactory mentions this may not be safe
+ // since the module could be destructed before callbacks complete... True?
dmichael (off chromium) 2013/09/17 20:10:46 Can you point me to the comment you saw that indic
DaleCurtis 2013/09/17 20:18:51 https://code.google.com/p/chromium/codesearch#chro
dmichael (off chromium) 2013/09/17 20:36:58 Ah, thanks. This stuff is confusing, and I still f
DaleCurtis 2013/09/23 18:30:57 Thanks for the explanation. Comment removed.
+ pp::Var signed_data_output_;
+ pp::Var signed_data_signature_output_;
+ pp::Var platform_key_certificate_output_;
+#endif
+
PpbBufferAllocator allocator_;
pp::CompletionCallbackFactory<CdmWrapper> callback_factory_;
cdm::ContentDecryptionModule* cdm_;
Rintaro Kuroiwa 2013/09/20 01:55:06 When OS_CHROMEOS is defined, this will error at 12
DaleCurtis 2013/09/23 18:30:57 Yeah I have another change to the CDM.h that switc
std::string key_system_;
+ bool can_challenge_platform_;
ddorwin 2013/09/17 05:26:46 We don't really need this other than OS_CHROMEOS.
DaleCurtis 2013/09/23 18:30:57 Done.
DISALLOW_COPY_AND_ASSIGN(CdmWrapper);
};
@@ -616,9 +660,20 @@ class CdmWrapper : public pp::Instance,
CdmWrapper::CdmWrapper(PP_Instance instance, pp::Module* module)
: pp::Instance(instance),
pp::ContentDecryptor_Private(this),
+#if defined(OS_CHROMEOS)
+ platform_verification_(this),
+ is_can_challenge_platform_set_(false),
+#endif
allocator_(this),
- cdm_(NULL) {
+ cdm_(NULL),
+ can_challenge_platform_(false) {
callback_factory_.Initialize(this);
+#if defined(OS_CHROMEOS)
+ // Preemptively retrieve the platform challenge status. It will not change.
+ platform_verification_.CanChallengePlatform(
ddorwin 2013/09/17 05:26:46 Re-entrancy from an Instance constructor seems lik
DaleCurtis 2013/09/17 18:49:33 Hmm, it will end up as a post anyways when the IPC
dmichael (off chromium) 2013/09/17 20:10:46 I'm not sure what re-entrancy you're worried about
ddorwin 2013/09/17 23:24:39 I was just worried about re-entrancy when we're in
+ callback_factory_.NewCallbackWithOutput(
+ &CdmWrapper::CanChallengePlatformDone));
+#endif
}
CdmWrapper::~CdmWrapper() {
@@ -652,6 +707,16 @@ void CdmWrapper::GenerateKeyRequest(const std::string& key_system,
PP_DCHECK(0 < url_components.host.len);
#endif // defined(CHECK_DOCUMENT_URL)
+#if defined(OS_CHROMEOS)
+ // Ensure CanChallengePlatform() has valid data before initializing the CDM;
+ // delaying the GenerateKeyRequest if necessary.
+ if (!is_can_challenge_platform_set_) {
+ delayed_gkr_ = callback_factory_.NewCallback(
ddorwin 2013/09/17 05:26:46 What if you get multiple GKRs at the same time?
DaleCurtis 2013/09/17 18:49:33 Ugh, I didn't realize that was a thing. To handle
DaleCurtis 2013/09/23 18:30:57 Yeah, delay isn't going to work. I've instead cha
+ &CdmWrapper::DelayedGenerateKeyRequest, key_system, type, init_data);
+ return;
+ }
+#endif
+
if (!cdm_) {
if (!CreateCdmInstance(key_system)) {
SendUnknownKeyError(key_system, std::string());
@@ -938,7 +1003,7 @@ void CdmWrapper::SendKeyError(const char* session_id,
}
void CdmWrapper::GetPrivateData(int32_t* instance,
- cdm::Host::GetPrivateInterface* get_interface) {
+ GetPrivateInterface* get_interface) {
*instance = pp_instance();
*get_interface = pp::Module::Get()->get_browser_interface();
}
@@ -1157,15 +1222,99 @@ bool CdmWrapper::IsValidVideoFrame(const LinkedVideoFrame& video_frame) {
return true;
}
+bool CdmWrapper::CanChallengePlatform() {
+ return can_challenge_platform_;
+}
+
+void CdmWrapper::SendPlatformChallenge(
+ const char* service_id, int32_t service_id_length,
+ const char* challenge, int32_t challenge_length) {
+#if defined(OS_CHROMEOS)
+ // TODO(dalecurtis): Reinitialize member variables to PP_Undefined?
+
+ pp::VarArrayBuffer challenge_var(challenge_length);
+ uint8_t* var_data = static_cast<uint8_t*>(challenge_var.Map());
+ memcpy(var_data, challenge, challenge_length);
+
+ std::string service_id_str(service_id, service_id_length);
+ int32_t result = platform_verification_.ChallengePlatform(
+ pp::Var(service_id_str), challenge_var, &signed_data_output_,
+ &signed_data_signature_output_, &platform_key_certificate_output_,
ddorwin 2013/09/17 05:26:46 Why are these passed as pointers? Aren't all pp::V
DaleCurtis 2013/09/17 18:49:33 [out] type variables end up as Var* per the PPAPI
dmichael (off chromium) 2013/09/17 20:10:46 ddorwin: I'm not sure what you mean... we try to
+ callback_factory_.NewCallback(&CdmWrapper::SendPlatformChallengeDone));
+ challenge_var.Unmap();
+#else
+ PlatformChallengeResponse pcr = {};
ddorwin 2013/09/17 05:26:46 suggest: s/pcr/response/
DaleCurtis 2013/09/23 18:30:57 Done.
+ cdm_->OnPlatformChallengeResponse(pcr);
+#endif
+}
+
+#if defined(OS_CHROMEOS)
+void CdmWrapper::CanChallengePlatformDone(int32_t result,
+ bool can_challenge_platform) {
+ PP_DCHECK(!is_can_challenge_platform_set_);
+ can_challenge_platform_ = (result == PP_OK) ? can_challenge_platform : false;
+ is_can_challenge_platform_set_ = true;
+ if (!delayed_gkr_.IsOptional())
ddorwin 2013/09/17 05:26:46 ? Is the gkr ever optional?
DaleCurtis 2013/09/17 18:49:33 I'm just using it to check if the callback is unin
DaleCurtis 2013/09/23 18:30:57 Removed since now I can just store the key system.
+ delayed_gkr_.RunAndClear(PP_OK);
+}
+
+void CdmWrapper::SendPlatformChallengeDone(int32_t result) {
+ if (result != PP_OK) {
+ cdm::PlatformChallengeResponse pcr = {};
ddorwin 2013/09/17 05:26:46 same
DaleCurtis 2013/09/23 18:30:57 Done.
+ cdm_->OnPlatformChallengeResponse(pcr);
+ return;
+ }
+
+ pp::VarArrayBuffer signed_data_var(signed_data_output_);
+ pp::VarArrayBuffer signed_data_signature_var(signed_data_signature_output_);
dmichael (off chromium) 2013/09/17 20:10:46 signed_data_output_ = pp::Var(); signed_data_signa
DaleCurtis 2013/09/23 18:30:57 Done.
+ std::string pkc_string = platform_key_certificate_output_.AsString();
ddorwin 2013/09/17 05:26:46 nit: "pkc" is not descriptive
DaleCurtis 2013/09/23 18:30:57 Done.
+
+ cdm::PlatformChallengeResponse pcr = {
+ static_cast<uint8_t*>(signed_data_var.Map()),
+ signed_data_var.ByteLength(),
+
+ static_cast<uint8_t*>(signed_data_signature_var.Map()),
+ signed_data_signature_var.ByteLength(),
+
+ reinterpret_cast<const uint8_t*>(pkc_string.c_str()),
dmichael (off chromium) 2013/09/17 20:10:46 static_cast?
DaleCurtis 2013/09/17 20:18:51 Requires reinterpret_cast for char* -> uint8_t*
Rintaro Kuroiwa 2013/09/20 01:55:06 Also need const_cast. The struct needs a non-const
DaleCurtis 2013/09/23 18:30:57 I have another patch which makes these fields cons
+ pkc_string.length()
+ };
+ cdm_->OnPlatformChallengeResponse(pcr);
+
+ signed_data_var.Unmap();
+ signed_data_signature_var.Unmap();
+}
+
+void CdmWrapper::DelayedGenerateKeyRequest(int32_t result,
ddorwin 2013/09/17 05:26:46 nit: The function name is a noun not an action
DaleCurtis 2013/09/23 18:30:57 Removed.
+ const std::string& key_system,
+ const std::string& type,
+ pp::VarArrayBuffer init_data) {
dmichael (off chromium) 2013/09/17 20:10:46 It's probably best to pass Var by const-reference,
DaleCurtis 2013/09/23 18:30:57 Removed.
+ GenerateKeyRequest(key_system, type, init_data);
+}
+#endif
+
+void CdmWrapper::EnableOutputProtection(uint32_t desired_protection_mask) {
+ // TODO(dalecurtis): Add implementation once PPAPI has landed.
+ cdm_->OnQueryOutputProtectionStatus(0, 0);
+}
+
+void CdmWrapper::QueryOutputProtectionStatus() {
+ // TODO(dalecurtis): Add implementation once PPAPI has landed.
+ cdm_->OnQueryOutputProtectionStatus(0, 0);
+}
+
void* GetCdmHost(int host_interface_version, void* user_data) {
if (!host_interface_version || !user_data)
return NULL;
- if (host_interface_version != cdm::kHostInterfaceVersion)
- return NULL;
-
- CdmWrapper* cdm_wrapper = static_cast<CdmWrapper*>(user_data);
- return static_cast<cdm::Host*>(cdm_wrapper);
+ switch (host_interface_version) {
+ case cdm::kHostInterfaceVersion_1:
+ return static_cast<cdm::Host_1*>(static_cast<CdmWrapper*>(user_data));
ddorwin 2013/09/17 05:26:46 tiny optional suggestion: It's an extra line but m
DaleCurtis 2013/09/23 18:30:57 Done.
+ case cdm::kHostInterfaceVersion_2:
+ return static_cast<cdm::Host_2*>(static_cast<CdmWrapper*>(user_data));
+ default:
+ return NULL;
ddorwin 2013/09/17 05:26:46 NOTREACHED()
DaleCurtis 2013/09/23 18:30:57 Done.
+ }
}
// This object is the global object representing this plugin library as long
« 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