Index: media/crypto/aes_decryptor.cc |
diff --git a/media/crypto/aes_decryptor.cc b/media/crypto/aes_decryptor.cc |
index cbb75b37bd33457f74b9f540d652ae01bbd77c19..b7ae9eff5886976b100b939c96eb9e54d3c2fca9 100644 |
--- a/media/crypto/aes_decryptor.cc |
+++ b/media/crypto/aes_decryptor.cc |
@@ -6,17 +6,21 @@ |
#include "base/logging.h" |
#include "base/stl_util.h" |
+#include "base/string_number_conversions.h" |
#include "base/string_piece.h" |
#include "crypto/encryptor.h" |
#include "crypto/symmetric_key.h" |
#include "media/base/decoder_buffer.h" |
#include "media/base/decrypt_config.h" |
+#include "media/crypto/decryptor_client.h" |
namespace media { |
// TODO(xhwang): Get real IV from frames. |
static const char kInitialCounter[] = "0000000000000000"; |
+uint32 AesDecryptor::next_session_id_ = 1; |
+ |
// Decrypt |input| using |key|. |
// Return a DecoderBuffer with the decrypted data if decryption succeeded. |
// Return NULL if decryption failed. |
@@ -48,35 +52,83 @@ static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input, |
decrypted_text.size()); |
} |
-AesDecryptor::AesDecryptor() {} |
+AesDecryptor::AesDecryptor(DecryptorClient* client) |
+ : client_(client) { |
+} |
AesDecryptor::~AesDecryptor() { |
STLDeleteValues(&key_map_); |
} |
-void AesDecryptor::AddKey(const uint8* key_id, int key_id_size, |
- const uint8* key, int key_size) { |
- CHECK(key_id && key); |
- CHECK_GT(key_id_size, 0); |
- CHECK_GT(key_size, 0); |
+void AesDecryptor::GenerateKeyRequest(const std::string& key_system, |
+ const uint8* init_data, |
+ int init_data_length) { |
+ std::string session_id_string(base::UintToString(next_session_id_++)); |
- std::string key_id_string(reinterpret_cast<const char*>(key_id), key_id_size); |
- std::string key_string(reinterpret_cast<const char*>(key) , key_size); |
+ // For now, just fire the event with the |init_data| as the request. |
+ int message_length = init_data_length; |
+ scoped_array<uint8> message(new uint8[message_length]); |
+ memcpy(message.get(), init_data, message_length); |
+ |
+ client_->KeyMessage(key_system, session_id_string, |
+ message.Pass(), message_length, ""); |
+} |
+ |
+void AesDecryptor::AddKey(const std::string& key_system, |
+ const uint8* key, |
+ int key_length, |
+ const uint8* init_data, |
+ int init_data_length, |
+ const std::string& session_id) { |
+ CHECK(key); |
+ CHECK_GT(key_length, 0); |
+ |
+ // TODO(xhwang): Add |session_id| check after we figure out how: |
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=16550 |
+ |
+ const int kSupportedKeyLength = 16; // 128-bit key. |
+ if (key_length != kSupportedKeyLength) { |
+ DVLOG(1) << "Invalid key length: " << key_length; |
+ client_->KeyError(key_system, session_id, kUnknownError, 0); |
+ return; |
+ } |
+ // TODO(xhwang): Fix the decryptor to accept no |init_data|. See |
+ // http://crbug.com/123265. Until then, ensure a non-empty value is passed. |
+ static const uint8 kDummyInitData[1] = { 0 }; |
+ if (!init_data) { |
+ init_data = kDummyInitData; |
+ init_data_length = arraysize(kDummyInitData); |
+ } |
+ |
+ // TODO(xhwang): For now, use |init_data| for key ID. Make this more spec |
+ // compliant later (http://crbug.com/123262, http://crbug.com/123265). |
+ std::string key_id_string(reinterpret_cast<const char*>(init_data), |
+ init_data_length); |
+ std::string key_string(reinterpret_cast<const char*>(key) , key_length); |
crypto::SymmetricKey* symmetric_key = crypto::SymmetricKey::Import( |
crypto::SymmetricKey::AES, key_string); |
if (!symmetric_key) { |
DVLOG(1) << "Could not import key."; |
+ client_->KeyError(key_system, session_id, kUnknownError, 0); |
return; |
} |
- base::AutoLock auto_lock(lock_); |
- KeyMap::iterator found = key_map_.find(key_id_string); |
- if (found != key_map_.end()) { |
- delete found->second; |
- key_map_.erase(found); |
+ { |
+ base::AutoLock auto_lock(key_map_lock_); |
+ KeyMap::iterator found = key_map_.find(key_id_string); |
+ if (found != key_map_.end()) { |
+ delete found->second; |
+ key_map_.erase(found); |
+ } |
+ key_map_[key_id_string] = symmetric_key; |
} |
- key_map_[key_id_string] = symmetric_key; |
+ |
+ client_->KeyAdded(key_system, session_id); |
+} |
+ |
+void AesDecryptor::CancelKeyRequest(const std::string& /* key_system */, |
+ const std::string& /* session_id */) { |
} |
scoped_refptr<DecoderBuffer> AesDecryptor::Decrypt( |
@@ -90,7 +142,7 @@ scoped_refptr<DecoderBuffer> AesDecryptor::Decrypt( |
crypto::SymmetricKey* key = NULL; |
{ |
- base::AutoLock auto_lock(lock_); |
+ base::AutoLock auto_lock(key_map_lock_); |
KeyMap::const_iterator found = key_map_.find(key_id_string); |
if (found == key_map_.end()) { |
DVLOG(1) << "Could not find a matching key for given key ID."; |