diff --git a/packager/media/base/widevine_key_source.cc b/packager/media/base/widevine_key_source.cc index d436f223ae..c5bd13692b 100644 --- a/packager/media/base/widevine_key_source.cc +++ b/packager/media/base/widevine_key_source.cc @@ -139,17 +139,17 @@ class WidevineKeySource::RefCountedEncryptionKeyMap WidevineKeySource::WidevineKeySource( const std::string& server_url, scoped_ptr signer) - : http_fetcher_(new SimpleHttpFetcher(kHttpTimeoutInSeconds)), + : key_production_thread_( + "KeyProductionThread", + base::Bind(&WidevineKeySource::FetchKeysTask, + base::Unretained(this))), + http_fetcher_(new SimpleHttpFetcher(kHttpTimeoutInSeconds)), server_url_(server_url), signer_(signer.Pass()), crypto_period_count_(kDefaultCryptoPeriodCount), key_production_started_(false), start_key_production_(false, false), - first_crypto_period_index_(0), - key_production_thread_( - "KeyProductionThread", - base::Bind(&WidevineKeySource::FetchKeysTask, - base::Unretained(this))) { + first_crypto_period_index_(0) { DCHECK(signer_); } diff --git a/packager/media/base/widevine_key_source.h b/packager/media/base/widevine_key_source.h index b099aa9912..578e637eec 100644 --- a/packager/media/base/widevine_key_source.h +++ b/packager/media/base/widevine_key_source.h @@ -37,7 +37,7 @@ class WidevineKeySource : public KeySource { virtual Status FetchKeys(const std::vector& content_id, const std::string& policy) OVERRIDE; virtual Status FetchKeys(const std::vector& pssh_data) OVERRIDE; - Status FetchKeys(uint32_t asset_id); + virtual Status FetchKeys(uint32_t asset_id); virtual Status GetKey(TrackType track_type, EncryptionKey* key) OVERRIDE; virtual Status GetKey(const std::vector& key_id, @@ -51,6 +51,9 @@ class WidevineKeySource : public KeySource { /// @param http_fetcher points to the @b HttpFetcher object to be injected. void set_http_fetcher(scoped_ptr http_fetcher); + protected: + ClosureThread key_production_thread_; + private: typedef std::map EncryptionKeyMap; class RefCountedEncryptionKeyMap; @@ -108,7 +111,6 @@ class WidevineKeySource : public KeySource { bool key_production_started_; base::WaitableEvent start_key_production_; uint32_t first_crypto_period_index_; - ClosureThread key_production_thread_; scoped_ptr key_pool_; EncryptionKeyMap encryption_key_map_; // For non key rotation request. Status common_encryption_request_status_; diff --git a/packager/media/formats/wvm/wvm.gyp b/packager/media/formats/wvm/wvm.gyp index 63473a0dc0..df0d085672 100644 --- a/packager/media/formats/wvm/wvm.gyp +++ b/packager/media/formats/wvm/wvm.gyp @@ -23,19 +23,18 @@ '../mpeg/mpeg.gyp:mpeg', ], }, - # TODO(ramjic): Re-enable when KeySource::FetchKeys() is mocked. - #{ - #'target_name': 'wvm_unittest', - #'type': '<(gtest_target_type)', - #'sources': [ - # 'wvm_media_parser_unittest.cc', - #], - #'dependencies': [ - # '../../../testing/gtest.gyp:gtest', - # '../../../testing/gmock.gyp:gmock', - # '../../test/media_test.gyp:media_test_support', - # 'wvm', - #] - #}, + { + 'target_name': 'wvm_unittest', + 'type': '<(gtest_target_type)', + 'sources': [ + 'wvm_media_parser_unittest.cc', + ], + 'dependencies': [ + '../../../testing/gtest.gyp:gtest', + '../../../testing/gmock.gyp:gmock', + '../../test/media_test.gyp:media_test_support', + 'wvm', + ] + }, ], } diff --git a/packager/media/formats/wvm/wvm_media_parser_unittest.cc b/packager/media/formats/wvm/wvm_media_parser_unittest.cc index a7f466b723..068f0446ed 100644 --- a/packager/media/formats/wvm/wvm_media_parser_unittest.cc +++ b/packager/media/formats/wvm/wvm_media_parser_unittest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include #include #include @@ -21,15 +22,63 @@ #include "packager/media/test/test_data_util.h" namespace { +const int64_t kNoTimestamp = std::numeric_limits::min(); const char kWvmFile[] = "hb2_4stream_encrypted.wvm"; // Constants associated with kWvmFile follows. const uint32_t kExpectedStreams = 4; const int kExpectedVideoFrameCount = 6665; const int kExpectedAudioFrameCount = 11964; -} +const char kServerUrl[] = "fake_server_url"; +const char kSigner[] = "fake_signer"; +const uint8 kExpectedAssetKey[16] = {'\006', static_cast('\201'), '\177', + 'H', 'k', static_cast('\362'), '\177', '>', static_cast('\307'), + '9', static_cast('\250'), '?', '\022', '\n', + static_cast('\322'), static_cast('\374')}; +} // namespace + +using ::testing::_; +using ::testing::DoAll; +using ::testing::InSequence; +using ::testing::Return; +using ::testing::SetArgPointee; namespace edash_packager { namespace media { + +class FakeRequestSigner : public RequestSigner { + public: + FakeRequestSigner() : RequestSigner(kSigner) {} + virtual ~FakeRequestSigner() {} + + virtual bool GenerateSignature(const std::string& message, + std::string* signature) OVERRIDE { + return true; + } + + private: + DISALLOW_COPY_AND_ASSIGN(FakeRequestSigner); +}; + +scoped_ptr kFakeRequestSigner(new FakeRequestSigner()); + +class MockKeySource : public WidevineKeySource { + public: + MockKeySource() : WidevineKeySource( + kServerUrl, kFakeRequestSigner.PassAs()) { + // KeyProduction thread started in test because FetchKeys() + // is mocked. ~ClosureThread expects to terminate this thread. + key_production_thread_.Start(); + } + virtual ~MockKeySource() {} + + MOCK_METHOD1(FetchKeys, Status(uint32_t asset_id)); + MOCK_METHOD2(GetKey, Status(TrackType track_type, + EncryptionKey* key)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockKeySource); +}; + namespace wvm { class WvmMediaParserTest : public testing::Test { @@ -40,29 +89,21 @@ class WvmMediaParserTest : public testing::Test { video_max_dts_(kNoTimestamp), current_track_id_(-1) { parser_.reset(new WvmMediaParser()); - const std::string server_url = - "https://license.uat.widevine.com/cenc/getcontentkey/widevine_test"; - const std::string aes_signing_key = - "1ae8ccd0e7985cc0b6203a55855a1034afc252980e970ca90e5202689f947ab9"; - const std::string aes_signing_iv = "d58ce954203b7c9a9a9d467f59839249"; - const std::string signer = "widevine_test"; - request_signer_.reset(AesRequestSigner::CreateSigner( - signer, aes_signing_key, aes_signing_iv)); - key_source_.reset(new WidevineKeySource(server_url, - request_signer_.Pass())); + key_source_.reset(new MockKeySource()); + encryption_key_.key.assign(kExpectedAssetKey, kExpectedAssetKey + 16); } protected: typedef std::map > StreamMap; scoped_ptr parser_; - scoped_ptr request_signer_; - scoped_ptr key_source_; + scoped_ptr key_source_; StreamMap stream_map_; int audio_frame_count_; int video_frame_count_; int64_t video_max_dts_; uint32_t current_track_id_; + EncryptionKey encryption_key_; void OnInit(const std::vector >& stream_infos) { DVLOG(1) << "OnInit: " << stream_infos.size() << " streams."; @@ -127,21 +168,12 @@ class WvmMediaParserTest : public testing::Test { }; TEST_F(WvmMediaParserTest, ParseWvm) { - Parse(kWvmFile); -} - -TEST_F(WvmMediaParserTest, StreamCount) { + EXPECT_CALL(*key_source_, FetchKeys(_)).WillOnce(Return(Status::OK)); + EXPECT_CALL(*key_source_, GetKey(_,_)) + .WillOnce(DoAll(SetArgPointee<1>(encryption_key_), Return(Status::OK))); Parse(kWvmFile); EXPECT_EQ(kExpectedStreams, stream_map_.size()); -} - -TEST_F(WvmMediaParserTest, VideoFrameCount) { - Parse(kWvmFile); EXPECT_EQ(kExpectedVideoFrameCount, video_frame_count_); -} - -TEST_F(WvmMediaParserTest, AudioFrameCount) { - Parse(kWvmFile); EXPECT_EQ(kExpectedAudioFrameCount, audio_frame_count_); }