diff options
author | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-22 03:42:02 +0000 |
---|---|---|
committer | xhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-22 03:42:02 +0000 |
commit | abd36b3af513028744c7e700bf00f73b6fb3b94a (patch) | |
tree | f15713db3c1050292261bc480d4e4ad11cb1332e /media | |
parent | 8d88545f5b25b783ede802a5c37f38e5f88422df (diff) | |
download | chromium_src-abd36b3af513028744c7e700bf00f73b6fb3b94a.zip chromium_src-abd36b3af513028744c7e700bf00f73b6fb3b94a.tar.gz chromium_src-abd36b3af513028744c7e700bf00f73b6fb3b94a.tar.bz2 |
Encrypted Media: Replace DecryptorClient with key event callbacks.
- Removed DecryptorClient and use key event callbacks.
- Renamed Decryptor::KeyAddedCB to Decryptor::NewKeyCB.
- ProxyDecryptor implements key event callbacks and WebMediaPlayerProxy does not handle key events anymore.
- PpapiDecryptor implements key event callbacks as well so ContentDecryptorDelegate doesn't call ProxyDecryptor directly.
Review URL: https://codereview.chromium.org/11226019
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@174495 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media')
-rw-r--r-- | media/base/decryptor.h | 34 | ||||
-rw-r--r-- | media/base/decryptor_client.h | 52 | ||||
-rw-r--r-- | media/base/mock_filters.cc | 12 | ||||
-rw-r--r-- | media/base/mock_filters.h | 36 | ||||
-rw-r--r-- | media/crypto/aes_decryptor.cc | 37 | ||||
-rw-r--r-- | media/crypto/aes_decryptor.h | 25 | ||||
-rw-r--r-- | media/crypto/aes_decryptor_unittest.cc | 27 | ||||
-rw-r--r-- | media/filters/audio_decoder_selector_unittest.cc | 2 | ||||
-rw-r--r-- | media/filters/decrypting_audio_decoder.cc | 2 | ||||
-rw-r--r-- | media/filters/decrypting_audio_decoder_unittest.cc | 4 | ||||
-rw-r--r-- | media/filters/decrypting_demuxer_stream.cc | 2 | ||||
-rw-r--r-- | media/filters/decrypting_demuxer_stream_unittest.cc | 6 | ||||
-rw-r--r-- | media/filters/decrypting_video_decoder.cc | 4 | ||||
-rw-r--r-- | media/filters/decrypting_video_decoder_unittest.cc | 8 | ||||
-rw-r--r-- | media/filters/pipeline_integration_test.cc | 152 | ||||
-rw-r--r-- | media/filters/video_decoder_selector_unittest.cc | 2 | ||||
-rw-r--r-- | media/media.gyp | 1 |
17 files changed, 178 insertions, 228 deletions
diff --git a/media/base/decryptor.h b/media/base/decryptor.h index fd51c96f..4cc05a1 100644 --- a/media/base/decryptor.h +++ b/media/base/decryptor.h @@ -90,16 +90,16 @@ class MEDIA_EXPORT Decryptor { virtual void CancelKeyRequest(const std::string& key_system, const std::string& session_id) = 0; - // Indicates that a key has been added to the Decryptor. - typedef base::Callback<void()> KeyAddedCB; + // Indicates that a new key has been added to the Decryptor. + typedef base::Callback<void()> NewKeyCB; - // Registers a KeyAddedCB which should be called when a key is added to the - // decryptor. Only one KeyAddedCB can be registered for one |stream_type|. + // Registers a NewKeyCB which should be called when a new key is added to the + // decryptor. Only one NewKeyCB can be registered for one |stream_type|. // If this function is called multiple times for the same |stream_type|, the // previously registered callback will be replaced. In other words, // registering a null callback cancels the originally registered callback. - virtual void RegisterKeyAddedCB(StreamType stream_type, - const KeyAddedCB& key_added_cb) = 0; + virtual void RegisterNewKeyCB(StreamType stream_type, + const NewKeyCB& key_added_cb) = 0; // Indicates completion of a decryption operation. // @@ -216,6 +216,28 @@ typedef base::Callback<void(Decryptor*)> DecryptorReadyCB; // fired immediately with NULL. typedef base::Callback<void(const DecryptorReadyCB&)> SetDecryptorReadyCB; + +// Key event callbacks. See the spec for details: +// http://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#event-summary +typedef base::Callback<void(const std::string& key_system, + const std::string& session_id)> KeyAddedCB; + +typedef base::Callback<void(const std::string& key_system, + const std::string& session_id, + media::Decryptor::KeyError error_code, + int system_code)> KeyErrorCB; + +typedef base::Callback<void(const std::string& key_system, + const std::string& session_id, + const std::string& message, + const std::string& default_url)> KeyMessageCB; + +typedef base::Callback<void(const std::string& key_system, + const std::string& session_id, + const std::string& type, + scoped_array<uint8> init_data, + int init_data_size)> NeedKeyCB; + } // namespace media #endif // MEDIA_BASE_DECRYPTOR_H_ diff --git a/media/base/decryptor_client.h b/media/base/decryptor_client.h deleted file mode 100644 index 14d09a9..0000000 --- a/media/base/decryptor_client.h +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_BASE_DECRYPTOR_CLIENT_H_ -#define MEDIA_BASE_DECRYPTOR_CLIENT_H_ - -#include <string> - -#include "base/memory/scoped_ptr.h" -#include "media/base/decryptor.h" - -namespace media { - -// Interface used by a decryptor to fire key events. -// See: http://dvcs.w3.org/hg/html-media/raw-file/tip/encrypted-media/encrypted-media.html#event-summary -class DecryptorClient { - public: - // Signals that a key has been added. - virtual void KeyAdded(const std::string& key_system, - const std::string& session_id) = 0; - - // Signals that a key error occurred. The |system_code| is key - // system-dependent. For clear key system, the |system_code| is always zero. - virtual void KeyError(const std::string& key_system, - const std::string& session_id, - Decryptor::KeyError error_code, - int system_code) = 0; - - // Signals that a key message has been generated. - virtual void KeyMessage(const std::string& key_system, - const std::string& session_id, - const std::string& message, - const std::string& default_url) = 0; - - // Signals that a key is needed for decryption. |key_system| and |session_id| - // can be empty if the key system has not been selected. - // TODO(xhwang): Figure out if "type" is optional for NeedKey fired from the - // decoder. - virtual void NeedKey(const std::string& key_system, - const std::string& session_id, - const std::string& type, - scoped_array<uint8> init_data, - int init_data_length) = 0; - - protected: - virtual ~DecryptorClient() {} -}; - -} // namespace media - -#endif // MEDIA_BASE_DECRYPTOR_CLIENT_H_ diff --git a/media/base/mock_filters.cc b/media/base/mock_filters.cc index c197ee2..692ab80 100644 --- a/media/base/mock_filters.cc +++ b/media/base/mock_filters.cc @@ -56,18 +56,6 @@ void MockDecryptor::InitializeVideoDecoder( InitializeVideoDecoderMock(*config, init_cb); } -MockDecryptorClient::MockDecryptorClient() {} - -MockDecryptorClient::~MockDecryptorClient() {} - -void MockDecryptorClient::NeedKey(const std::string& key_system, - const std::string& session_id, - const std::string& type, - scoped_array<uint8> init_data, - int init_data_length) { - NeedKeyMock(key_system, session_id, type, init_data.get(), init_data_length); -} - MockFilterCollection::MockFilterCollection() : demuxer_(new MockDemuxer()), video_decoder_(new MockVideoDecoder()), diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h index d5a27b0..1b47bcc 100644 --- a/media/base/mock_filters.h +++ b/media/base/mock_filters.h @@ -20,7 +20,6 @@ #include "media/base/audio_renderer.h" #include "media/base/decoder_buffer.h" #include "media/base/decryptor.h" -#include "media/base/decryptor_client.h" #include "media/base/demuxer.h" #include "media/base/filter_collection.h" #include "media/base/pipeline_status.h" @@ -208,8 +207,8 @@ class MockDecryptor : public Decryptor { const std::string& session_id)); MOCK_METHOD2(CancelKeyRequest, void(const std::string& key_system, const std::string& session_id)); - MOCK_METHOD2(RegisterKeyAddedCB, void(StreamType stream_type, - const KeyAddedCB& key_added_cb)); + MOCK_METHOD2(RegisterNewKeyCB, void(StreamType stream_type, + const NewKeyCB& new_key_cb)); MOCK_METHOD3(Decrypt, void(StreamType stream_type, const scoped_refptr<DecoderBuffer>& encrypted, const DecryptCB& decrypt_cb)); @@ -241,37 +240,6 @@ class MockDecryptor : public Decryptor { DISALLOW_COPY_AND_ASSIGN(MockDecryptor); }; -class MockDecryptorClient : public DecryptorClient { - public: - MockDecryptorClient(); - virtual ~MockDecryptorClient(); - - MOCK_METHOD2(KeyAdded, void(const std::string&, const std::string&)); - MOCK_METHOD4(KeyError, void(const std::string&, const std::string&, - Decryptor::KeyError, int)); - MOCK_METHOD4(KeyMessage, void(const std::string& key_system, - const std::string& session_id, - const std::string& message, - const std::string& default_url)); - // TODO(xhwang): This is a workaround of the issue that move-only parameters - // are not supported in mocked methods. Remove this when the issue is fixed - // (http://code.google.com/p/googletest/issues/detail?id=395) or when we use - // std::string instead of scoped_array<uint8> (http://crbug.com/130689). - MOCK_METHOD5(NeedKeyMock, void(const std::string& key_system, - const std::string& session_id, - const std::string& type, - const uint8* init_data, - int init_data_length)); - virtual void NeedKey(const std::string& key_system, - const std::string& session_id, - const std::string& type, - scoped_array<uint8> init_data, - int init_data_length) OVERRIDE; - - private: - DISALLOW_COPY_AND_ASSIGN(MockDecryptorClient); -}; - // FilterFactory that returns canned instances of mock filters. You can set // expectations on the filters and then pass the collection into a pipeline. class MockFilterCollection { diff --git a/media/crypto/aes_decryptor.cc b/media/crypto/aes_decryptor.cc index a4b6bc6..83f818e 100644 --- a/media/crypto/aes_decryptor.cc +++ b/media/crypto/aes_decryptor.cc @@ -14,7 +14,6 @@ #include "media/base/audio_decoder_config.h" #include "media/base/decoder_buffer.h" #include "media/base/decrypt_config.h" -#include "media/base/decryptor_client.h" #include "media/base/video_decoder_config.h" #include "media/base/video_frame.h" @@ -125,8 +124,14 @@ static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input, return output; } -AesDecryptor::AesDecryptor(DecryptorClient* client) - : client_(client) { +AesDecryptor::AesDecryptor(const KeyAddedCB& key_added_cb, + const KeyErrorCB& key_error_cb, + const KeyMessageCB& key_message_cb, + const NeedKeyCB& need_key_cb) + : key_added_cb_(key_added_cb), + key_error_cb_(key_error_cb), + key_message_cb_(key_message_cb), + need_key_cb_(need_key_cb) { } AesDecryptor::~AesDecryptor() { @@ -147,7 +152,7 @@ bool AesDecryptor::GenerateKeyRequest(const std::string& key_system, init_data_length); } - client_->KeyMessage(key_system, session_id_string, message, ""); + key_message_cb_.Run(key_system, session_id_string, message, ""); return true; } @@ -164,7 +169,7 @@ void AesDecryptor::AddKey(const std::string& key_system, // https://www.w3.org/Bugs/Public/show_bug.cgi?id=16550 if (key_length != DecryptConfig::kDecryptionKeySize) { DVLOG(1) << "Invalid key length: " << key_length; - client_->KeyError(key_system, session_id, Decryptor::kUnknownError, 0); + key_error_cb_.Run(key_system, session_id, Decryptor::kUnknownError, 0); return; } @@ -184,39 +189,39 @@ void AesDecryptor::AddKey(const std::string& key_system, scoped_ptr<DecryptionKey> decryption_key(new DecryptionKey(key_string)); if (!decryption_key.get()) { DVLOG(1) << "Could not create key."; - client_->KeyError(key_system, session_id, Decryptor::kUnknownError, 0); + key_error_cb_.Run(key_system, session_id, Decryptor::kUnknownError, 0); return; } if (!decryption_key->Init()) { DVLOG(1) << "Could not initialize decryption key."; - client_->KeyError(key_system, session_id, Decryptor::kUnknownError, 0); + key_error_cb_.Run(key_system, session_id, Decryptor::kUnknownError, 0); return; } SetKey(key_id_string, decryption_key.Pass()); - if (!audio_key_added_cb_.is_null()) - audio_key_added_cb_.Run(); + if (!new_audio_key_cb_.is_null()) + new_audio_key_cb_.Run(); - if (!video_key_added_cb_.is_null()) - video_key_added_cb_.Run(); + if (!new_video_key_cb_.is_null()) + new_video_key_cb_.Run(); - client_->KeyAdded(key_system, session_id); + key_added_cb_.Run(key_system, session_id); } void AesDecryptor::CancelKeyRequest(const std::string& key_system, const std::string& session_id) { } -void AesDecryptor::RegisterKeyAddedCB(StreamType stream_type, - const KeyAddedCB& key_added_cb) { +void AesDecryptor::RegisterNewKeyCB(StreamType stream_type, + const NewKeyCB& new_key_cb) { switch (stream_type) { case kAudio: - audio_key_added_cb_ = key_added_cb; + new_audio_key_cb_ = new_key_cb; break; case kVideo: - video_key_added_cb_ = key_added_cb; + new_video_key_cb_ = new_key_cb; break; default: NOTREACHED(); diff --git a/media/crypto/aes_decryptor.h b/media/crypto/aes_decryptor.h index e983805..999d661 100644 --- a/media/crypto/aes_decryptor.h +++ b/media/crypto/aes_decryptor.h @@ -22,15 +22,14 @@ class SymmetricKey; namespace media { -class DecryptorClient; - // Decrypts an AES encrypted buffer into an unencrypted buffer. The AES // encryption must be CTR with a key size of 128bits. class MEDIA_EXPORT AesDecryptor : public Decryptor { public: - // The AesDecryptor does not take ownership of the |client|. The |client| - // must be valid throughout the lifetime of the AesDecryptor. - explicit AesDecryptor(DecryptorClient* client); + AesDecryptor(const KeyAddedCB& key_added_cb, + const KeyErrorCB& key_error_cb, + const KeyMessageCB& key_message_cb, + const NeedKeyCB& need_key_cb); virtual ~AesDecryptor(); // Decryptor implementation. @@ -46,8 +45,8 @@ class MEDIA_EXPORT AesDecryptor : public Decryptor { const std::string& session_id) OVERRIDE; virtual void CancelKeyRequest(const std::string& key_system, const std::string& session_id) OVERRIDE; - virtual void RegisterKeyAddedCB(StreamType stream_type, - const KeyAddedCB& key_added_cb) OVERRIDE; + virtual void RegisterNewKeyCB(StreamType stream_type, + const NewKeyCB& key_added_cb) OVERRIDE; virtual void Decrypt(StreamType stream_type, const scoped_refptr<DecoderBuffer>& encrypted, const DecryptCB& decrypt_cb) OVERRIDE; @@ -96,6 +95,12 @@ class MEDIA_EXPORT AesDecryptor : public Decryptor { // the key. Returns NULL if no key is associated with |key_id|. DecryptionKey* GetKey(const std::string& key_id) const; + // Callbacks for firing key events. + KeyAddedCB key_added_cb_; + KeyErrorCB key_error_cb_; + KeyMessageCB key_message_cb_; + NeedKeyCB need_key_cb_; + // KeyMap owns the DecryptionKey* and must delete them when they are // not needed any more. typedef base::hash_map<std::string, DecryptionKey*> KeyMap; @@ -111,10 +116,8 @@ class MEDIA_EXPORT AesDecryptor : public Decryptor { // https://www.w3.org/Bugs/Public/show_bug.cgi?id=16739#c0 static uint32 next_session_id_; - DecryptorClient* const client_; - - KeyAddedCB audio_key_added_cb_; - KeyAddedCB video_key_added_cb_; + NewKeyCB new_audio_key_cb_; + NewKeyCB new_video_key_cb_; DISALLOW_COPY_AND_ASSIGN(AesDecryptor); }; diff --git a/media/crypto/aes_decryptor_unittest.cc b/media/crypto/aes_decryptor_unittest.cc index 2fab86d..f882150 100644 --- a/media/crypto/aes_decryptor_unittest.cc +++ b/media/crypto/aes_decryptor_unittest.cc @@ -227,7 +227,11 @@ static scoped_refptr<DecoderBuffer> CreateSubsampleEncryptedBuffer( class AesDecryptorTest : public testing::Test { public: AesDecryptorTest() - : decryptor_(&client_), + : decryptor_( + base::Bind(&AesDecryptorTest::KeyAdded, base::Unretained(this)), + base::Bind(&AesDecryptorTest::KeyError, base::Unretained(this)), + base::Bind(&AesDecryptorTest::KeyMessage, base::Unretained(this)), + NeedKeyCB()), decrypt_cb_(base::Bind(&AesDecryptorTest::BufferDecrypted, base::Unretained(this))), subsample_entries_(kSubsampleEntries, @@ -238,8 +242,8 @@ class AesDecryptorTest : public testing::Test { void GenerateKeyRequest(const uint8* key_id, int key_id_size) { std::string key_id_string(reinterpret_cast<const char*>(key_id), key_id_size); - EXPECT_CALL(client_, KeyMessage(kClearKeySystem, - StrNe(""), StrEq(key_id_string), "")) + EXPECT_CALL(*this, KeyMessage(kClearKeySystem, + StrNe(""), StrEq(key_id_string), "")) .WillOnce(SaveArg<1>(&session_id_string_)); EXPECT_TRUE(decryptor_.GenerateKeyRequest(kClearKeySystem, "", key_id, key_id_size)); @@ -247,15 +251,15 @@ class AesDecryptorTest : public testing::Test { void AddKeyAndExpectToSucceed(const uint8* key_id, int key_id_size, const uint8* key, int key_size) { - EXPECT_CALL(client_, KeyAdded(kClearKeySystem, session_id_string_)); + EXPECT_CALL(*this, KeyAdded(kClearKeySystem, session_id_string_)); decryptor_.AddKey(kClearKeySystem, key, key_size, key_id, key_id_size, session_id_string_); } void AddKeyAndExpectToFail(const uint8* key_id, int key_id_size, const uint8* key, int key_size) { - EXPECT_CALL(client_, KeyError(kClearKeySystem, session_id_string_, - Decryptor::kUnknownError, 0)); + EXPECT_CALL(*this, KeyError(kClearKeySystem, session_id_string_, + Decryptor::kUnknownError, 0)); decryptor_.AddKey(kClearKeySystem, key, key_size, key_id, key_id_size, session_id_string_); } @@ -306,7 +310,14 @@ class AesDecryptorTest : public testing::Test { decryptor_.Decrypt(Decryptor::kVideo, encrypted, decrypt_cb_); } - MockDecryptorClient client_; + MOCK_METHOD2(KeyAdded, void(const std::string&, const std::string&)); + MOCK_METHOD4(KeyError, void(const std::string&, const std::string&, + Decryptor::KeyError, int)); + MOCK_METHOD4(KeyMessage, void(const std::string& key_system, + const std::string& session_id, + const std::string& message, + const std::string& default_url)); + AesDecryptor decryptor_; std::string session_id_string_; AesDecryptor::DecryptCB decrypt_cb_; @@ -314,7 +325,7 @@ class AesDecryptorTest : public testing::Test { }; TEST_F(AesDecryptorTest, GenerateKeyRequestWithNullInitData) { - EXPECT_CALL(client_, KeyMessage(kClearKeySystem, StrNe(""), "", "")); + EXPECT_CALL(*this, KeyMessage(kClearKeySystem, StrNe(""), "", "")); EXPECT_TRUE(decryptor_.GenerateKeyRequest(kClearKeySystem, "", NULL, 0)); } diff --git a/media/filters/audio_decoder_selector_unittest.cc b/media/filters/audio_decoder_selector_unittest.cc index 7b0631a..f8792cc 100644 --- a/media/filters/audio_decoder_selector_unittest.cc +++ b/media/filters/audio_decoder_selector_unittest.cc @@ -108,7 +108,7 @@ class AudioDecoderSelectorTest : public ::testing::Test { AudioDecoderConfig encrypted_audio_config_; scoped_refptr<StrictMock<MockDemuxerStream> > demuxer_stream_; // Use NiceMock since we don't care about most of calls on the decryptor, e.g. - // RegisterKeyAddedCB(). + // RegisterNewKeyCB(). scoped_ptr<NiceMock<MockDecryptor> > decryptor_; scoped_refptr<StrictMock<MockAudioDecoder> > decoder_1_; scoped_refptr<StrictMock<MockAudioDecoder> > decoder_2_; diff --git a/media/filters/decrypting_audio_decoder.cc b/media/filters/decrypting_audio_decoder.cc index 42d7a1b..b55907e 100644 --- a/media/filters/decrypting_audio_decoder.cc +++ b/media/filters/decrypting_audio_decoder.cc @@ -199,7 +199,7 @@ void DecryptingAudioDecoder::FinishInitialization(bool success) { bytes_per_sample_ = ChannelLayoutToChannelCount(channel_layout_) * bits_per_channel_ / kBitsPerByte; - decryptor_->RegisterKeyAddedCB( + decryptor_->RegisterNewKeyCB( Decryptor::kAudio, BIND_TO_LOOP(&DecryptingAudioDecoder::OnKeyAdded)); state_ = kIdle; diff --git a/media/filters/decrypting_audio_decoder_unittest.cc b/media/filters/decrypting_audio_decoder_unittest.cc index 0621888..c8c0f0f 100644 --- a/media/filters/decrypting_audio_decoder_unittest.cc +++ b/media/filters/decrypting_audio_decoder_unittest.cc @@ -105,7 +105,7 @@ class DecryptingAudioDecoderTest : public testing::Test { .WillOnce(RunCallback<1>(true)); EXPECT_CALL(*this, RequestDecryptorNotification(_)) .WillOnce(RunCallbackIfNotNull(decryptor_.get())); - EXPECT_CALL(*decryptor_, RegisterKeyAddedCB(Decryptor::kAudio, _)) + EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _)) .WillOnce(SaveArg<1>(&key_added_cb_)); AudioDecoderConfig config(kCodecVorbis, 16, CHANNEL_LAYOUT_STEREO, 44100, @@ -224,7 +224,7 @@ class DecryptingAudioDecoderTest : public testing::Test { DemuxerStream::ReadCB pending_demuxer_read_cb_; Decryptor::DecoderInitCB pending_init_cb_; - Decryptor::KeyAddedCB key_added_cb_; + Decryptor::NewKeyCB key_added_cb_; Decryptor::AudioDecodeCB pending_audio_decode_cb_; // Constant buffer/frames to be returned by the |demuxer_| and |decryptor_|. diff --git a/media/filters/decrypting_demuxer_stream.cc b/media/filters/decrypting_demuxer_stream.cc index 78bf74a..53e921c 100644 --- a/media/filters/decrypting_demuxer_stream.cc +++ b/media/filters/decrypting_demuxer_stream.cc @@ -191,7 +191,7 @@ void DecryptingDemuxerStream::SetDecryptor(Decryptor* decryptor) { return; } - decryptor_->RegisterKeyAddedCB( + decryptor_->RegisterNewKeyCB( GetDecryptorStreamType(), BIND_TO_LOOP(&DecryptingDemuxerStream::OnKeyAdded)); diff --git a/media/filters/decrypting_demuxer_stream_unittest.cc b/media/filters/decrypting_demuxer_stream_unittest.cc index e1f13bd..0b61ea5 100644 --- a/media/filters/decrypting_demuxer_stream_unittest.cc +++ b/media/filters/decrypting_demuxer_stream_unittest.cc @@ -115,7 +115,7 @@ class DecryptingDemuxerStreamTest : public testing::Test { void Initialize() { EXPECT_CALL(*this, RequestDecryptorNotification(_)) .WillOnce(RunCallbackIfNotNull(decryptor_.get())); - EXPECT_CALL(*decryptor_, RegisterKeyAddedCB(Decryptor::kAudio, _)) + EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kAudio, _)) .WillOnce(SaveArg<1>(&key_added_cb_)); AudioDecoderConfig input_config( @@ -222,7 +222,7 @@ class DecryptingDemuxerStreamTest : public testing::Test { scoped_refptr<StrictMock<MockDemuxerStream> > input_video_stream_; DemuxerStream::ReadCB pending_demuxer_read_cb_; - Decryptor::KeyAddedCB key_added_cb_; + Decryptor::NewKeyCB key_added_cb_; Decryptor::DecryptCB pending_decrypt_cb_; // Constant buffers to be returned by the input demuxer streams and the @@ -257,7 +257,7 @@ TEST_F(DecryptingDemuxerStreamTest, Initialize_InvalidAudioConfig) { TEST_F(DecryptingDemuxerStreamTest, Initialize_NormalVideo) { EXPECT_CALL(*this, RequestDecryptorNotification(_)) .WillOnce(RunCallbackIfNotNull(decryptor_.get())); - EXPECT_CALL(*decryptor_, RegisterKeyAddedCB(Decryptor::kVideo, _)) + EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _)) .WillOnce(SaveArg<1>(&key_added_cb_)); VideoDecoderConfig config(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, diff --git a/media/filters/decrypting_video_decoder.cc b/media/filters/decrypting_video_decoder.cc index ebb72c2..7117d753 100644 --- a/media/filters/decrypting_video_decoder.cc +++ b/media/filters/decrypting_video_decoder.cc @@ -125,7 +125,7 @@ void DecryptingVideoDecoder::Stop(const base::Closure& closure) { // render thread to be processing messages to complete (such as PPAPI // callbacks). if (decryptor_) { - decryptor_->RegisterKeyAddedCB(Decryptor::kVideo, Decryptor::KeyAddedCB()); + decryptor_->RegisterNewKeyCB(Decryptor::kVideo, Decryptor::NewKeyCB()); decryptor_->DeinitializeDecoder(Decryptor::kVideo); decryptor_ = NULL; } @@ -187,7 +187,7 @@ void DecryptingVideoDecoder::FinishInitialization(bool success) { return; } - decryptor_->RegisterKeyAddedCB(Decryptor::kVideo, BindToCurrentLoop( + decryptor_->RegisterNewKeyCB(Decryptor::kVideo, BindToCurrentLoop( base::Bind(&DecryptingVideoDecoder::OnKeyAdded, this))); // Success! diff --git a/media/filters/decrypting_video_decoder_unittest.cc b/media/filters/decrypting_video_decoder_unittest.cc index a29d444..32ea01c 100644 --- a/media/filters/decrypting_video_decoder_unittest.cc +++ b/media/filters/decrypting_video_decoder_unittest.cc @@ -106,7 +106,7 @@ class DecryptingVideoDecoderTest : public testing::Test { EXPECT_CALL(*decryptor_, InitializeVideoDecoderMock(_, _)) .Times(AtMost(1)) .WillOnce(RunCallback<1>(true)); - EXPECT_CALL(*decryptor_, RegisterKeyAddedCB(Decryptor::kVideo, _)) + EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, _)) .WillOnce(SaveArg<1>(&key_added_cb_)); config_.Initialize(kCodecVP8, VIDEO_CODEC_PROFILE_UNKNOWN, kVideoFormat, @@ -218,8 +218,8 @@ class DecryptingVideoDecoderTest : public testing::Test { } void Stop() { - EXPECT_CALL(*decryptor_, RegisterKeyAddedCB(Decryptor::kVideo, - IsNullCallback())) + EXPECT_CALL(*decryptor_, RegisterNewKeyCB(Decryptor::kVideo, + IsNullCallback())) .Times(AtMost(1)); EXPECT_CALL(*decryptor_, DeinitializeDecoder(Decryptor::kVideo)) .WillRepeatedly(InvokeWithoutArgs( @@ -243,7 +243,7 @@ class DecryptingVideoDecoderTest : public testing::Test { DemuxerStream::ReadCB pending_demuxer_read_cb_; Decryptor::DecoderInitCB pending_init_cb_; - Decryptor::KeyAddedCB key_added_cb_; + Decryptor::NewKeyCB key_added_cb_; Decryptor::VideoDecodeCB pending_video_decode_cb_; // Constant buffer/frames to be returned by the |demuxer_| and |decryptor_|. diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc index 088d991..e196d58 100644 --- a/media/filters/pipeline_integration_test.cc +++ b/media/filters/pipeline_integration_test.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/string_util.h" #include "media/base/decoder_buffer.h" -#include "media/base/decryptor_client.h" #include "media/base/test_data_util.h" #include "media/crypto/aes_decryptor.h" @@ -32,6 +31,76 @@ static const uint8 kSecretKey[] = { static const int kAppendWholeFile = -1; +class FakeEncryptedMedia { + public: + FakeEncryptedMedia() + : decryptor_(base::Bind(&FakeEncryptedMedia::KeyAdded, + base::Unretained(this)), + base::Bind(&FakeEncryptedMedia::KeyError, + base::Unretained(this)), + base::Bind(&FakeEncryptedMedia::KeyMessage, + base::Unretained(this)), + base::Bind(&FakeEncryptedMedia::NeedKey, + base::Unretained(this))) { + } + + AesDecryptor* decryptor() { + return &decryptor_; + } + + // Callbacks for firing key events. + void KeyAdded(const std::string& key_system, const std::string& session_id) { + EXPECT_EQ(kClearKeySystem, key_system); + EXPECT_FALSE(session_id.empty()); + } + + void KeyError(const std::string& key_system, + const std::string& session_id, + AesDecryptor::KeyError error_code, + int system_code) { + FAIL() << "Unexpected Key Error"; + } + + void KeyMessage(const std::string& key_system, + const std::string& session_id, + const std::string& message, + const std::string& default_url) { + EXPECT_EQ(kClearKeySystem, key_system); + EXPECT_FALSE(session_id.empty()); + EXPECT_FALSE(message.empty()); + + current_key_system_ = key_system; + current_session_id_ = session_id; + } + + void NeedKey(const std::string& key_system, + const std::string& session_id, + const std::string& type, + scoped_array<uint8> init_data, int init_data_length) { + current_key_system_ = key_system; + current_session_id_ = session_id; + + // When NeedKey is called from the demuxer, the |key_system| will be empty. + // In this case, we need to call GenerateKeyRequest() to initialize a + // session (which will call KeyMessage). + if (current_key_system_.empty()) { + EXPECT_TRUE(current_session_id_.empty()); + EXPECT_TRUE(decryptor_.GenerateKeyRequest( + kClearKeySystem, type, kInitData, arraysize(kInitData))); + } + + EXPECT_FALSE(current_key_system_.empty()); + EXPECT_FALSE(current_session_id_.empty()); + decryptor_.AddKey(current_key_system_, kSecretKey, arraysize(kSecretKey), + init_data.get(), init_data_length, current_session_id_); + } + + private: + AesDecryptor decryptor_; + std::string current_key_system_; + std::string current_session_id_; +}; + // Helper class that emulates calls made on the ChunkDemuxer by the // Media Source API. class MockMediaSource { @@ -59,8 +128,9 @@ class MockMediaSource { virtual ~MockMediaSource() {} const scoped_refptr<ChunkDemuxer>& demuxer() const { return chunk_demuxer_; } - void set_decryptor_client(DecryptorClient* decryptor_client) { - decryptor_client_ = decryptor_client; + + void set_need_key_cb(const NeedKeyCB& need_key_cb) { + need_key_cb_ = need_key_cb; } void Seek(int new_position, int seek_append_size) { @@ -125,8 +195,7 @@ class MockMediaSource { scoped_array<uint8> init_data, int init_data_size) { DCHECK(init_data.get()); DCHECK_GT(init_data_size, 0); - DCHECK(decryptor_client_); - decryptor_client_->NeedKey("", "", type, init_data.Pass(), init_data_size); + need_key_cb_.Run("", "", type, init_data.Pass(), init_data_size); } private: @@ -136,70 +205,7 @@ class MockMediaSource { int initial_append_size_; std::string mimetype_; scoped_refptr<ChunkDemuxer> chunk_demuxer_; - DecryptorClient* decryptor_client_; -}; - -class FakeDecryptorClient : public DecryptorClient { - public: - FakeDecryptorClient() : decryptor_(this) {} - - AesDecryptor* decryptor() { - return &decryptor_; - } - - // DecryptorClient implementation. - virtual void KeyAdded(const std::string& key_system, - const std::string& session_id) { - EXPECT_EQ(kClearKeySystem, key_system); - EXPECT_FALSE(session_id.empty()); - } - - virtual void KeyError(const std::string& key_system, - const std::string& session_id, - AesDecryptor::KeyError error_code, - int system_code) { - NOTIMPLEMENTED(); - } - - virtual void KeyMessage(const std::string& key_system, - const std::string& session_id, - const std::string& message, - const std::string& default_url) { - EXPECT_EQ(kClearKeySystem, key_system); - EXPECT_FALSE(session_id.empty()); - EXPECT_FALSE(message.empty()); - - current_key_system_ = key_system; - current_session_id_ = session_id; - } - - virtual void NeedKey(const std::string& key_system, - const std::string& session_id, - const std::string& type, - scoped_array<uint8> init_data, - int init_data_length) { - current_key_system_ = key_system; - current_session_id_ = session_id; - - // When NeedKey is called from the demuxer, the |key_system| will be empty. - // In this case, we need to call GenerateKeyRequest() to initialize a - // session (which will call KeyMessage). - if (current_key_system_.empty()) { - DCHECK(current_session_id_.empty()); - EXPECT_TRUE(decryptor_.GenerateKeyRequest( - kClearKeySystem, type, kInitData, arraysize(kInitData))); - } - - EXPECT_FALSE(current_key_system_.empty()); - EXPECT_FALSE(current_session_id_.empty()); - decryptor_.AddKey(current_key_system_, kSecretKey, arraysize(kSecretKey), - init_data.get(), init_data_length, current_session_id_); - } - - private: - AesDecryptor decryptor_; - std::string current_key_system_; - std::string current_session_id_; + NeedKeyCB need_key_cb_; }; class PipelineIntegrationTest @@ -224,7 +230,7 @@ class PipelineIntegrationTest void StartPipelineWithEncryptedMedia( MockMediaSource* source, - FakeDecryptorClient* encrypted_media) { + FakeEncryptedMedia* encrypted_media) { EXPECT_CALL(*this, OnBufferingState(Pipeline::kHaveMetadata)) .Times(AtMost(1)); EXPECT_CALL(*this, OnBufferingState(Pipeline::kPrerollCompleted)) @@ -237,7 +243,8 @@ class PipelineIntegrationTest base::Bind(&PipelineIntegrationTest::OnBufferingState, base::Unretained(this))); - source->set_decryptor_client(encrypted_media); + source->set_need_key_cb(base::Bind(&FakeEncryptedMedia::NeedKey, + base::Unretained(encrypted_media))); message_loop_.Run(); } @@ -274,7 +281,6 @@ class PipelineIntegrationTest } }; - TEST_F(PipelineIntegrationTest, BasicPlayback) { ASSERT_TRUE(Start(GetTestDataFilePath("bear-320x240.webm"), PIPELINE_OK)); @@ -372,7 +378,7 @@ TEST_F(PipelineIntegrationTest, BasicPlayback_16x9AspectRatio) { TEST_F(PipelineIntegrationTest, EncryptedPlayback) { MockMediaSource source("bear-320x240-encrypted.webm", kWebM, 219816); - FakeDecryptorClient encrypted_media; + FakeEncryptedMedia encrypted_media; StartPipelineWithEncryptedMedia(&source, &encrypted_media); source.EndOfStream(); diff --git a/media/filters/video_decoder_selector_unittest.cc b/media/filters/video_decoder_selector_unittest.cc index dcf390d..9ca8c85 100644 --- a/media/filters/video_decoder_selector_unittest.cc +++ b/media/filters/video_decoder_selector_unittest.cc @@ -129,7 +129,7 @@ class VideoDecoderSelectorTest : public ::testing::Test { VideoDecoderConfig encrypted_video_config_; scoped_refptr<StrictMock<MockDemuxerStream> > demuxer_stream_; // Use NiceMock since we don't care about most of calls on the decryptor, e.g. - // RegisterKeyAddedCB(). + // RegisterNewKeyCB(). scoped_ptr<NiceMock<MockDecryptor> > decryptor_; scoped_refptr<StrictMock<MockVideoDecoder> > decoder_1_; scoped_refptr<StrictMock<MockVideoDecoder> > decoder_2_; diff --git a/media/media.gyp b/media/media.gyp index 6879847..b7a8b4c 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -212,7 +212,6 @@ 'base/decoder_buffer_queue.h', 'base/decryptor.cc', 'base/decryptor.h', - 'base/decryptor_client.h', 'base/decrypt_config.cc', 'base/decrypt_config.h', 'base/demuxer.cc', |