Commit ca9f19e7 authored by xhwang@chromium.org's avatar xhwang@chromium.org

CdmAdapter: Allow parallel SendPlatformChallenge() calls.

Previously CdmAdapter only allows one outstanding SendPlatformChallenge() call.
However, CDM actually needs to make parallel SendPlatformChallenge() calls. This
CL fixes CdmAdapter to allow this.

BUG=393722
TEST=Tested on ChromeOS build on Linux with hack in
PepperPlatformVerificationMessageFilter to return faked challenge platform reply.

Review URL: https://codereview.chromium.org/393713003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283651 0039d316-1c4b-4281-b951-d872f2087c98
parent 6f7b4e45
...@@ -255,7 +255,6 @@ CdmAdapter::CdmAdapter(PP_Instance instance, pp::Module* module) ...@@ -255,7 +255,6 @@ CdmAdapter::CdmAdapter(PP_Instance instance, pp::Module* module)
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
output_protection_(this), output_protection_(this),
platform_verification_(this), platform_verification_(this),
challenge_in_progress_(false),
output_link_mask_(0), output_link_mask_(0),
output_protection_mask_(0), output_protection_mask_(0),
query_output_protection_in_progress_(false), query_output_protection_in_progress_(false),
...@@ -1009,34 +1008,33 @@ void CdmAdapter::SendPlatformChallenge( ...@@ -1009,34 +1008,33 @@ void CdmAdapter::SendPlatformChallenge(
const char* service_id, uint32_t service_id_length, const char* service_id, uint32_t service_id_length,
const char* challenge, uint32_t challenge_length) { const char* challenge, uint32_t challenge_length) {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
PP_DCHECK(!challenge_in_progress_);
// Ensure member variables set by the callback are in a clean state.
signed_data_output_ = pp::Var();
signed_data_signature_output_ = pp::Var();
platform_key_certificate_output_ = pp::Var();
pp::VarArrayBuffer challenge_var(challenge_length); pp::VarArrayBuffer challenge_var(challenge_length);
uint8_t* var_data = static_cast<uint8_t*>(challenge_var.Map()); uint8_t* var_data = static_cast<uint8_t*>(challenge_var.Map());
memcpy(var_data, challenge, challenge_length); memcpy(var_data, challenge, challenge_length);
std::string service_id_str(service_id, service_id_length); std::string service_id_str(service_id, service_id_length);
linked_ptr<PepperPlatformChallengeResponse> response(
new PepperPlatformChallengeResponse());
int32_t result = platform_verification_.ChallengePlatform( int32_t result = platform_verification_.ChallengePlatform(
pp::Var(service_id_str), challenge_var, &signed_data_output_, pp::Var(service_id_str),
&signed_data_signature_output_, &platform_key_certificate_output_, challenge_var,
callback_factory_.NewCallback(&CdmAdapter::SendPlatformChallengeDone)); &response->signed_data,
&response->signed_data_signature,
&response->platform_key_certificate,
callback_factory_.NewCallback(&CdmAdapter::SendPlatformChallengeDone,
response));
challenge_var.Unmap(); challenge_var.Unmap();
if (result == PP_OK_COMPLETIONPENDING) { if (result == PP_OK_COMPLETIONPENDING)
challenge_in_progress_ = true;
return; return;
}
// Fall through on error and issue an empty OnPlatformChallengeResponse(). // Fall through on error and issue an empty OnPlatformChallengeResponse().
PP_DCHECK(result != PP_OK); PP_DCHECK(result != PP_OK);
#endif #endif
cdm::PlatformChallengeResponse response = {}; cdm::PlatformChallengeResponse platform_challenge_response = {};
cdm_->OnPlatformChallengeResponse(response); cdm_->OnPlatformChallengeResponse(platform_challenge_response);
} }
void CdmAdapter::EnableOutputProtection(uint32_t desired_protection_mask) { void CdmAdapter::EnableOutputProtection(uint32_t desired_protection_mask) {
...@@ -1154,29 +1152,29 @@ void CdmAdapter::ReportOutputProtectionQueryResult() { ...@@ -1154,29 +1152,29 @@ void CdmAdapter::ReportOutputProtectionQueryResult() {
// queries and success results. // queries and success results.
} }
void CdmAdapter::SendPlatformChallengeDone(int32_t result) { void CdmAdapter::SendPlatformChallengeDone(
challenge_in_progress_ = false; int32_t result,
const linked_ptr<PepperPlatformChallengeResponse>& response) {
if (result != PP_OK) { if (result != PP_OK) {
CDM_DLOG() << __FUNCTION__ << ": Platform challenge failed!"; CDM_DLOG() << __FUNCTION__ << ": Platform challenge failed!";
cdm::PlatformChallengeResponse response = {}; cdm::PlatformChallengeResponse platform_challenge_response = {};
cdm_->OnPlatformChallengeResponse(response); cdm_->OnPlatformChallengeResponse(platform_challenge_response);
return; return;
} }
pp::VarArrayBuffer signed_data_var(signed_data_output_); pp::VarArrayBuffer signed_data_var(response->signed_data);
pp::VarArrayBuffer signed_data_signature_var(signed_data_signature_output_); pp::VarArrayBuffer signed_data_signature_var(response->signed_data_signature);
std::string platform_key_certificate_string = std::string platform_key_certificate_string =
platform_key_certificate_output_.AsString(); response->platform_key_certificate.AsString();
cdm::PlatformChallengeResponse response = { cdm::PlatformChallengeResponse platform_challenge_response = {
static_cast<uint8_t*>(signed_data_var.Map()), static_cast<uint8_t*>(signed_data_var.Map()),
signed_data_var.ByteLength(), signed_data_var.ByteLength(),
static_cast<uint8_t*>(signed_data_signature_var.Map()), static_cast<uint8_t*>(signed_data_signature_var.Map()),
signed_data_signature_var.ByteLength(), signed_data_signature_var.ByteLength(),
reinterpret_cast<const uint8_t*>(platform_key_certificate_string.data()), reinterpret_cast<const uint8_t*>(platform_key_certificate_string.data()),
static_cast<uint32_t>(platform_key_certificate_string.length())}; static_cast<uint32_t>(platform_key_certificate_string.length())};
cdm_->OnPlatformChallengeResponse(response); cdm_->OnPlatformChallengeResponse(platform_challenge_response);
signed_data_var.Unmap(); signed_data_var.Unmap();
signed_data_signature_var.Unmap(); signed_data_signature_var.Unmap();
......
...@@ -245,21 +245,21 @@ class CdmAdapter : public pp::Instance, ...@@ -245,21 +245,21 @@ class CdmAdapter : public pp::Instance,
void ReportOutputProtectionQuery(); void ReportOutputProtectionQuery();
void ReportOutputProtectionQueryResult(); void ReportOutputProtectionQueryResult();
void SendPlatformChallengeDone(int32_t result); struct PepperPlatformChallengeResponse {
pp::Var signed_data;
pp::Var signed_data_signature;
pp::Var platform_key_certificate;
};
void SendPlatformChallengeDone(
int32_t result,
const linked_ptr<PepperPlatformChallengeResponse>& response);
void EnableProtectionDone(int32_t result); void EnableProtectionDone(int32_t result);
void QueryOutputProtectionStatusDone(int32_t result); void QueryOutputProtectionStatusDone(int32_t result);
pp::OutputProtection_Private output_protection_; pp::OutputProtection_Private output_protection_;
pp::PlatformVerification platform_verification_; pp::PlatformVerification platform_verification_;
// Since PPAPI doesn't provide handlers for CompletionCallbacks with more than
// one output we need to manage our own. These values are only read by
// SendPlatformChallengeDone().
pp::Var signed_data_output_;
pp::Var signed_data_signature_output_;
pp::Var platform_key_certificate_output_;
bool challenge_in_progress_;
// Same as above, these are only read by QueryOutputProtectionStatusDone(). // Same as above, these are only read by QueryOutputProtectionStatusDone().
uint32_t output_link_mask_; uint32_t output_link_mask_;
uint32_t output_protection_mask_; uint32_t output_protection_mask_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment