From 1927109818ad0552c274625c1a501fea9ffb86c8 Mon Sep 17 00:00:00 2001 From: KongQun Yang Date: Wed, 18 Jun 2014 12:23:34 -0700 Subject: [PATCH] Adjust WidevineEncryptionKeySource to handle timeout Change-Id: Iac4a86acae2e522c6cfc84ce02ae7ec1dd30c47e --- media/base/widevine_encryption_key_source.cc | 39 +++++++------- ...widevine_encryption_key_source_unittest.cc | 51 ++++++++++++------- 2 files changed, 53 insertions(+), 37 deletions(-) diff --git a/media/base/widevine_encryption_key_source.cc b/media/base/widevine_encryption_key_source.cc index 18aa3b14db..0b318b2f76 100644 --- a/media/base/widevine_encryption_key_source.cc +++ b/media/base/widevine_encryption_key_source.cc @@ -40,6 +40,7 @@ const int kFirstRetryDelayMilliseconds = 1000; // key rotation enabled request. const int kDefaultCryptoPeriodCount = 10; const int kGetKeyTimeoutInSeconds = 5 * 60; // 5 minutes. +const int kHttpTimeoutInSeconds = 60; // 1 minute. bool Base64StringToBytes(const std::string& base64_string, std::vector* bytes) { @@ -129,7 +130,7 @@ WidevineEncryptionKeySource::WidevineEncryptionKeySource( const std::string& policy, scoped_ptr signer, int first_crypto_period_index) - : http_fetcher_(new SimpleHttpFetcher()), + : http_fetcher_(new SimpleHttpFetcher(kHttpTimeoutInSeconds)), server_url_(server_url), content_id_(content_id), policy_(policy), @@ -243,24 +244,26 @@ Status WidevineEncryptionKeySource::FetchKeys( // server limitation. for (int i = 0; i < kNumTransientErrorRetries; ++i) { status = http_fetcher_->Post(server_url_, message, &raw_response); - if (!status.ok()) + if (status.ok()) { + VLOG(1) << "Retry [" << i << "] Response:" << raw_response; + + std::string response; + if (!DecodeResponse(raw_response, &response)) { + return Status(error::SERVER_ERROR, + "Failed to decode response '" + raw_response + "'."); + } + + bool transient_error = false; + if (ExtractEncryptionKey(response, &transient_error)) + return Status::OK; + + if (!transient_error) { + return Status( + error::SERVER_ERROR, + "Failed to extract encryption key from '" + response + "'."); + } + } else if (status.error_code() != error::TIME_OUT) { return status; - VLOG(1) << "Retry [" << i << "] Response:" << raw_response; - - std::string response; - if (!DecodeResponse(raw_response, &response)) { - return Status(error::SERVER_ERROR, - "Failed to decode response '" + raw_response + "'."); - } - - bool transient_error = false; - if (ExtractEncryptionKey(response, &transient_error)) - return Status::OK; - - if (!transient_error) { - return Status( - error::SERVER_ERROR, - "Failed to extract encryption key from '" + response + "'."); } // Exponential backoff. diff --git a/media/base/widevine_encryption_key_source_unittest.cc b/media/base/widevine_encryption_key_source_unittest.cc index d9870b0940..1567bad3e9 100644 --- a/media/base/widevine_encryption_key_source_unittest.cc +++ b/media/base/widevine_encryption_key_source_unittest.cc @@ -143,6 +143,20 @@ class WidevineEncryptionKeySourceTest : public ::testing::Test { mock_http_fetcher_.PassAs()); } + void VerifyKeys() { + EncryptionKey encryption_key; + const std::string kTrackTypes[] = {"SD", "HD", "AUDIO"}; + for (size_t i = 0; i < arraysize(kTrackTypes); ++i) { + ASSERT_OK(widevine_encryption_key_source_->GetKey( + EncryptionKeySource::GetTrackTypeFromString(kTrackTypes[i]), + &encryption_key)); + EXPECT_EQ(GetMockKeyId(kTrackTypes[i]), ToString(encryption_key.key_id)); + EXPECT_EQ(GetMockKey(kTrackTypes[i]), ToString(encryption_key.key)); + EXPECT_EQ(GetMockPsshData(kTrackTypes[i]), + GetPsshDataFromPsshBox(ToString(encryption_key.pssh))); + } + } + scoped_ptr mock_request_signer_; scoped_ptr mock_http_fetcher_; scoped_ptr widevine_encryption_key_source_; @@ -217,18 +231,24 @@ TEST_F(WidevineEncryptionKeySourceTest, LicenseStatusOK) { CreateWidevineEncryptionKeySource(kDisableKeyRotation); ASSERT_OK(widevine_encryption_key_source_->Initialize()); + VerifyKeys(); +} - EncryptionKey encryption_key; - const std::string kTrackTypes[] = {"SD", "HD", "AUDIO"}; - for (size_t i = 0; i < 3; ++i) { - ASSERT_OK(widevine_encryption_key_source_->GetKey( - EncryptionKeySource::GetTrackTypeFromString(kTrackTypes[i]), - &encryption_key)); - EXPECT_EQ(GetMockKeyId(kTrackTypes[i]), ToString(encryption_key.key_id)); - EXPECT_EQ(GetMockKey(kTrackTypes[i]), ToString(encryption_key.key)); - EXPECT_EQ(GetMockPsshData(kTrackTypes[i]), - GetPsshDataFromPsshBox(ToString(encryption_key.pssh))); - } +TEST_F(WidevineEncryptionKeySourceTest, RetryOnHttpTimeout) { + EXPECT_CALL(*mock_request_signer_, GenerateSignature(_, _)) + .WillOnce(Return(true)); + + std::string mock_response = base::StringPrintf( + kHttpResponseFormat, Base64Encode(GenerateMockLicenseResponse()).c_str()); + + // Retry is expected on HTTP timeout. + EXPECT_CALL(*mock_http_fetcher_, Post(_, _, _)) + .WillOnce(Return(Status(error::TIME_OUT, ""))) + .WillOnce(DoAll(SetArgPointee<2>(mock_response), Return(Status::OK))); + + CreateWidevineEncryptionKeySource(kDisableKeyRotation); + ASSERT_OK(widevine_encryption_key_source_->Initialize()); + VerifyKeys(); } TEST_F(WidevineEncryptionKeySourceTest, RetryOnTransientError) { @@ -251,14 +271,7 @@ TEST_F(WidevineEncryptionKeySourceTest, RetryOnTransientError) { CreateWidevineEncryptionKeySource(kDisableKeyRotation); ASSERT_OK(widevine_encryption_key_source_->Initialize()); - - EncryptionKey encryption_key; - ASSERT_OK(widevine_encryption_key_source_->GetKey( - EncryptionKeySource::TRACK_TYPE_SD, &encryption_key)); - EXPECT_EQ(GetMockKeyId("SD"), ToString(encryption_key.key_id)); - EXPECT_EQ(GetMockKey("SD"), ToString(encryption_key.key)); - EXPECT_EQ(GetMockPsshData("SD"), - GetPsshDataFromPsshBox(ToString(encryption_key.pssh))); + VerifyKeys(); } TEST_F(WidevineEncryptionKeySourceTest, NoRetryOnUnknownError) {