summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-13 10:05:29 +0000
committerxhwang@chromium.org <xhwang@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-13 10:05:29 +0000
commitc441bf976879c42f29ad5da263c4e94cb0a432f7 (patch)
treebd6aa28a673ca99ea4ea39bcbf80e4b268d88ad5 /webkit
parent9f5babf4b2d4247b108318411c59e347f4a4738a (diff)
downloadchromium_src-c441bf976879c42f29ad5da263c4e94cb0a432f7.zip
chromium_src-c441bf976879c42f29ad5da263c4e94cb0a432f7.tar.gz
chromium_src-c441bf976879c42f29ad5da263c4e94cb0a432f7.tar.bz2
Implement heart beat in ClearKeyCdm.
Clear Key CDM sends out heart beat message periodically. To facilitate testing, the period of heart beat messages is short (200ms) at start-up. Then the period gets longer and longer until it reaches the maximum (1min) to avoid message spam. The heart beat key message starts with HEARTBEAT and the application should parse key messages to handle them properly. BUG=none TEST=none Review URL: https://chromiumcodereview.appspot.com/11368023 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@167350 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/media/crypto/ppapi/clear_key_cdm.cc52
-rw-r--r--webkit/media/crypto/ppapi/clear_key_cdm.h12
2 files changed, 54 insertions, 10 deletions
diff --git a/webkit/media/crypto/ppapi/clear_key_cdm.cc b/webkit/media/crypto/ppapi/clear_key_cdm.cc
index 7930646..3c3ce77 100644
--- a/webkit/media/crypto/ppapi/clear_key_cdm.cc
+++ b/webkit/media/crypto/ppapi/clear_key_cdm.cc
@@ -4,6 +4,9 @@
#include "webkit/media/crypto/ppapi/clear_key_cdm.h"
+#include <algorithm>
+#include <sstream>
+#include <string>
#include <vector>
#include "base/bind.h"
@@ -54,8 +57,15 @@ static bool InitializeFFmpegLibraries() {
static bool g_cdm_module_initialized = InitializeFFmpegLibraries();
#endif // CLEAR_KEY_CDM_USE_FFMPEG_DECODER
-static const char kClearKeyCdmVersion[] = "0.1.0.0";
+static const char kClearKeyCdmVersion[] = "0.1.0.1";
static const char kExternalClearKey[] = "org.chromium.externalclearkey";
+static const int64 kSecondsPerMinute = 60;
+static const int64 kMsPerSecond = 1000;
+static const int64 kInitialTimerDelayMs = 200;
+static const int64 kMaxTimerDelayMs = 1 * kSecondsPerMinute * kMsPerSecond;
+// Heart beat message header. If a key message starts with |kHeartBeatHeader|,
+// it's a heart beat message. Otherwise, it's a key request.
+static const char kHeartBeatHeader[] = "HEARTBEAT";
// Copies |input_buffer| into a media::DecoderBuffer. If the |input_buffer| is
// empty, an empty (end-of-stream) media::DecoderBuffer is returned.
@@ -188,9 +198,12 @@ void ClearKeyCdm::Client::NeedKey(const std::string& key_system,
NOTREACHED();
}
-ClearKeyCdm::ClearKeyCdm(cdm::Allocator* allocator, cdm::CdmHost*)
+ClearKeyCdm::ClearKeyCdm(cdm::Allocator* allocator, cdm::CdmHost* cdm_host)
: decryptor_(&client_),
- allocator_(allocator) {
+ allocator_(allocator),
+ cdm_host_(cdm_host),
+ timer_delay_ms_(kInitialTimerDelayMs),
+ timer_set_(false) {
DCHECK(allocator_);
#if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
channel_count_ = 0;
@@ -220,18 +233,18 @@ cdm::Status ClearKeyCdm::GenerateKeyRequest(const char* type, int type_size,
DCHECK(key_request);
key_request->set_session_id(client_.session_id().data(),
client_.session_id().size());
+ latest_session_id_ = client_.session_id();
// TODO(tomfinegan): Get rid of this copy.
key_request->set_message(allocator_->Allocate(client_.key_message_length()));
-
DCHECK(key_request->message());
DCHECK_EQ(key_request->message()->size(), client_.key_message_length());
- memcpy(reinterpret_cast<void*>(key_request->message()->data()),
- reinterpret_cast<const void*>(client_.key_message()),
- client_.key_message_length());
+ memcpy(key_request->message()->data(),
+ client_.key_message(), client_.key_message_length());
key_request->set_default_url(client_.default_url().data(),
client_.default_url().size());
+
return cdm::kSuccess;
}
@@ -250,6 +263,11 @@ cdm::Status ClearKeyCdm::AddKey(const char* session_id,
if (client_.status() != Client::kKeyAdded)
return cdm::kSessionError;
+ if (!timer_set_) {
+ cdm_host_->SetTimer(timer_delay_ms_);
+ timer_set_ = true;
+ }
+
return cdm::kSuccess;
}
@@ -263,8 +281,24 @@ cdm::Status ClearKeyCdm::CancelKeyRequest(const char* session_id,
}
void ClearKeyCdm::TimerExpired(cdm::KeyMessage* msg, bool* populated) {
- // TODO(xhwang): do something with this?
- NOTREACHED() << "Wouldn't it be nice if CdmHost::SetTimer() was used?";
+ std::ostringstream msg_stream;
+ msg_stream << kHeartBeatHeader << " from ClearKey CDM at time "
+ << cdm_host_->GetCurrentWallTimeInSeconds() << ".";
+ std::string msg_string = msg_stream.str();
+
+ msg->set_message(allocator_->Allocate(msg_string.length()));
+ memcpy(msg->message()->data(), msg_string.data(), msg_string.length());
+ msg->set_session_id(latest_session_id_.data(), latest_session_id_.length());
+ msg->set_default_url(NULL, 0);
+
+ *populated = true;
+
+ cdm_host_->SetTimer(timer_delay_ms_);
+
+ // Use a smaller timer delay at start-up to facilitate testing. Increase the
+ // timer delay up to a limit to avoid message spam.
+ if (timer_delay_ms_ < kMaxTimerDelayMs)
+ timer_delay_ms_ = std::min(2 * timer_delay_ms_, kMaxTimerDelayMs);
}
static void CopyDecryptResults(
diff --git a/webkit/media/crypto/ppapi/clear_key_cdm.h b/webkit/media/crypto/ppapi/clear_key_cdm.h
index e3056be..691e1df 100644
--- a/webkit/media/crypto/ppapi/clear_key_cdm.h
+++ b/webkit/media/crypto/ppapi/clear_key_cdm.h
@@ -42,7 +42,7 @@ class FFmpegCdmVideoDecoder;
// Clear key implementation of the cdm::ContentDecryptionModule interface.
class ClearKeyCdm : public cdm::ContentDecryptionModule {
public:
- explicit ClearKeyCdm(cdm::Allocator* allocator, cdm::CdmHost*);
+ ClearKeyCdm(cdm::Allocator* allocator, cdm::CdmHost* cdm_host);
virtual ~ClearKeyCdm();
// ContentDecryptionModule implementation.
@@ -159,6 +159,16 @@ class ClearKeyCdm : public cdm::ContentDecryptionModule {
base::Lock client_lock_;
cdm::Allocator* const allocator_;
+ cdm::CdmHost* cdm_host_;
+
+ std::string latest_session_id_;
+
+ // Timer delay in milliseconds for the next cdm_host_->SetTimer() call.
+ int64 timer_delay_ms_;
+
+ // Indicates whether a timer has been set to prevent multiple timers from
+ // running.
+ bool timer_set_;
#if defined(CLEAR_KEY_CDM_USE_FAKE_AUDIO_DECODER)
int channel_count_;