Commit 6d613d6d authored by xhwang@chromium.org's avatar xhwang@chromium.org

Encrypted Media: Allows empty key message to be fired.

This CL also changes the expected behavior of GenerateKeyRequest() of CleryKey key system when init_data is null. Previously it returns MediaKeyException (from render side) or fires KeyError (from plugin side). Now it fires an empty KeyMessage regardless. In the future the spec should be clear about this.

BUG=163785
TEST=media Layout test; media_unittests; content_browsertests


Review URL: https://chromiumcodereview.appspot.com/11348365

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171081 0039d316-1c4b-4281-b951-d872f2087c98
parent 2432c058
...@@ -139,16 +139,16 @@ bool AesDecryptor::GenerateKeyRequest(const std::string& key_system, ...@@ -139,16 +139,16 @@ bool AesDecryptor::GenerateKeyRequest(const std::string& key_system,
int init_data_length) { int init_data_length) {
std::string session_id_string(base::UintToString(next_session_id_++)); std::string session_id_string(base::UintToString(next_session_id_++));
if (!init_data || !init_data_length) {
DVLOG(1) << "init_data required to generate a key request.";
return false;
}
// For now, the AesDecryptor does not care about |key_system| and |type|; // For now, the AesDecryptor does not care about |key_system| and |type|;
// just fire the event with the |init_data| as the request. // just fire the event with the |init_data| as the request.
int message_length = init_data_length; scoped_array<uint8> message;
scoped_array<uint8> message(new uint8[message_length]); int message_length = 0;
memcpy(message.get(), init_data, message_length);
if (init_data && init_data_length) {
message_length = init_data_length;
message.reset(new uint8[message_length]);
memcpy(message.get(), init_data, message_length);
}
client_->KeyMessage(key_system, session_id_string, client_->KeyMessage(key_system, session_id_string,
message.Pass(), message_length, ""); message.Pass(), message_length, "");
......
...@@ -316,7 +316,9 @@ class AesDecryptorTest : public testing::Test { ...@@ -316,7 +316,9 @@ class AesDecryptorTest : public testing::Test {
}; };
TEST_F(AesDecryptorTest, GenerateKeyRequestWithNullInitData) { TEST_F(AesDecryptorTest, GenerateKeyRequestWithNullInitData) {
EXPECT_FALSE(decryptor_.GenerateKeyRequest(kClearKeySystem, "", NULL, 0)); EXPECT_CALL(client_, KeyMessageMock(kClearKeySystem, StrNe(""),
IsNull(), 0, ""));
EXPECT_TRUE(decryptor_.GenerateKeyRequest(kClearKeySystem, "", NULL, 0));
} }
TEST_F(AesDecryptorTest, NormalWebMDecryption) { TEST_F(AesDecryptorTest, NormalWebMDecryption) {
......
...@@ -94,7 +94,8 @@ interface PPB_ContentDecryptor_Private { ...@@ -94,7 +94,8 @@ interface PPB_ContentDecryptor_Private {
* <code>PP_VARTYPE_STRING</code> containing the session ID. * <code>PP_VARTYPE_STRING</code> containing the session ID.
* *
* @param[in] resource A <code>PP_Resource</code> corresponding to a * @param[in] resource A <code>PP_Resource</code> corresponding to a
* <code>PPB_Buffer_Dev</code> resource that contains the message. * <code>PPB_Buffer_Dev</code> resource that contains the message. A 0
* resource is allowed which indicates an empty message.
* *
* @param[in] default_url A <code>PP_Var</code> of type * @param[in] default_url A <code>PP_Var</code> of type
* <code>PP_VARTYPE_STRING</code> containing the default URL for the message. * <code>PP_VARTYPE_STRING</code> containing the default URL for the message.
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
*/ */
/* From private/ppb_content_decryptor_private.idl, /* From private/ppb_content_decryptor_private.idl,
* modified Fri Oct 26 14:47:38 2012. * modified Tue Dec 4 10:30:29 2012.
*/ */
#ifndef PPAPI_C_PRIVATE_PPB_CONTENT_DECRYPTOR_PRIVATE_H_ #ifndef PPAPI_C_PRIVATE_PPB_CONTENT_DECRYPTOR_PRIVATE_H_
...@@ -113,7 +113,8 @@ struct PPB_ContentDecryptor_Private_0_6 { ...@@ -113,7 +113,8 @@ struct PPB_ContentDecryptor_Private_0_6 {
* <code>PP_VARTYPE_STRING</code> containing the session ID. * <code>PP_VARTYPE_STRING</code> containing the session ID.
* *
* @param[in] resource A <code>PP_Resource</code> corresponding to a * @param[in] resource A <code>PP_Resource</code> corresponding to a
* <code>PPB_Buffer_Dev</code> resource that contains the message. * <code>PPB_Buffer_Dev</code> resource that contains the message. A 0
* resource is allowed which indicates an empty message.
* *
* @param[in] default_url A <code>PP_Var</code> of type * @param[in] default_url A <code>PP_Var</code> of type
* <code>PP_VARTYPE_STRING</code> containing the default URL for the message. * <code>PP_VARTYPE_STRING</code> containing the default URL for the message.
......
...@@ -544,17 +544,22 @@ void PPB_Instance_Proxy::KeyMessage(PP_Instance instance, ...@@ -544,17 +544,22 @@ void PPB_Instance_Proxy::KeyMessage(PP_Instance instance,
PP_Var session_id, PP_Var session_id,
PP_Resource message, PP_Resource message,
PP_Var default_url) { PP_Var default_url) {
Resource* object = PP_Resource host_resource = 0;
PpapiGlobals::Get()->GetResourceTracker()->GetResource(message); if (message) {
if (!object || object->pp_instance() != instance) Resource* object =
return; PpapiGlobals::Get()->GetResourceTracker()->GetResource(message);
if (!object || object->pp_instance() != instance)
return;
host_resource = object->host_resource().host_resource();
}
dispatcher()->Send( dispatcher()->Send(
new PpapiHostMsg_PPBInstance_KeyMessage( new PpapiHostMsg_PPBInstance_KeyMessage(
API_ID_PPB_INSTANCE, API_ID_PPB_INSTANCE,
instance, instance,
SerializedVarSendInput(dispatcher(), key_system), SerializedVarSendInput(dispatcher(), key_system),
SerializedVarSendInput(dispatcher(), session_id), SerializedVarSendInput(dispatcher(), session_id),
object->host_resource().host_resource(), host_resource,
SerializedVarSendInput(dispatcher(), default_url))); SerializedVarSendInput(dispatcher(), default_url)));
} }
......
...@@ -554,9 +554,7 @@ void CdmWrapper::GenerateKeyRequest(const std::string& key_system, ...@@ -554,9 +554,7 @@ void CdmWrapper::GenerateKeyRequest(const std::string& key_system,
init_data.ByteLength(), init_data.ByteLength(),
key_request.get()); key_request.get());
PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError);
if (status != cdm::kSuccess || if (status != cdm::kSuccess) {
!key_request->message() ||
key_request->message()->size() == 0) {
FireKeyError(""); FireKeyError("");
return; return;
} }
...@@ -816,8 +814,13 @@ void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) { ...@@ -816,8 +814,13 @@ void CdmWrapper::KeyAdded(int32_t result, const std::string& session_id) {
void CdmWrapper::KeyMessage(int32_t result, void CdmWrapper::KeyMessage(int32_t result,
const LinkedKeyMessage& key_message) { const LinkedKeyMessage& key_message) {
PP_DCHECK(result == PP_OK); PP_DCHECK(result == PP_OK);
pp::Buffer_Dev message_buffer =
static_cast<const PpbBuffer*>(key_message->message())->buffer_dev(); pp::Buffer_Dev message_buffer;
if (key_message->message()) {
message_buffer = static_cast<const PpbBuffer*>(
key_message->message())->buffer_dev();
}
pp::ContentDecryptor_Private::KeyMessage( pp::ContentDecryptor_Private::KeyMessage(
key_system_, key_system_,
key_message->session_id_string(), key_message->session_id_string(),
......
...@@ -235,12 +235,16 @@ cdm::Status ClearKeyCdm::GenerateKeyRequest(const char* type, int type_size, ...@@ -235,12 +235,16 @@ cdm::Status ClearKeyCdm::GenerateKeyRequest(const char* type, int type_size,
client_.session_id().size()); client_.session_id().size());
latest_session_id_ = client_.session_id(); latest_session_id_ = client_.session_id();
// TODO(tomfinegan): Get rid of this copy. DCHECK(!key_request->message());
key_request->set_message(allocator_->Allocate(client_.key_message_length())); if (client_.key_message_length()) {
DCHECK(key_request->message()); // TODO(tomfinegan): Get rid of this copy.
DCHECK_EQ(key_request->message()->size(), client_.key_message_length()); key_request->set_message(
memcpy(key_request->message()->data(), allocator_->Allocate(client_.key_message_length()));
client_.key_message(), client_.key_message_length()); DCHECK(key_request->message());
DCHECK_EQ(key_request->message()->size(), client_.key_message_length());
memcpy(key_request->message()->data(),
client_.key_message(), client_.key_message_length());
}
key_request->set_default_url(client_.default_url().data(), key_request->set_default_url(client_.default_url().data(),
client_.default_url().size()); client_.default_url().size());
......
...@@ -645,24 +645,37 @@ void ContentDecryptorDelegate::KeyMessage(PP_Var key_system_var, ...@@ -645,24 +645,37 @@ void ContentDecryptorDelegate::KeyMessage(PP_Var key_system_var,
return; return;
} }
EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true); scoped_array<uint8> message_array;
if (!enter.succeeded()) { int message_size = 0;
decryptor_client_->KeyError(key_system_string->value(),
session_id_string->value(), if (message_resource) {
media::Decryptor::kUnknownError, EnterResourceNoLock<PPB_Buffer_API> enter(message_resource, true);
0); if (!enter.succeeded()) {
return; decryptor_client_->KeyError(key_system_string->value(),
} session_id_string->value(),
media::Decryptor::kUnknownError,
0);
return;
}
BufferAutoMapper mapper(enter.object()); BufferAutoMapper mapper(enter.object());
scoped_array<uint8> message_array(new uint8[mapper.size()]); if (!mapper.data() || !mapper.size()) {
if (mapper.data() && mapper.size()) decryptor_client_->KeyError(key_system_string->value(),
session_id_string->value(),
media::Decryptor::kUnknownError,
0);
return;
}
message_size = mapper.size();
message_array.reset(new uint8[message_size]);
memcpy(message_array.get(), mapper.data(), mapper.size()); memcpy(message_array.get(), mapper.data(), mapper.size());
}
decryptor_client_->KeyMessage(key_system_string->value(), decryptor_client_->KeyMessage(key_system_string->value(),
session_id_string->value(), session_id_string->value(),
message_array.Pass(), message_array.Pass(),
mapper.size(), message_size,
default_url_string->value()); default_url_string->value());
} }
......
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