Index: content/renderer/media/crypto/proxy_media_keys.cc |
diff --git a/content/renderer/media/crypto/proxy_media_keys.cc b/content/renderer/media/crypto/proxy_media_keys.cc |
index 94fe5aa8e624ea186f3cb4299d2f953c83f54bfe..fca2757f85bf0973a138c2e5bb48869eb6085c25 100644 |
--- a/content/renderer/media/crypto/proxy_media_keys.cc |
+++ b/content/renderer/media/crypto/proxy_media_keys.cc |
@@ -10,6 +10,7 @@ |
#include "base/logging.h" |
#include "base/stl_util.h" |
#include "content/renderer/media/crypto/renderer_cdm_manager.h" |
+#include "media/base/cdm_key_information.h" |
#include "media/base/cdm_promise.h" |
#include "media/base/key_systems.h" |
@@ -25,14 +26,9 @@ scoped_ptr<ProxyMediaKeys> ProxyMediaKeys::Create( |
const media::SessionKeysChangeCB& session_keys_change_cb, |
const media::SessionExpirationUpdateCB& session_expiration_update_cb) { |
DCHECK(manager); |
- |
- // TODO(jrummell): Add support for SessionKeysChangeCB and |
- // SessionExpirationUpdateCB. |
- scoped_ptr<ProxyMediaKeys> proxy_media_keys( |
- new ProxyMediaKeys(manager, |
- session_message_cb, |
- session_closed_cb, |
- session_error_cb)); |
+ scoped_ptr<ProxyMediaKeys> proxy_media_keys(new ProxyMediaKeys( |
+ manager, session_message_cb, session_closed_cb, session_error_cb, |
+ session_keys_change_cb, session_expiration_update_cb)); |
proxy_media_keys->InitializeCdm(key_system, security_origin); |
return proxy_media_keys.Pass(); |
} |
@@ -40,22 +36,18 @@ scoped_ptr<ProxyMediaKeys> ProxyMediaKeys::Create( |
ProxyMediaKeys::~ProxyMediaKeys() { |
manager_->DestroyCdm(cdm_id_); |
manager_->UnregisterMediaKeys(cdm_id_); |
- |
- // Reject any outstanding promises. |
- for (PromiseMap::iterator it = session_id_to_promise_map_.begin(); |
- it != session_id_to_promise_map_.end(); |
- ++it) { |
- it->second->reject( |
- media::MediaKeys::NOT_SUPPORTED_ERROR, 0, "The operation was aborted."); |
- } |
- session_id_to_promise_map_.clear(); |
+ cdm_promise_adapter_.Clear(); |
} |
void ProxyMediaKeys::SetServerCertificate( |
const uint8* certificate_data, |
int certificate_data_length, |
scoped_ptr<media::SimpleCdmPromise> promise) { |
- promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented."); |
+ uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
+ manager_->SetServerCertificate( |
+ cdm_id_, promise_id, |
+ std::vector<uint8>(certificate_data, |
+ certificate_data + certificate_data_length)); |
} |
void ProxyMediaKeys::CreateSessionAndGenerateRequest( |
@@ -64,13 +56,19 @@ void ProxyMediaKeys::CreateSessionAndGenerateRequest( |
const uint8* init_data, |
int init_data_length, |
scoped_ptr<media::NewSessionCdmPromise> promise) { |
+ if (session_type != media::MediaKeys::TEMPORARY_SESSION) { |
+ promise->reject(NOT_SUPPORTED_ERROR, 0, |
+ "Only the temporary session type is supported."); |
+ return; |
+ } |
+ |
// TODO(xhwang): Move these checks up to blink and DCHECK here. |
// See http://crbug.com/342510 |
- CdmHostMsg_CreateSession_ContentType create_session_content_type; |
+ CdmHostMsg_CreateSession_InitDataType create_session_init_data_type; |
if (init_data_type == "cenc") { |
- create_session_content_type = CREATE_SESSION_TYPE_MP4; |
+ create_session_init_data_type = CREATE_SESSION_TYPE_MP4; |
} else if (init_data_type == "webm") { |
- create_session_content_type = CREATE_SESSION_TYPE_WEBM; |
+ create_session_init_data_type = CREATE_SESSION_TYPE_WEBM; |
} else { |
DLOG(ERROR) << "Unsupported EME CreateSession content type of " |
<< init_data_type; |
@@ -81,59 +79,45 @@ void ProxyMediaKeys::CreateSessionAndGenerateRequest( |
return; |
} |
- uint32 session_id = CreateSessionId(); |
- SavePromise(session_id, promise.Pass()); |
- manager_->CreateSession( |
- cdm_id_, |
- session_id, |
- create_session_content_type, |
+ uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
+ manager_->CreateSessionAndGenerateRequest( |
+ cdm_id_, promise_id, create_session_init_data_type, |
std::vector<uint8>(init_data, init_data + init_data_length)); |
} |
void ProxyMediaKeys::LoadSession( |
SessionType session_type, |
- const std::string& web_session_id, |
+ const std::string& session_id, |
scoped_ptr<media::NewSessionCdmPromise> promise) { |
// TODO(xhwang): Check key system and platform support for LoadSession in |
- // blink and add NOTREACHED() here. |
+ // blink and add NOTREACHED() here. See http://crbug.com/384152 |
DLOG(ERROR) << "ProxyMediaKeys doesn't support session loading."; |
promise->reject(NOT_SUPPORTED_ERROR, 0, "LoadSession() is not supported."); |
} |
void ProxyMediaKeys::UpdateSession( |
- const std::string& web_session_id, |
+ const std::string& session_id, |
const uint8* response, |
int response_length, |
scoped_ptr<media::SimpleCdmPromise> promise) { |
- uint32 session_id = LookupSessionId(web_session_id); |
- if (!session_id) { |
- promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist."); |
- return; |
- } |
- |
- SavePromise(session_id, promise.Pass()); |
+ uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
manager_->UpdateSession( |
- cdm_id_, |
- session_id, |
+ cdm_id_, promise_id, session_id, |
std::vector<uint8>(response, response + response_length)); |
} |
-void ProxyMediaKeys::CloseSession(const std::string& web_session_id, |
+void ProxyMediaKeys::CloseSession(const std::string& session_id, |
scoped_ptr<media::SimpleCdmPromise> promise) { |
- uint32 session_id = LookupSessionId(web_session_id); |
- if (!session_id) { |
- promise->reject(INVALID_ACCESS_ERROR, 0, "Session does not exist."); |
- return; |
- } |
- |
- SavePromise(session_id, promise.Pass()); |
- manager_->ReleaseSession(cdm_id_, session_id); |
+ uint32_t promise_id = cdm_promise_adapter_.SavePromise(promise.Pass()); |
+ manager_->CloseSession(cdm_id_, promise_id, session_id); |
} |
void ProxyMediaKeys::RemoveSession( |
- const std::string& web_session_id, |
+ const std::string& session_id, |
scoped_ptr<media::SimpleCdmPromise> promise) { |
- promise->reject(NOT_SUPPORTED_ERROR, 0, "Not yet implemented."); |
+ // TODO(xhwang): Check key system and platform support for LoadSession in |
+ // blink and add NOTREACHED() here. See http://crbug.com/384152 |
+ promise->reject(NOT_SUPPORTED_ERROR, 0, "RemoveSession() not supported."); |
} |
media::CdmContext* ProxyMediaKeys::GetCdmContext() { |
@@ -148,93 +132,70 @@ int ProxyMediaKeys::GetCdmId() const { |
return cdm_id_; |
} |
-void ProxyMediaKeys::OnSessionCreated(uint32 session_id, |
- const std::string& web_session_id) { |
- AssignWebSessionId(session_id, web_session_id); |
- scoped_ptr<media::CdmPromise> promise = TakePromise(session_id); |
- if (promise) { |
- media::NewSessionCdmPromise* session_promise( |
- static_cast<media::NewSessionCdmPromise*>(promise.get())); |
- session_promise->resolve(web_session_id); |
- } |
+void ProxyMediaKeys::OnSessionMessage( |
+ const std::string& session_id, |
+ media::MediaKeys::MessageType message_type, |
+ const std::vector<uint8>& message, |
+ const GURL& legacy_destination_url) { |
+ session_message_cb_.Run(session_id, message_type, message, |
+ legacy_destination_url); |
} |
-void ProxyMediaKeys::OnSessionMessage(uint32 session_id, |
- const std::vector<uint8>& message, |
- const GURL& legacy_destination_url) { |
- // TODO(jrummell): Once |message_type| is passed, use it rather than |
- // guessing from the URL. |
- media::MediaKeys::MessageType message_type = |
- legacy_destination_url.is_empty() ? media::MediaKeys::LICENSE_REQUEST |
- : media::MediaKeys::LICENSE_RENEWAL; |
- session_message_cb_.Run(LookupWebSessionId(session_id), message_type, message, |
- legacy_destination_url); |
+void ProxyMediaKeys::OnSessionClosed(const std::string& session_id) { |
+ session_closed_cb_.Run(session_id); |
} |
-void ProxyMediaKeys::OnSessionReady(uint32 session_id) { |
- scoped_ptr<media::CdmPromise> promise = TakePromise(session_id); |
- if (promise) { |
- media::SimpleCdmPromise* simple_promise( |
- static_cast<media::SimpleCdmPromise*>(promise.get())); |
- simple_promise->resolve(); |
- } |
+void ProxyMediaKeys::OnLegacySessionError(const std::string& session_id, |
+ media::MediaKeys::Exception exception, |
+ uint32 system_code, |
+ const std::string& error_message) { |
+ session_error_cb_.Run(session_id, exception, system_code, error_message); |
} |
-void ProxyMediaKeys::OnSessionClosed(uint32 session_id) { |
- const std::string web_session_id = LookupWebSessionId(session_id); |
- DropWebSessionId(web_session_id); |
- scoped_ptr<media::CdmPromise> promise = TakePromise(session_id); |
- if (promise) { |
- media::SimpleCdmPromise* simple_promise( |
- static_cast<media::SimpleCdmPromise*>(promise.get())); |
- simple_promise->resolve(); |
- } else { |
- // It is possible for the CDM to close a session independent of a |
- // Release() request. |
- session_closed_cb_.Run(web_session_id); |
- } |
+void ProxyMediaKeys::OnSessionKeysChange(const std::string& session_id, |
+ bool has_additional_usable_key, |
+ media::CdmKeysInfo keys_info) { |
+ session_keys_change_cb_.Run(session_id, has_additional_usable_key, |
+ keys_info.Pass()); |
} |
-void ProxyMediaKeys::OnSessionError(uint32 session_id, |
- media::MediaKeys::KeyError error_code, |
- uint32 system_code) { |
- const std::string web_session_id = LookupWebSessionId(session_id); |
- media::MediaKeys::Exception exception_code; |
- switch (error_code) { |
- case media::MediaKeys::kClientError: |
- exception_code = media::MediaKeys::CLIENT_ERROR; |
- break; |
- case media::MediaKeys::kOutputError: |
- exception_code = media::MediaKeys::OUTPUT_ERROR; |
- break; |
- case media::MediaKeys::kUnknownError: |
- default: |
- exception_code = media::MediaKeys::UNKNOWN_ERROR; |
- break; |
- } |
+void ProxyMediaKeys::OnSessionExpirationUpdate( |
+ const std::string& session_id, |
+ const base::Time& new_expiry_time) { |
+ session_expiration_update_cb_.Run(session_id, new_expiry_time); |
+} |
- scoped_ptr<media::CdmPromise> promise = TakePromise(session_id); |
- if (promise) { |
- promise->reject(exception_code, system_code, std::string()); |
- return; |
- } |
+void ProxyMediaKeys::OnPromiseResolved(uint32_t promise_id) { |
+ cdm_promise_adapter_.ResolvePromise(promise_id); |
+} |
+ |
+void ProxyMediaKeys::OnPromiseResolvedWithSession( |
+ uint32_t promise_id, |
+ const std::string& session_id) { |
+ cdm_promise_adapter_.ResolvePromise(promise_id, session_id); |
+} |
- // Errors generally happen in response to a request, but it is possible |
- // for something bad to happen in the CDM and it needs to tell the client. |
- session_error_cb_.Run( |
- web_session_id, exception_code, system_code, std::string()); |
+void ProxyMediaKeys::OnPromiseRejected(uint32_t promise_id, |
+ media::MediaKeys::Exception exception, |
+ uint32_t system_code, |
+ const std::string& error_message) { |
+ cdm_promise_adapter_.RejectPromise(promise_id, exception, system_code, |
+ error_message); |
} |
ProxyMediaKeys::ProxyMediaKeys( |
RendererCdmManager* manager, |
const media::SessionMessageCB& session_message_cb, |
const media::SessionClosedCB& session_closed_cb, |
- const media::SessionErrorCB& session_error_cb) |
+ const media::SessionErrorCB& session_error_cb, |
+ const media::SessionKeysChangeCB& session_keys_change_cb, |
+ const media::SessionExpirationUpdateCB& session_expiration_update_cb) |
: manager_(manager), |
session_message_cb_(session_message_cb), |
session_closed_cb_(session_closed_cb), |
session_error_cb_(session_error_cb), |
- next_session_id_(1) { |
+ session_keys_change_cb_(session_keys_change_cb), |
+ session_expiration_update_cb_(session_expiration_update_cb) { |
cdm_id_ = manager->RegisterMediaKeys(this); |
} |
@@ -243,54 +204,4 @@ void ProxyMediaKeys::InitializeCdm(const std::string& key_system, |
manager_->InitializeCdm(cdm_id_, this, key_system, security_origin); |
} |
-uint32_t ProxyMediaKeys::CreateSessionId() { |
- return next_session_id_++; |
-} |
- |
-void ProxyMediaKeys::AssignWebSessionId(uint32_t session_id, |
- const std::string& web_session_id) { |
- DCHECK(!ContainsKey(web_session_to_session_id_map_, web_session_id)); |
- DCHECK(session_id); |
- web_session_to_session_id_map_.insert( |
- std::make_pair(web_session_id, session_id)); |
-} |
- |
-uint32_t ProxyMediaKeys::LookupSessionId( |
- const std::string& web_session_id) const { |
- SessionIdMap::const_iterator it = |
- web_session_to_session_id_map_.find(web_session_id); |
- return (it != web_session_to_session_id_map_.end()) ? it->second : 0; |
-} |
- |
-std::string ProxyMediaKeys::LookupWebSessionId(uint32_t session_id) const { |
- for (SessionIdMap::const_iterator it = web_session_to_session_id_map_.begin(); |
- it != web_session_to_session_id_map_.end(); |
- ++it) { |
- if (it->second == session_id) |
- return it->first; |
- } |
- // Possible to get an error creating a session, so no |web_session_id| |
- // available. |
- return std::string(); |
-} |
- |
-void ProxyMediaKeys::DropWebSessionId(const std::string& web_session_id) { |
- web_session_to_session_id_map_.erase(web_session_id); |
-} |
- |
-void ProxyMediaKeys::SavePromise(uint32_t session_id, |
- scoped_ptr<media::CdmPromise> promise) { |
- // Should only be one promise outstanding for any |session_id|. |
- DCHECK(!ContainsKey(session_id_to_promise_map_, session_id)); |
- session_id_to_promise_map_.add(session_id, promise.Pass()); |
-} |
- |
-scoped_ptr<media::CdmPromise> ProxyMediaKeys::TakePromise(uint32_t session_id) { |
- PromiseMap::iterator it = session_id_to_promise_map_.find(session_id); |
- // May not be a promise associated with this session for asynchronous events. |
- if (it == session_id_to_promise_map_.end()) |
- return scoped_ptr<media::CdmPromise>(); |
- return session_id_to_promise_map_.take_and_erase(it); |
-} |
- |
} // namespace content |