Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1380)

Unified Diff: media/cdm/proxy_decryptor.cc

Issue 1070853004: media: CdmFactory creates CDM (MediaKeys) asynchronously. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: use ScopedVector Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/cdm/proxy_decryptor.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/cdm/proxy_decryptor.cc
diff --git a/media/cdm/proxy_decryptor.cc b/media/cdm/proxy_decryptor.cc
index 944b61405c415927b8bda4e8d1e30ebc0e5fb844..9260e1455b654fe434eb567f20c7630e21a9ef35 100644
--- a/media/cdm/proxy_decryptor.cc
+++ b/media/cdm/proxy_decryptor.cc
@@ -25,11 +25,22 @@ namespace media {
// EME API.
const int kSessionClosedSystemCode = 29127;
+ProxyDecryptor::PendingGenerateKeyRequestData::PendingGenerateKeyRequestData(
+ EmeInitDataType init_data_type,
+ const std::vector<uint8>& init_data)
+ : init_data_type(init_data_type), init_data(init_data) {
+}
+
+ProxyDecryptor::PendingGenerateKeyRequestData::
+ ~PendingGenerateKeyRequestData() {
+}
+
ProxyDecryptor::ProxyDecryptor(MediaPermission* media_permission,
const KeyAddedCB& key_added_cb,
const KeyErrorCB& key_error_cb,
const KeyMessageCB& key_message_cb)
- : media_permission_(media_permission),
+ : is_creating_cdm_(false),
+ media_permission_(media_permission),
key_added_cb_(key_added_cb),
key_error_cb_(key_error_cb),
key_message_cb_(key_message_cb),
@@ -46,33 +57,77 @@ ProxyDecryptor::~ProxyDecryptor() {
media_keys_.reset();
}
-CdmContext* ProxyDecryptor::GetCdmContext() {
- return media_keys_ ? media_keys_->GetCdmContext() : nullptr;
+void ProxyDecryptor::CreateCdm(CdmFactory* cdm_factory,
+ const std::string& key_system,
+ const GURL& security_origin,
+ const CdmContextReadyCB& cdm_context_ready_cb) {
+ DVLOG(1) << __FUNCTION__ << ": key_system = " << key_system;
+ DCHECK(!is_creating_cdm_);
+ DCHECK(!media_keys_);
+
+ // TODO(sandersd): Trigger permissions check here and use it to determine
+ // distinctive identifier support, instead of always requiring the
+ // permission. http://crbug.com/455271
+ bool allow_distinctive_identifier = true;
+ bool allow_persistent_state = true;
+
+ is_creating_cdm_ = true;
+
+ base::WeakPtr<ProxyDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr();
+ cdm_factory->Create(
+ key_system, allow_distinctive_identifier, allow_persistent_state,
+ security_origin, base::Bind(&ProxyDecryptor::OnSessionMessage, weak_this),
+ base::Bind(&ProxyDecryptor::OnSessionClosed, weak_this),
+ base::Bind(&ProxyDecryptor::OnLegacySessionError, weak_this),
+ base::Bind(&ProxyDecryptor::OnSessionKeysChange, weak_this),
+ base::Bind(&ProxyDecryptor::OnSessionExpirationUpdate, weak_this),
+ base::Bind(&ProxyDecryptor::OnCdmCreated, weak_this, key_system,
+ security_origin, cdm_context_ready_cb));
}
-bool ProxyDecryptor::InitializeCDM(CdmFactory* cdm_factory,
- const std::string& key_system,
- const GURL& security_origin) {
- DVLOG(1) << "InitializeCDM: key_system = " << key_system;
+void ProxyDecryptor::OnCdmCreated(const std::string& key_system,
+ const GURL& security_origin,
+ const CdmContextReadyCB& cdm_context_ready_cb,
+ scoped_ptr<MediaKeys> cdm) {
+ is_creating_cdm_ = false;
- DCHECK(!media_keys_);
- media_keys_ = CreateMediaKeys(cdm_factory, key_system, security_origin);
- if (!media_keys_)
- return false;
+ if (!cdm) {
+ cdm_context_ready_cb.Run(nullptr);
+ return;
+ }
key_system_ = key_system;
security_origin_ = security_origin;
+ is_clear_key_ = IsClearKey(key_system) || IsExternalClearKey(key_system);
+ media_keys_ = cdm.Pass();
+
+ cdm_context_ready_cb.Run(media_keys_->GetCdmContext());
+
+ for (const auto& request : pending_requests_)
+ GenerateKeyRequestInternal(request->init_data_type, request->init_data);
+
+ pending_requests_.clear();
+}
+
+void ProxyDecryptor::GenerateKeyRequest(EmeInitDataType init_data_type,
+ const uint8* init_data,
+ int init_data_length) {
+ std::vector<uint8> init_data_vector(init_data, init_data + init_data_length);
+
+ if (is_creating_cdm_) {
+ pending_requests_.push_back(
+ new PendingGenerateKeyRequestData(init_data_type, init_data_vector));
+ return;
+ }
- is_clear_key_ =
- IsClearKey(key_system) || IsExternalClearKey(key_system);
- return true;
+ GenerateKeyRequestInternal(init_data_type, init_data_vector);
}
// Returns true if |data| is prefixed with |header| and has data after the
// |header|.
-bool HasHeader(const uint8* data, int data_length, const std::string& header) {
- return static_cast<size_t>(data_length) > header.size() &&
- std::equal(data, data + header.size(), header.begin());
+bool HasHeader(const std::vector<uint8>& data, const std::string& header) {
+ return data.size() > header.size() &&
+ std::equal(header.begin(), header.end(), data.begin());
}
// Removes the first |length| items from |data|.
@@ -80,23 +135,30 @@ void StripHeader(std::vector<uint8>& data, size_t length) {
data.erase(data.begin(), data.begin() + length);
}
-bool ProxyDecryptor::GenerateKeyRequest(EmeInitDataType init_data_type,
- const uint8* init_data,
- int init_data_length) {
- DVLOG(1) << "GenerateKeyRequest()";
+void ProxyDecryptor::GenerateKeyRequestInternal(
+ EmeInitDataType init_data_type,
+ const std::vector<uint8>& init_data) {
+ DVLOG(1) << __FUNCTION__;
+ DCHECK(!is_creating_cdm_);
+
+ if (!media_keys_) {
+ OnLegacySessionError(std::string(), MediaKeys::NOT_SUPPORTED_ERROR, 0,
+ "CDM creation failed.");
+ return;
+ }
+
const char kPrefixedApiPersistentSessionHeader[] = "PERSISTENT|";
const char kPrefixedApiLoadSessionHeader[] = "LOAD_SESSION|";
SessionCreationType session_creation_type = TemporarySession;
- std::vector<uint8> init_data_vector(init_data, init_data + init_data_length);
- if (HasHeader(init_data, init_data_length, kPrefixedApiLoadSessionHeader)) {
+ std::vector<uint8> stripped_init_data = init_data;
+ if (HasHeader(init_data, kPrefixedApiLoadSessionHeader)) {
session_creation_type = LoadSession;
- StripHeader(init_data_vector, strlen(kPrefixedApiLoadSessionHeader));
- } else if (HasHeader(init_data,
- init_data_length,
- kPrefixedApiPersistentSessionHeader)) {
+ StripHeader(stripped_init_data, strlen(kPrefixedApiLoadSessionHeader));
+ } else if (HasHeader(init_data, kPrefixedApiPersistentSessionHeader)) {
session_creation_type = PersistentSession;
- StripHeader(init_data_vector, strlen(kPrefixedApiPersistentSessionHeader));
+ StripHeader(stripped_init_data,
+ strlen(kPrefixedApiPersistentSessionHeader));
}
scoped_ptr<NewSessionCdmPromise> promise(new CdmCallbackPromise<std::string>(
@@ -110,10 +172,10 @@ bool ProxyDecryptor::GenerateKeyRequest(EmeInitDataType init_data_type,
media_keys_->LoadSession(
MediaKeys::PERSISTENT_LICENSE_SESSION,
std::string(
- reinterpret_cast<const char*>(vector_as_array(&init_data_vector)),
- init_data_vector.size()),
+ reinterpret_cast<const char*>(vector_as_array(&stripped_init_data)),
+ stripped_init_data.size()),
promise.Pass());
- return true;
+ return;
}
MediaKeys::SessionType session_type =
@@ -125,9 +187,9 @@ bool ProxyDecryptor::GenerateKeyRequest(EmeInitDataType init_data_type,
// external clear key.
DCHECK(!key_system_.empty());
if (CanUseAesDecryptor(key_system_) || IsExternalClearKey(key_system_)) {
- OnPermissionStatus(session_type, init_data_type, init_data_vector,
+ OnPermissionStatus(session_type, init_data_type, stripped_init_data,
promise.Pass(), true /* granted */);
- return true;
+ return;
}
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
@@ -135,13 +197,11 @@ bool ProxyDecryptor::GenerateKeyRequest(EmeInitDataType init_data_type,
MediaPermission::PROTECTED_MEDIA_IDENTIFIER, security_origin_,
base::Bind(&ProxyDecryptor::OnPermissionStatus,
weak_ptr_factory_.GetWeakPtr(), session_type, init_data_type,
- init_data_vector, base::Passed(&promise)));
+ stripped_init_data, base::Passed(&promise)));
#else
- OnPermissionStatus(session_type, init_data_type, init_data_vector,
+ OnPermissionStatus(session_type, init_data_type, stripped_init_data,
promise.Pass(), true /* granted */);
#endif
-
- return true;
}
void ProxyDecryptor::OnPermissionStatus(
@@ -168,6 +228,12 @@ void ProxyDecryptor::AddKey(const uint8* key,
const std::string& session_id) {
DVLOG(1) << "AddKey()";
+ if (!media_keys_) {
+ OnLegacySessionError(std::string(), MediaKeys::INVALID_STATE_ERROR, 0,
+ "CDM is not available.");
+ return;
+ }
+
// In the prefixed API, the session parameter provided to addKey() is
// optional, so use the single existing session if it exists.
std::string new_session_id(session_id);
@@ -216,6 +282,12 @@ void ProxyDecryptor::AddKey(const uint8* key,
void ProxyDecryptor::CancelKeyRequest(const std::string& session_id) {
DVLOG(1) << "CancelKeyRequest()";
+ if (!media_keys_) {
+ OnLegacySessionError(std::string(), MediaKeys::INVALID_STATE_ERROR, 0,
+ "CDM is not available.");
+ return;
+ }
+
scoped_ptr<SimpleCdmPromise> promise(new CdmCallbackPromise<>(
base::Bind(&ProxyDecryptor::OnSessionClosed,
weak_ptr_factory_.GetWeakPtr(), session_id),
@@ -224,25 +296,6 @@ void ProxyDecryptor::CancelKeyRequest(const std::string& session_id) {
media_keys_->RemoveSession(session_id, promise.Pass());
}
-scoped_ptr<MediaKeys> ProxyDecryptor::CreateMediaKeys(
- CdmFactory* cdm_factory,
- const std::string& key_system,
- const GURL& security_origin) {
- // TODO(sandersd): Trigger permissions check here and use it to determine
- // distinctive identifier support, instead of always requiring the
- // permission. http://crbug.com/455271
- bool allow_distinctive_identifier = true;
- bool allow_persistent_state = true;
- base::WeakPtr<ProxyDecryptor> weak_this = weak_ptr_factory_.GetWeakPtr();
- return cdm_factory->Create(
- key_system, allow_distinctive_identifier, allow_persistent_state,
- security_origin, base::Bind(&ProxyDecryptor::OnSessionMessage, weak_this),
- base::Bind(&ProxyDecryptor::OnSessionClosed, weak_this),
- base::Bind(&ProxyDecryptor::OnLegacySessionError, weak_this),
- base::Bind(&ProxyDecryptor::OnSessionKeysChange, weak_this),
- base::Bind(&ProxyDecryptor::OnSessionExpirationUpdate, weak_this));
-}
-
void ProxyDecryptor::OnSessionMessage(const std::string& session_id,
MediaKeys::MessageType message_type,
const std::vector<uint8>& message,
« no previous file with comments | « media/cdm/proxy_decryptor.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698