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

Unified Diff: webkit/media/crypto/proxy_decryptor.cc

Issue 10822026: Implement "Key Presence" step in "Encrypted Block Encounted" algorithm in EME. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 5 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
Index: webkit/media/crypto/proxy_decryptor.cc
diff --git a/webkit/media/crypto/proxy_decryptor.cc b/webkit/media/crypto/proxy_decryptor.cc
index e20f8eeb4adfd05d0dcb37f57a47fefb1949c7db..e05fc57196bc80fce939a7e8b0e828a6260c43b5 100644
--- a/webkit/media/crypto/proxy_decryptor.cc
+++ b/webkit/media/crypto/proxy_decryptor.cc
@@ -4,6 +4,8 @@
#include "webkit/media/crypto/proxy_decryptor.h"
+#include <algorithm>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
@@ -23,9 +25,6 @@
// Fix include order here when the bug is fixed.
#include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.h"
-using media::Decryptor;
-using media::DecoderBuffer;
-
namespace webkit_media {
static scoped_refptr<webkit::ppapi::PluginInstance> CreatePluginInstance(
@@ -50,15 +49,14 @@ static scoped_refptr<webkit::ppapi::PluginInstance> CreatePluginInstance(
// TODO(xhwang): Simplify this function. This is mostly caused by the fact that
// we need to copy a scoped_array<uint8>.
static void FireNeedKey(media::DecryptorClient* client,
- const scoped_refptr<DecoderBuffer>& encrypted) {
+ const scoped_refptr<media::DecoderBuffer>& encrypted) {
DCHECK(client);
DCHECK(encrypted);
DCHECK(encrypted->GetDecryptConfig());
- const uint8* key_id = encrypted->GetDecryptConfig()->key_id();
- const int key_id_size = encrypted->GetDecryptConfig()->key_id_size();
- scoped_array<uint8> key_id_array(new uint8[key_id_size]);
- memcpy(key_id_array.get(), key_id, key_id_size);
- client->NeedKey("", "", key_id_array.Pass(), key_id_size);
+ std::string key_id = encrypted->GetDecryptConfig()->key_id();
+ scoped_array<uint8> key_id_array(new uint8[key_id.size()]);
+ memcpy(key_id_array.get(), key_id.data(), key_id.size());
+ client->NeedKey("", "", key_id_array.Pass(), key_id.size());
}
ProxyDecryptor::ProxyDecryptor(
@@ -67,7 +65,8 @@ ProxyDecryptor::ProxyDecryptor(
WebKit::WebFrame* web_frame)
: client_(decryptor_client),
web_media_player_client_(web_media_player_client),
- web_frame_(web_frame) {
+ web_frame_(web_frame),
+ is_shutting_down_(false) {
}
ProxyDecryptor::~ProxyDecryptor() {
@@ -80,13 +79,12 @@ void ProxyDecryptor::GenerateKeyRequest(const std::string& key_system,
// only creates a new decryptor when |decryptor_| is not initialized.
DVLOG(1) << "GenerateKeyRequest: key_system = " << key_system;
if (!decryptor_.get()) {
- base::AutoLock auto_lock(decryptor_lock_);
+ base::AutoLock auto_lock(lock_);
decryptor_ = CreateDecryptor(key_system);
}
if (!decryptor_.get()) {
- DCHECK(client_);
- client_->KeyError(key_system, "", Decryptor::kUnknownError, 0);
+ client_->KeyError(key_system, "", media::Decryptor::kUnknownError, 0);
return;
}
@@ -108,10 +106,12 @@ void ProxyDecryptor::AddKey(const std::string& key_system,
std::vector<base::Closure> closures_to_run;
{
- base::AutoLock auto_lock(pending_decrypt_closures_lock_);
+ base::AutoLock auto_lock(lock_);
std::swap(pending_decrypt_closures_, closures_to_run);
}
+ // Fire all pending callbacks here because only the |decryptor_| knows if the
+ // pending buffers can be decrypted or not.
for (std::vector<base::Closure>::iterator iter = closures_to_run.begin();
iter != closures_to_run.end();
++iter) {
@@ -129,30 +129,31 @@ void ProxyDecryptor::CancelKeyRequest(const std::string& key_system,
}
void ProxyDecryptor::Decrypt(
- const scoped_refptr<DecoderBuffer>& encrypted,
+ const scoped_refptr<media::DecoderBuffer>& encrypted,
const DecryptCB& decrypt_cb) {
- DVLOG(2) << "Decrypt()";
-
// This is safe as we do not replace/delete an existing decryptor at run-time.
- Decryptor* decryptor = NULL;
+ media::Decryptor* decryptor = NULL;
{
- base::AutoLock auto_lock(decryptor_lock_);
+ base::AutoLock auto_lock(lock_);
+ if (is_shutting_down_) {
+ DVLOG(1) << "Decrypt(): fire decrypt callbacks with kError.";
+ decrypt_cb.Run(kError, NULL);
+ return;
+ }
decryptor = decryptor_.get();
- }
-
- if (!decryptor) {
- DVLOG(1) << "ProxyDecryptor::Decrypt(): decryptor not initialized.";
- {
- base::AutoLock auto_lock(pending_decrypt_closures_lock_);
- pending_decrypt_closures_.push_back(base::Bind(
- &ProxyDecryptor::DecryptOnMessageLoop, base::Unretained(this),
- base::MessageLoopProxy::current(), encrypted, decrypt_cb));
+ if (!decryptor) {
+ DVLOG(1) << "ProxyDecryptor::Decrypt(): decryptor not initialized.";
+ pending_decrypt_closures_.push_back(
+ base::Bind(&ProxyDecryptor::DecryptOnMessageLoop,
+ base::Unretained(this),
+ base::MessageLoopProxy::current(), encrypted,
+ decrypt_cb));
+ // TODO(xhwang): The same NeedKey may be fired here and multiple times in
+ // OnBufferDecrypted(). While the spec says only one NeedKey should be
+ // fired. Leave them as is since the spec about this may change.
+ FireNeedKey(client_, encrypted);
+ return;
}
- // TODO(xhwang): The same NeedKey may be fired here and multiple times in
- // OnBufferDecrypted(). While the spec says only one NeedKey should be
- // fired. Leave them as is since the spec about this may change.
- FireNeedKey(client_, encrypted);
- return;
}
decryptor->Decrypt(encrypted, base::Bind(
@@ -160,7 +161,26 @@ void ProxyDecryptor::Decrypt(
base::MessageLoopProxy::current(), encrypted, decrypt_cb));
}
-scoped_ptr<Decryptor> ProxyDecryptor::CreatePpapiDecryptor(
+void ProxyDecryptor::Stop() {
+ DVLOG(1) << "AddKey()";
+
+ std::vector<base::Closure> closures_to_run;
+ {
+ base::AutoLock auto_lock(lock_);
+ if (decryptor_.get())
+ decryptor_->Stop();
+ is_shutting_down_ = true;
+ std::swap(pending_decrypt_closures_, closures_to_run);
+ }
+
+ for (std::vector<base::Closure>::iterator iter = closures_to_run.begin();
+ iter != closures_to_run.end();
+ ++iter) {
+ iter->Run();
+ }
+}
+
+scoped_ptr<media::Decryptor> ProxyDecryptor::CreatePpapiDecryptor(
const std::string& key_system) {
DCHECK(client_);
DCHECK(web_media_player_client_);
@@ -172,18 +192,19 @@ scoped_ptr<Decryptor> ProxyDecryptor::CreatePpapiDecryptor(
CreatePluginInstance(plugin_type, web_media_player_client_, web_frame_);
if (!plugin_instance) {
DVLOG(1) << "PpapiDecryptor: plugin instance creation failed.";
- return scoped_ptr<Decryptor>();
+ return scoped_ptr<media::Decryptor>();
}
- return scoped_ptr<Decryptor>(new PpapiDecryptor(client_, plugin_instance));
+ return scoped_ptr<media::Decryptor>(new PpapiDecryptor(client_,
+ plugin_instance));
}
-scoped_ptr<Decryptor> ProxyDecryptor::CreateDecryptor(
+scoped_ptr<media::Decryptor> ProxyDecryptor::CreateDecryptor(
const std::string& key_system) {
DCHECK(client_);
if (CanUseAesDecryptor(key_system))
- return scoped_ptr<Decryptor>(new media::AesDecryptor(client_));
+ return scoped_ptr<media::Decryptor>(new media::AesDecryptor(client_));
// We only support AesDecryptor and PpapiDecryptor. So if we cannot
// use the AesDecryptor, then we'll try to create a PpapiDecryptor for given
@@ -193,9 +214,8 @@ scoped_ptr<Decryptor> ProxyDecryptor::CreateDecryptor(
void ProxyDecryptor::DecryptOnMessageLoop(
const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
- const scoped_refptr<DecoderBuffer>& encrypted,
- const Decryptor::DecryptCB& decrypt_cb) {
- DVLOG(2) << "DecryptOnMessageLoop()";
+ const scoped_refptr<media::DecoderBuffer>& encrypted,
+ const media::Decryptor::DecryptCB& decrypt_cb) {
DCHECK(decryptor_.get());
if (!message_loop_proxy->BelongsToCurrentThread()) {
@@ -205,27 +225,40 @@ void ProxyDecryptor::DecryptOnMessageLoop(
return;
}
+ {
+ base::AutoLock auto_lock(lock_);
+ if (is_shutting_down_) {
+ DVLOG(1) << "DecryptOnMessageLoop(): fire decrypt callbacks with kError.";
+ decrypt_cb.Run(kError, NULL);
+ return;
+ }
+ }
+
decryptor_->Decrypt(encrypted, base::Bind(&ProxyDecryptor::OnBufferDecrypted,
scherkus (not reviewing) 2012/08/02 18:05:32 nit: technically this is mixing style: params on n
xhwang 2012/08/03 20:08:10 Done.
base::Unretained(this), message_loop_proxy, encrypted, decrypt_cb));
}
void ProxyDecryptor::OnBufferDecrypted(
const scoped_refptr<base::MessageLoopProxy>& message_loop_proxy,
- const scoped_refptr<DecoderBuffer>& encrypted,
- const Decryptor::DecryptCB& decrypt_cb,
- Decryptor::DecryptStatus status,
- const scoped_refptr<DecoderBuffer>& decrypted) {
- DVLOG(2) << "OnBufferDecrypted()";
-
- if (status == Decryptor::kSuccess || status == Decryptor::kError) {
+ const scoped_refptr<media::DecoderBuffer>& encrypted,
+ const media::Decryptor::DecryptCB& decrypt_cb,
+ media::Decryptor::DecryptStatus status,
+ const scoped_refptr<media::DecoderBuffer>& decrypted) {
+ if (status == media::Decryptor::kSuccess ||
+ status == media::Decryptor::kError) {
decrypt_cb.Run(status, decrypted);
return;
}
- DCHECK_EQ(status, Decryptor::kNoKey);
+ DCHECK_EQ(status, media::Decryptor::kNoKey);
DVLOG(1) << "OnBufferDecrypted(): kNoKey fired";
{
- base::AutoLock auto_lock(pending_decrypt_closures_lock_);
+ base::AutoLock auto_lock(lock_);
+ if (is_shutting_down_) {
+ DVLOG(1) << "OnBufferDecrypted(): fire decrypt callbacks with kError.";
+ decrypt_cb.Run(kError, NULL);
+ return;
+ }
pending_decrypt_closures_.push_back(base::Bind(
&ProxyDecryptor::DecryptOnMessageLoop, base::Unretained(this),
message_loop_proxy, encrypted, decrypt_cb));

Powered by Google App Engine
This is Rietveld 408576698