diff options
author | jrummell@chromium.org <jrummell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-14 01:34:24 +0000 |
---|---|---|
committer | jrummell@chromium.org <jrummell@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-11-14 01:34:24 +0000 |
commit | dc45e793ab9b1d06b54225416c6cdbe2bc2d45c6 (patch) | |
tree | 9f51f7b2ed902e8445ced95e157f86f0931e0eb0 | |
parent | f60a627cf5ce3c2234c1c66def822b58f686d7e2 (diff) | |
download | chromium_src-dc45e793ab9b1d06b54225416c6cdbe2bc2d45c6.zip chromium_src-dc45e793ab9b1d06b54225416c6cdbe2bc2d45c6.tar.gz chromium_src-dc45e793ab9b1d06b54225416c6cdbe2bc2d45c6.tar.bz2 |
Add support for multiple MediaKey sessions
The draft EME spec supports multiple instances of MediaKey objects, each having 0 or more sessions (MediaKeySession). This change adds a way to uniquely identify each instance of MediaKeySession so that they can all coexist, and adds an additional callback SetSessionId() which is called whenever a new session is actually created by a CDM.
Currently there is no way to correlate a created session with the original request. Change is to add a unique reference_id for each MediaKeySession, and use that to identify the session, rather that session_id (although session_id will still be available as a property via MediaKeySession). With session_id not being passed around, the new callback SetSessionId() is used when a session ID is assigned by the CDM.
There are also changes to the way WebMediaPlayer works with prefixed EME to support the new internal interfaces.
Not done is changes to the CDMs to support the reference_id. Currently it is handled by having the CDM wrapper keep track of a reference_id -> session_id mapping.
BUG=308704
TEST=encrypted-media layout tests and browser_tests for encrypted media pass
Review URL: https://codereview.chromium.org/26687006
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@235008 0039d316-1c4b-4281-b951-d872f2087c98
50 files changed, 1417 insertions, 883 deletions
diff --git a/content/browser/media/android/browser_media_player_manager.cc b/content/browser/media/android/browser_media_player_manager.cc index 682ef3f..8067218 100644 --- a/content/browser/media/android/browser_media_player_manager.cc +++ b/content/browser/media/android/browser_media_player_manager.cc @@ -341,26 +341,33 @@ void BrowserMediaPlayerManager::OnProtectedSurfaceRequested(int player_id) { } void BrowserMediaPlayerManager::OnKeyAdded(int media_keys_id, - const std::string& session_id) { - Send(new MediaKeysMsg_KeyAdded(routing_id(), media_keys_id, session_id)); + uint32 reference_id) { + Send(new MediaKeysMsg_KeyAdded(routing_id(), media_keys_id, reference_id)); } void BrowserMediaPlayerManager::OnKeyError( int media_keys_id, - const std::string& session_id, + uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code) { Send(new MediaKeysMsg_KeyError(routing_id(), media_keys_id, - session_id, error_code, system_code)); + reference_id, error_code, system_code)); } void BrowserMediaPlayerManager::OnKeyMessage( int media_keys_id, - const std::string& session_id, + uint32 reference_id, const std::vector<uint8>& message, const std::string& destination_url) { Send(new MediaKeysMsg_KeyMessage(routing_id(), media_keys_id, - session_id, message, destination_url)); + reference_id, message, destination_url)); +} + +void BrowserMediaPlayerManager::OnSetSessionId(int media_keys_id, + uint32 reference_id, + const std::string& session_id) { + Send(new MediaKeysMsg_SetSessionId( + routing_id(), media_keys_id, reference_id, session_id)); } #if defined(GOOGLE_TV) @@ -517,18 +524,19 @@ void BrowserMediaPlayerManager::OnInitializeCDM( void BrowserMediaPlayerManager::OnGenerateKeyRequest( int media_keys_id, + uint32 reference_id, const std::string& type, const std::vector<uint8>& init_data) { if (CommandLine::ForCurrentProcess() ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) { - GenerateKeyIfAllowed(media_keys_id, type, init_data, true); + GenerateKeyIfAllowed(media_keys_id, reference_id, type, init_data, true); return; } MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); if (!drm_bridge) { DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; - OnKeyError(media_keys_id, "", media::MediaKeys::kUnknownError, 0); + OnKeyError(media_keys_id, reference_id, media::MediaKeys::kUnknownError, 0); return; } @@ -542,23 +550,25 @@ void BrowserMediaPlayerManager::OnGenerateKeyRequest( base::Bind(&BrowserMediaPlayerManager::GenerateKeyIfAllowed, weak_ptr_factory_.GetWeakPtr(), media_keys_id, + reference_id, type, init_data)); } void BrowserMediaPlayerManager::OnAddKey(int media_keys_id, + uint32 reference_id, const std::vector<uint8>& key, - const std::vector<uint8>& init_data, - const std::string& session_id) { + const std::vector<uint8>& init_data) { MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); if (!drm_bridge) { DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; - OnKeyError(media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); + OnKeyError(media_keys_id, reference_id, media::MediaKeys::kUnknownError, 0); return; } - drm_bridge->AddKey(&key[0], key.size(), &init_data[0], init_data.size(), - session_id); + drm_bridge->AddKey(reference_id, + &key[0], key.size(), + &init_data[0], init_data.size()); // In EME v0.1b MediaKeys lives in the media element. So the |media_keys_id| // is the same as the |player_id|. // TODO(xhwang): Separate |media_keys_id| and |player_id|. @@ -569,15 +579,15 @@ void BrowserMediaPlayerManager::OnAddKey(int media_keys_id, void BrowserMediaPlayerManager::OnCancelKeyRequest( int media_keys_id, - const std::string& session_id) { + uint32 reference_id) { MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); if (!drm_bridge) { DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; - OnKeyError(media_keys_id, session_id, media::MediaKeys::kUnknownError, 0); + OnKeyError(media_keys_id, reference_id, media::MediaKeys::kUnknownError, 0); return; } - drm_bridge->CancelKeyRequest(session_id); + drm_bridge->CancelKeyRequest(reference_id); } void BrowserMediaPlayerManager::AddPlayer(MediaPlayerAndroid* player) { @@ -640,8 +650,9 @@ void BrowserMediaPlayerManager::AddDrmBridge(int media_keys_id, scoped_ptr<MediaDrmBridge> drm_bridge(MediaDrmBridge::Create( media_keys_id, uuid, frame_url, security_level, this)); if (!drm_bridge) { + // This failure will be discovered and reported by OnGenerateKeyRequest() + // as GetDrmBridge() will return null. DVLOG(1) << "failed to create drm bridge."; - OnKeyError(media_keys_id, "", media::MediaKeys::kUnknownError, 0); return; } @@ -673,6 +684,7 @@ void BrowserMediaPlayerManager::OnSetMediaKeys(int player_id, void BrowserMediaPlayerManager::GenerateKeyIfAllowed( int media_keys_id, + uint32 reference_id, const std::string& type, const std::vector<uint8>& init_data, bool allowed) { @@ -682,12 +694,13 @@ void BrowserMediaPlayerManager::GenerateKeyIfAllowed( MediaDrmBridge* drm_bridge = GetDrmBridge(media_keys_id); if (!drm_bridge) { DLOG(WARNING) << "No MediaDrmBridge for ID: " << media_keys_id << " found"; - OnKeyError(media_keys_id, "", media::MediaKeys::kUnknownError, 0); + OnKeyError(media_keys_id, reference_id, media::MediaKeys::kUnknownError, 0); return; } media_keys_ids_pending_approval_.erase(media_keys_id); media_keys_ids_approved_.insert(media_keys_id); - drm_bridge->GenerateKeyRequest(type, &init_data[0], init_data.size()); + drm_bridge->GenerateKeyRequest( + reference_id, type, &init_data[0], init_data.size()); // TODO(qinmin): currently |media_keys_id| and player ID are identical. // This might not be true in the future. diff --git a/content/browser/media/android/browser_media_player_manager.h b/content/browser/media/android/browser_media_player_manager.h index 93b7592..cabd360 100644 --- a/content/browser/media/android/browser_media_player_manager.h +++ b/content/browser/media/android/browser_media_player_manager.h @@ -91,15 +91,18 @@ class CONTENT_EXPORT BrowserMediaPlayerManager virtual void DestroyAllMediaPlayers() OVERRIDE; virtual void OnProtectedSurfaceRequested(int player_id) OVERRIDE; virtual void OnKeyAdded(int media_keys_id, - const std::string& session_id) OVERRIDE; + uint32 reference_id) OVERRIDE; virtual void OnKeyError(int media_keys_id, - const std::string& session_id, + uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code) OVERRIDE; virtual void OnKeyMessage(int media_keys_id, - const std::string& session_id, + uint32 reference_id, const std::vector<uint8>& message, const std::string& destination_url) OVERRIDE; + virtual void OnSetSessionId(int media_keys_id, + uint32 reference_id, + const std::string& session_id) OVERRIDE; #if defined(GOOGLE_TV) void AttachExternalVideoSurface(int player_id, jobject surface); @@ -133,13 +136,14 @@ class CONTENT_EXPORT BrowserMediaPlayerManager const std::vector<uint8>& uuid, const GURL& frame_url); void OnGenerateKeyRequest(int media_keys_id, + uint32 reference_id, const std::string& type, const std::vector<uint8>& init_data); void OnAddKey(int media_keys_id, + uint32 reference_id, const std::vector<uint8>& key, - const std::vector<uint8>& init_data, - const std::string& session_id); - void OnCancelKeyRequest(int media_keys_id, const std::string& session_id); + const std::vector<uint8>& init_data); + void OnCancelKeyRequest(int media_keys_id, uint32 reference_id); void OnSetMediaKeys(int player_id, int media_keys_id); #if defined(GOOGLE_TV) @@ -160,7 +164,7 @@ class CONTENT_EXPORT BrowserMediaPlayerManager int player_id, media::MediaPlayerAndroid* player); - // Add a new MediaDrmBridge for the given |uuid|, |media_keys_id|, and + // Adds a new MediaDrmBridge for the given |uuid|, |media_keys_id|, and // |frame_url|. void AddDrmBridge(int media_keys_id, const std::vector<uint8>& uuid, @@ -171,6 +175,7 @@ class CONTENT_EXPORT BrowserMediaPlayerManager private: void GenerateKeyIfAllowed(int media_keys_id, + uint32 reference_id, const std::string& type, const std::vector<uint8>& init_data, bool allowed); diff --git a/content/common/media/media_player_messages_android.h b/content/common/media/media_player_messages_android.h index 2c833eb..054fb22 100644 --- a/content/common/media/media_player_messages_android.h +++ b/content/common/media/media_player_messages_android.h @@ -287,33 +287,39 @@ IPC_MESSAGE_ROUTED3(MediaKeysHostMsg_InitializeCDM, std::vector<uint8> /* uuid */, GURL /* frame url */) -IPC_MESSAGE_ROUTED3(MediaKeysHostMsg_GenerateKeyRequest, +IPC_MESSAGE_ROUTED4(MediaKeysHostMsg_GenerateKeyRequest, int /* media_keys_id */, + uint32_t /* reference_id */, std::string /* type */, std::vector<uint8> /* init_data */) IPC_MESSAGE_ROUTED4(MediaKeysHostMsg_AddKey, int /* media_keys_id */, + uint32_t /* reference_id */, std::vector<uint8> /* key */, - std::vector<uint8> /* init_data */, - std::string /* session_id */) + std::vector<uint8> /* init_data */) IPC_MESSAGE_ROUTED2(MediaKeysHostMsg_CancelKeyRequest, int /* media_keys_id */, - std::string /* session_id */) + uint32_t /* reference_id */) IPC_MESSAGE_ROUTED2(MediaKeysMsg_KeyAdded, int /* media_keys_id */, - std::string /* session_id */) + uint32_t /* reference_id */) IPC_MESSAGE_ROUTED4(MediaKeysMsg_KeyError, int /* media_keys_id */, - std::string /* session_id */, + uint32_t /* reference_id */, media::MediaKeys::KeyError /* error_code */, int /* system_code */) IPC_MESSAGE_ROUTED4(MediaKeysMsg_KeyMessage, int /* media_keys_id */, - std::string /* session_id */, + uint32_t /* reference_id */, std::vector<uint8> /* message */, std::string /* destination_url */) + +IPC_MESSAGE_ROUTED3(MediaKeysMsg_SetSessionId, + int /* media_keys_id */, + uint32_t /* reference_id */, + std::string /* session_id */) diff --git a/content/renderer/media/android/proxy_media_keys.cc b/content/renderer/media/android/proxy_media_keys.cc index 2df2dbc6..8310a83 100644 --- a/content/renderer/media/android/proxy_media_keys.cc +++ b/content/renderer/media/android/proxy_media_keys.cc @@ -17,12 +17,14 @@ ProxyMediaKeys::ProxyMediaKeys(RendererMediaPlayerManager* manager, int media_keys_id, const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, - const media::KeyMessageCB& key_message_cb) + const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb) : manager_(manager), media_keys_id_(media_keys_id), key_added_cb_(key_added_cb), key_error_cb_(key_error_cb), - key_message_cb_(key_message_cb) { + key_message_cb_(key_message_cb), + set_session_id_cb_(set_session_id_cb) { DCHECK(manager_); } @@ -40,43 +42,50 @@ void ProxyMediaKeys::InitializeCDM(const std::string& key_system, #endif } -bool ProxyMediaKeys::GenerateKeyRequest(const std::string& type, +bool ProxyMediaKeys::GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) { manager_->GenerateKeyRequest( media_keys_id_, + reference_id, type, std::vector<uint8>(init_data, init_data + init_data_length)); return true; } -void ProxyMediaKeys::AddKey(const uint8* key, int key_length, - const uint8* init_data, int init_data_length, - const std::string& session_id) { +void ProxyMediaKeys::AddKey(uint32 reference_id, + const uint8* key, int key_length, + const uint8* init_data, int init_data_length) { manager_->AddKey(media_keys_id_, - std::vector<uint8>(key, key + key_length), - std::vector<uint8>(init_data, init_data + init_data_length), - session_id); + reference_id, + std::vector<uint8>(key, key + key_length), + std::vector<uint8>(init_data, init_data + init_data_length)); } -void ProxyMediaKeys::CancelKeyRequest(const std::string& session_id) { - manager_->CancelKeyRequest(media_keys_id_, session_id); +void ProxyMediaKeys::CancelKeyRequest(uint32 reference_id) { + manager_->CancelKeyRequest(media_keys_id_, reference_id); } -void ProxyMediaKeys::OnKeyAdded(const std::string& session_id) { - key_added_cb_.Run(session_id); +void ProxyMediaKeys::OnKeyAdded(uint32 reference_id) { + key_added_cb_.Run(reference_id); } -void ProxyMediaKeys::OnKeyError(const std::string& session_id, +void ProxyMediaKeys::OnKeyError(uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code) { - key_error_cb_.Run(session_id, error_code, system_code); + key_error_cb_.Run(reference_id, error_code, system_code); } -void ProxyMediaKeys::OnKeyMessage(const std::string& session_id, +void ProxyMediaKeys::OnKeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& destination_url) { - key_message_cb_.Run(session_id, message, destination_url); + key_message_cb_.Run(reference_id, message, destination_url); +} + +void ProxyMediaKeys::OnSetSessionId(uint32 reference_id, + const std::string& session_id) { + set_session_id_cb_.Run(reference_id, session_id); } } // namespace content diff --git a/content/renderer/media/android/proxy_media_keys.h b/content/renderer/media/android/proxy_media_keys.h index 10ebf41..119418c 100644 --- a/content/renderer/media/android/proxy_media_keys.h +++ b/content/renderer/media/android/proxy_media_keys.h @@ -24,28 +24,31 @@ class ProxyMediaKeys : public media::MediaKeys { int media_keys_id, const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, - const media::KeyMessageCB& key_message_cb); + const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb); virtual ~ProxyMediaKeys(); void InitializeCDM(const std::string& key_system, const GURL& frame_url); // MediaKeys implementation. - virtual bool GenerateKeyRequest(const std::string& type, + virtual bool GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) OVERRIDE; - virtual void AddKey(const uint8* key, int key_length, - const uint8* init_data, int init_data_length, - const std::string& session_id) OVERRIDE; - virtual void CancelKeyRequest(const std::string& session_id) OVERRIDE; + virtual void AddKey(uint32 reference_id, + const uint8* key, int key_length, + const uint8* init_data, int init_data_length) OVERRIDE; + virtual void CancelKeyRequest(uint32 reference_id) OVERRIDE; // Callbacks. - void OnKeyAdded(const std::string& session_id); - void OnKeyError(const std::string& session_id, + void OnKeyAdded(uint32 reference_id); + void OnKeyError(uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code); - void OnKeyMessage(const std::string& session_id, + void OnKeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& destination_url); + void OnSetSessionId(uint32 reference_id, const std::string& session_id); private: RendererMediaPlayerManager* manager_; @@ -53,6 +56,7 @@ class ProxyMediaKeys : public media::MediaKeys { media::KeyAddedCB key_added_cb_; media::KeyErrorCB key_error_cb_; media::KeyMessageCB key_message_cb_; + media::SetSessionIdCB set_session_id_cb_; DISALLOW_COPY_AND_ASSIGN(ProxyMediaKeys); }; diff --git a/content/renderer/media/android/renderer_media_player_manager.cc b/content/renderer/media/android/renderer_media_player_manager.cc index 5cc92ad..d3560ad 100644 --- a/content/renderer/media/android/renderer_media_player_manager.cc +++ b/content/renderer/media/android/renderer_media_player_manager.cc @@ -60,6 +60,7 @@ bool RendererMediaPlayerManager::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(MediaKeysMsg_KeyAdded, OnKeyAdded) IPC_MESSAGE_HANDLER(MediaKeysMsg_KeyError, OnKeyError) IPC_MESSAGE_HANDLER(MediaKeysMsg_KeyMessage, OnKeyMessage) + IPC_MESSAGE_HANDLER(MediaKeysMsg_SetSessionId, OnSetSessionId) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -233,52 +234,60 @@ void RendererMediaPlayerManager::InitializeCDM(int media_keys_id, void RendererMediaPlayerManager::GenerateKeyRequest( int media_keys_id, + uint32 reference_id, const std::string& type, const std::vector<uint8>& init_data) { Send(new MediaKeysHostMsg_GenerateKeyRequest( - routing_id(), media_keys_id, type, init_data)); + routing_id(), media_keys_id, reference_id, type, init_data)); } void RendererMediaPlayerManager::AddKey(int media_keys_id, + uint32 reference_id, const std::vector<uint8>& key, - const std::vector<uint8>& init_data, - const std::string& session_id) { + const std::vector<uint8>& init_data) { Send(new MediaKeysHostMsg_AddKey( - routing_id(), media_keys_id, key, init_data, session_id)); + routing_id(), media_keys_id, reference_id, key, init_data)); } -void RendererMediaPlayerManager::CancelKeyRequest( - int media_keys_id, - const std::string& session_id) { +void RendererMediaPlayerManager::CancelKeyRequest(int media_keys_id, + uint32 reference_id) { Send(new MediaKeysHostMsg_CancelKeyRequest( - routing_id(), media_keys_id, session_id)); + routing_id(), media_keys_id, reference_id)); } void RendererMediaPlayerManager::OnKeyAdded(int media_keys_id, - const std::string& session_id) { + uint32 reference_id) { ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id); if (media_keys) - media_keys->OnKeyAdded(session_id); + media_keys->OnKeyAdded(reference_id); } void RendererMediaPlayerManager::OnKeyError( int media_keys_id, - const std::string& session_id, + uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code) { ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id); if (media_keys) - media_keys->OnKeyError(session_id, error_code, system_code); + media_keys->OnKeyError(reference_id, error_code, system_code); } void RendererMediaPlayerManager::OnKeyMessage( int media_keys_id, - const std::string& session_id, + uint32 reference_id, const std::vector<uint8>& message, const std::string& destination_url) { ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id); if (media_keys) - media_keys->OnKeyMessage(session_id, message, destination_url); + media_keys->OnKeyMessage(reference_id, message, destination_url); +} + +void RendererMediaPlayerManager::OnSetSessionId(int media_keys_id, + uint32 reference_id, + const std::string& session_id) { + ProxyMediaKeys* media_keys = GetMediaKeys(media_keys_id); + if (media_keys) + media_keys->OnSetSessionId(reference_id, session_id); } int RendererMediaPlayerManager::RegisterMediaPlayer( diff --git a/content/renderer/media/android/renderer_media_player_manager.h b/content/renderer/media/android/renderer_media_player_manager.h index d68d03e..58344c7 100644 --- a/content/renderer/media/android/renderer_media_player_manager.h +++ b/content/renderer/media/android/renderer_media_player_manager.h @@ -94,13 +94,14 @@ class RendererMediaPlayerManager : public RenderViewObserver { const std::vector<uint8>& uuid, const GURL& frame_url); void GenerateKeyRequest(int media_keys_id, + uint32 reference_id, const std::string& type, const std::vector<uint8>& init_data); void AddKey(int media_keys_id, + uint32 reference_id, const std::vector<uint8>& key, - const std::vector<uint8>& init_data, - const std::string& session_id); - void CancelKeyRequest(int media_keys_id, const std::string& session_id); + const std::vector<uint8>& init_data); + void CancelKeyRequest(int media_keys_id, uint32 reference_id); // Registers and unregisters a WebMediaPlayerAndroid object. int RegisterMediaPlayer(WebMediaPlayerAndroid* player); @@ -159,15 +160,18 @@ class RendererMediaPlayerManager : public RenderViewObserver { void OnPlayerPlay(int player_id); void OnPlayerPause(int player_id); void OnRequestFullscreen(int player_id); - void OnKeyAdded(int media_keys_id, const std::string& session_id); + void OnKeyAdded(int media_keys_id, uint32 reference_id); void OnKeyError(int media_keys_id, - const std::string& session_id, + uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code); void OnKeyMessage(int media_keys_id, - const std::string& session_id, + uint32 reference_id, const std::vector<uint8>& message, const std::string& destination_url); + void OnSetSessionId(int media_keys_id, + uint32 reference_id, + const std::string& session_id); // Info for all available WebMediaPlayerAndroid on a page; kept so that // we can enumerate them to send updates about tab focus and visibility. diff --git a/content/renderer/media/crypto/content_decryption_module_factory.cc b/content/renderer/media/crypto/content_decryption_module_factory.cc index 7bfa45b..8a16c02 100644 --- a/content/renderer/media/crypto/content_decryption_module_factory.cc +++ b/content/renderer/media/crypto/content_decryption_module_factory.cc @@ -50,6 +50,7 @@ static scoped_ptr<media::MediaKeys> CreatePpapiDecryptor( const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb, const base::Closure& destroy_plugin_cb, blink::WebMediaPlayerClient* web_media_player_client, blink::WebFrame* web_frame) { @@ -61,7 +62,7 @@ static scoped_ptr<media::MediaKeys> CreatePpapiDecryptor( const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance = CreateHelperPlugin(plugin_type, web_media_player_client, web_frame); if (!plugin_instance.get()) { - DLOG(ERROR) << "ProxyDecryptor: plugin instance creation failed."; + DLOG(ERROR) << "Plugin instance creation failed."; return scoped_ptr<media::MediaKeys>(); } @@ -71,6 +72,7 @@ static scoped_ptr<media::MediaKeys> CreatePpapiDecryptor( key_added_cb, key_error_cb, key_message_cb, + set_session_id_cb, destroy_plugin_cb); if (!decryptor) @@ -100,10 +102,11 @@ scoped_ptr<media::MediaKeys> ContentDecryptionModuleFactory::Create( #endif // defined(ENABLE_PEPPER_CDMS) const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, - const media::KeyMessageCB& key_message_cb) { + const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb) { if (CanUseAesDecryptor(key_system)) { - return scoped_ptr<media::MediaKeys>( - new media::AesDecryptor(key_added_cb, key_error_cb, key_message_cb)); + return scoped_ptr<media::MediaKeys>(new media::AesDecryptor( + key_added_cb, key_error_cb, key_message_cb, set_session_id_cb)); } #if defined(ENABLE_PEPPER_CDMS) @@ -112,12 +115,22 @@ scoped_ptr<media::MediaKeys> ContentDecryptionModuleFactory::Create( if (!web_media_player_client) return scoped_ptr<media::MediaKeys>(); - return CreatePpapiDecryptor( - key_system, key_added_cb, key_error_cb, key_message_cb, - destroy_plugin_cb, web_media_player_client, web_frame); + return CreatePpapiDecryptor(key_system, + key_added_cb, + key_error_cb, + key_message_cb, + set_session_id_cb, + destroy_plugin_cb, + web_media_player_client, + web_frame); #elif defined(OS_ANDROID) - scoped_ptr<ProxyMediaKeys> proxy_media_keys(new ProxyMediaKeys( - manager, media_keys_id, key_added_cb, key_error_cb, key_message_cb)); + scoped_ptr<ProxyMediaKeys> proxy_media_keys( + new ProxyMediaKeys(manager, + media_keys_id, + key_added_cb, + key_error_cb, + key_message_cb, + set_session_id_cb)); proxy_media_keys->InitializeCDM(key_system, frame_url); return proxy_media_keys.PassAs<media::MediaKeys>(); #else diff --git a/content/renderer/media/crypto/content_decryption_module_factory.h b/content/renderer/media/crypto/content_decryption_module_factory.h index 6a84f0f..1b8fa7c 100644 --- a/content/renderer/media/crypto/content_decryption_module_factory.h +++ b/content/renderer/media/crypto/content_decryption_module_factory.h @@ -39,7 +39,8 @@ class ContentDecryptionModuleFactory { #endif // defined(ENABLE_PEPPER_CDMS) const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, - const media::KeyMessageCB& key_message_cb); + const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb); #if defined(ENABLE_PEPPER_CDMS) static void DestroyHelperPlugin( diff --git a/content/renderer/media/crypto/ppapi_decryptor.cc b/content/renderer/media/crypto/ppapi_decryptor.cc index 5722735..6beac45 100644 --- a/content/renderer/media/crypto/ppapi_decryptor.cc +++ b/content/renderer/media/crypto/ppapi_decryptor.cc @@ -28,6 +28,7 @@ scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create( const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb, const base::Closure& destroy_plugin_cb) { ContentDecryptorDelegate* plugin_cdm_delegate = plugin_instance->GetContentDecryptorDelegate(); @@ -36,16 +37,14 @@ scoped_ptr<PpapiDecryptor> PpapiDecryptor::Create( return scoped_ptr<PpapiDecryptor>(); } - // TODO(jrummell): How do we get the can_challenge_platform value from - // the browser? - const bool can_challenge_platform = false; - plugin_cdm_delegate->Initialize(key_system, can_challenge_platform); + plugin_cdm_delegate->Initialize(key_system); return scoped_ptr<PpapiDecryptor>(new PpapiDecryptor(plugin_instance, plugin_cdm_delegate, key_added_cb, key_error_cb, key_message_cb, + set_session_id_cb, destroy_plugin_cb)); } @@ -55,23 +54,31 @@ PpapiDecryptor::PpapiDecryptor( const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb, const base::Closure& destroy_plugin_cb) : plugin_instance_(plugin_instance), plugin_cdm_delegate_(plugin_cdm_delegate), key_added_cb_(key_added_cb), key_error_cb_(key_error_cb), key_message_cb_(key_message_cb), + set_session_id_cb_(set_session_id_cb), destroy_plugin_cb_(destroy_plugin_cb), render_loop_proxy_(base::MessageLoopProxy::current()), weak_ptr_factory_(this) { DCHECK(plugin_instance_.get()); + DCHECK(!key_added_cb_.is_null()); + DCHECK(!key_error_cb_.is_null()); + DCHECK(!key_message_cb_.is_null()); + DCHECK(!set_session_id_cb_.is_null()); + DCHECK(!destroy_plugin_cb_.is_null()); weak_this_ = weak_ptr_factory_.GetWeakPtr(); plugin_cdm_delegate_->SetKeyEventCallbacks( base::Bind(&PpapiDecryptor::KeyAdded, weak_this_), base::Bind(&PpapiDecryptor::KeyError, weak_this_), - base::Bind(&PpapiDecryptor::KeyMessage, weak_this_)); + base::Bind(&PpapiDecryptor::KeyMessage, weak_this_), + base::Bind(&PpapiDecryptor::SetSessionId, weak_this_)); } PpapiDecryptor::~PpapiDecryptor() { @@ -80,7 +87,8 @@ PpapiDecryptor::~PpapiDecryptor() { destroy_plugin_cb_.Run(); } -bool PpapiDecryptor::GenerateKeyRequest(const std::string& type, +bool PpapiDecryptor::GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) { DVLOG(2) << "GenerateKeyRequest()"; @@ -88,25 +96,25 @@ bool PpapiDecryptor::GenerateKeyRequest(const std::string& type, DCHECK(plugin_cdm_delegate_); if (!plugin_cdm_delegate_->GenerateKeyRequest( - type, init_data, init_data_length)) { - ReportFailureToCallPlugin(std::string()); + reference_id, type, init_data, init_data_length)) { + ReportFailureToCallPlugin(reference_id); return false; } return true; } -void PpapiDecryptor::AddKey(const uint8* key, +void PpapiDecryptor::AddKey(uint32 reference_id, + const uint8* key, int key_length, const uint8* init_data, - int init_data_length, - const std::string& session_id) { + int init_data_length) { DVLOG(2) << "AddKey()"; DCHECK(render_loop_proxy_->BelongsToCurrentThread()); if (!plugin_cdm_delegate_->AddKey( - session_id, key, key_length, init_data, init_data_length)) { - ReportFailureToCallPlugin(session_id); + reference_id, key, key_length, init_data, init_data_length)) { + ReportFailureToCallPlugin(reference_id); } if (!new_audio_key_cb_.is_null()) @@ -116,12 +124,12 @@ void PpapiDecryptor::AddKey(const uint8* key, new_video_key_cb_.Run(); } -void PpapiDecryptor::CancelKeyRequest(const std::string& session_id) { +void PpapiDecryptor::CancelKeyRequest(uint32 reference_id) { DVLOG(2) << "CancelKeyRequest()"; DCHECK(render_loop_proxy_->BelongsToCurrentThread()); - if (!plugin_cdm_delegate_->CancelKeyRequest(session_id)) - ReportFailureToCallPlugin(session_id); + if (!plugin_cdm_delegate_->CancelKeyRequest(reference_id)) + ReportFailureToCallPlugin(reference_id); } media::Decryptor* PpapiDecryptor::GetDecryptor() { @@ -268,9 +276,9 @@ void PpapiDecryptor::DeinitializeDecoder(StreamType stream_type) { plugin_cdm_delegate_->DeinitializeDecoder(stream_type); } -void PpapiDecryptor::ReportFailureToCallPlugin(const std::string& session_id) { +void PpapiDecryptor::ReportFailureToCallPlugin(uint32 reference_id) { DVLOG(1) << "Failed to call plugin."; - key_error_cb_.Run(session_id, kUnknownError, 0); + key_error_cb_.Run(reference_id, kUnknownError, 0); } void PpapiDecryptor::OnDecoderInitialized(StreamType stream_type, @@ -289,23 +297,29 @@ void PpapiDecryptor::OnDecoderInitialized(StreamType stream_type, } } -void PpapiDecryptor::KeyAdded(const std::string& session_id) { +void PpapiDecryptor::KeyAdded(uint32 reference_id) { DCHECK(render_loop_proxy_->BelongsToCurrentThread()); - key_added_cb_.Run(session_id); + key_added_cb_.Run(reference_id); } -void PpapiDecryptor::KeyError(const std::string& session_id, +void PpapiDecryptor::KeyError(uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code) { DCHECK(render_loop_proxy_->BelongsToCurrentThread()); - key_error_cb_.Run(session_id, error_code, system_code); + key_error_cb_.Run(reference_id, error_code, system_code); } -void PpapiDecryptor::KeyMessage(const std::string& session_id, +void PpapiDecryptor::KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url) { DCHECK(render_loop_proxy_->BelongsToCurrentThread()); - key_message_cb_.Run(session_id, message, default_url); + key_message_cb_.Run(reference_id, message, default_url); +} + +void PpapiDecryptor::SetSessionId(uint32 reference_id, + const std::string& session_id) { + DCHECK(render_loop_proxy_->BelongsToCurrentThread()); + set_session_id_cb_.Run(reference_id, session_id); } } // namespace content diff --git a/content/renderer/media/crypto/ppapi_decryptor.h b/content/renderer/media/crypto/ppapi_decryptor.h index 5700204..48bf436 100644 --- a/content/renderer/media/crypto/ppapi_decryptor.h +++ b/content/renderer/media/crypto/ppapi_decryptor.h @@ -35,18 +35,22 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb, const base::Closure& destroy_plugin_cb); virtual ~PpapiDecryptor(); // media::MediaKeys implementation. - virtual bool GenerateKeyRequest(const std::string& type, + virtual bool GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) OVERRIDE; - virtual void AddKey(const uint8* key, int key_length, - const uint8* init_data, int init_data_length, - const std::string& session_id) OVERRIDE; - virtual void CancelKeyRequest(const std::string& session_id) OVERRIDE; + virtual void AddKey(uint32 reference_id, + const uint8* key, + int key_length, + const uint8* init_data, + int init_data_length) OVERRIDE; + virtual void CancelKeyRequest(uint32 reference_id) OVERRIDE; virtual Decryptor* GetDecryptor() OVERRIDE; // media::Decryptor implementation. @@ -70,26 +74,27 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { virtual void DeinitializeDecoder(StreamType stream_type) OVERRIDE; private: - PpapiDecryptor( - const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance, - ContentDecryptorDelegate* plugin_cdm_delegate, - const media::KeyAddedCB& key_added_cb, - const media::KeyErrorCB& key_error_cb, - const media::KeyMessageCB& key_message_cb, - const base::Closure& destroy_plugin_cb); + PpapiDecryptor(const scoped_refptr<PepperPluginInstanceImpl>& plugin_instance, + ContentDecryptorDelegate* plugin_cdm_delegate, + const media::KeyAddedCB& key_added_cb, + const media::KeyErrorCB& key_error_cb, + const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb, + const base::Closure& destroy_plugin_cb); - void ReportFailureToCallPlugin(const std::string& session_id); + void ReportFailureToCallPlugin(uint32 reference_id); void OnDecoderInitialized(StreamType stream_type, bool success); // Callbacks for |plugin_cdm_delegate_| to fire key events. - void KeyAdded(const std::string& session_id); - void KeyError(const std::string& session_id, + void KeyAdded(uint32 reference_id); + void KeyError(uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code); - void KeyMessage(const std::string& session_id, + void KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url); + void SetSessionId(uint32 reference_id, const std::string& session_id); base::WeakPtr<PpapiDecryptor> weak_this_; @@ -104,6 +109,7 @@ class PpapiDecryptor : public media::MediaKeys, public media::Decryptor { media::KeyAddedCB key_added_cb_; media::KeyErrorCB key_error_cb_; media::KeyMessageCB key_message_cb_; + media::SetSessionIdCB set_session_id_cb_; // Called to destroy the helper plugin when this class no longer needs it. base::Closure destroy_plugin_cb_; diff --git a/content/renderer/media/crypto/proxy_decryptor.cc b/content/renderer/media/crypto/proxy_decryptor.cc index a75e71c..7387be5 100644 --- a/content/renderer/media/crypto/proxy_decryptor.cc +++ b/content/renderer/media/crypto/proxy_decryptor.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/logging.h" +#include "base/strings/string_util.h" #include "content/renderer/media/crypto/content_decryption_module_factory.h" #if defined(OS_ANDROID) #include "content/renderer/media/android/renderer_media_player_manager.h" @@ -14,6 +15,14 @@ namespace content { +// Since these reference IDs may conflict with the ones generated in +// WebContentDecryptionModuleSessionImpl for the short time both paths are +// active, start with 100000 and generate the IDs from there. +// TODO(jrummell): Only allow one path http://crbug.com/306680. +uint32 ProxyDecryptor::next_reference_id_ = 100000; + +const uint32 INVALID_REFERENCE_ID = 0; + #if defined(ENABLE_PEPPER_CDMS) void ProxyDecryptor::DestroyHelperPlugin() { ContentDecryptionModuleFactory::DestroyHelperPlugin( @@ -29,9 +38,9 @@ ProxyDecryptor::ProxyDecryptor( RendererMediaPlayerManager* manager, int media_keys_id, #endif // defined(ENABLE_PEPPER_CDMS) - const media::KeyAddedCB& key_added_cb, - const media::KeyErrorCB& key_error_cb, - const media::KeyMessageCB& key_message_cb) + const KeyAddedCB& key_added_cb, + const KeyErrorCB& key_error_cb, + const KeyMessageCB& key_message_cb) : weak_ptr_factory_(this), #if defined(ENABLE_PEPPER_CDMS) web_media_player_client_(web_media_player_client), @@ -43,6 +52,9 @@ ProxyDecryptor::ProxyDecryptor( key_added_cb_(key_added_cb), key_error_cb_(key_error_cb), key_message_cb_(key_message_cb) { + DCHECK(!key_added_cb_.is_null()); + DCHECK(!key_error_cb_.is_null()); + DCHECK(!key_message_cb_.is_null()); } ProxyDecryptor::~ProxyDecryptor() { @@ -97,7 +109,10 @@ bool ProxyDecryptor::InitializeCDM(const std::string& key_system, bool ProxyDecryptor::GenerateKeyRequest(const std::string& type, const uint8* init_data, int init_data_length) { - if (!media_keys_->GenerateKeyRequest(type, init_data, init_data_length)) { + // Use a unique reference id for this request. + uint32 reference_id = next_reference_id_++; + if (!media_keys_->GenerateKeyRequest( + reference_id, type, init_data, init_data_length)) { media_keys_.reset(); return false; } @@ -113,14 +128,35 @@ void ProxyDecryptor::AddKey(const uint8* key, DVLOG(1) << "AddKey()"; // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. - media_keys_->AddKey(key, key_length, init_data, init_data_length, session_id); + uint32 reference_id = LookupReferenceId(session_id); + if (reference_id == INVALID_REFERENCE_ID) { + // Session hasn't been referenced before, so it is an error. + // Note that the specification says "If sessionId is not null and is + // unrecognized, throw an INVALID_ACCESS_ERR." However, for backwards + // compatibility the error is not thrown, but rather reported as a + // KeyError. + key_error_cb_.Run( + std::string(), media::MediaKeys::kUnknownError, 0); + } + else { + media_keys_->AddKey( + reference_id, key, key_length, init_data, init_data_length); + } } void ProxyDecryptor::CancelKeyRequest(const std::string& session_id) { DVLOG(1) << "CancelKeyRequest()"; // WebMediaPlayerImpl ensures GenerateKeyRequest() has been called. - media_keys_->CancelKeyRequest(session_id); + uint32 reference_id = LookupReferenceId(session_id); + if (reference_id == INVALID_REFERENCE_ID) { + // Session hasn't been created, so it is an error. + key_error_cb_.Run( + std::string(), media::MediaKeys::kUnknownError, 0); + } + else { + media_keys_->CancelKeyRequest(reference_id); + } } scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys( @@ -140,23 +176,60 @@ scoped_ptr<media::MediaKeys> ProxyDecryptor::CreateMediaKeys( #endif // defined(ENABLE_PEPPER_CDMS) base::Bind(&ProxyDecryptor::KeyAdded, weak_ptr_factory_.GetWeakPtr()), base::Bind(&ProxyDecryptor::KeyError, weak_ptr_factory_.GetWeakPtr()), - base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr())); + base::Bind(&ProxyDecryptor::KeyMessage, weak_ptr_factory_.GetWeakPtr()), + base::Bind(&ProxyDecryptor::SetSessionId, + weak_ptr_factory_.GetWeakPtr())); } -void ProxyDecryptor::KeyAdded(const std::string& session_id) { - key_added_cb_.Run(session_id); +void ProxyDecryptor::KeyAdded(uint32 reference_id) { + // Assumes that SetSessionId() has been called before this. + key_added_cb_.Run(LookupSessionId(reference_id)); } -void ProxyDecryptor::KeyError(const std::string& session_id, +void ProxyDecryptor::KeyError(uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code) { - key_error_cb_.Run(session_id, error_code, system_code); + // Assumes that SetSessionId() has been called before this. + key_error_cb_.Run(LookupSessionId(reference_id), error_code, system_code); } -void ProxyDecryptor::KeyMessage(const std::string& session_id, +void ProxyDecryptor::KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url) { - key_message_cb_.Run(session_id, message, default_url); + // Assumes that SetSessionId() has been called before this. + key_message_cb_.Run(LookupSessionId(reference_id), message, default_url); +} + +void ProxyDecryptor::SetSessionId(uint32 reference_id, + const std::string& session_id) { + // Due to heartbeat messages, SetSessionId() can get called multiple times. + SessionIdMap::iterator it = sessions_.find(reference_id); + DCHECK(it == sessions_.end() || it->second == session_id); + if (it == sessions_.end()) + sessions_[reference_id] = session_id; +} + +uint32 ProxyDecryptor::LookupReferenceId(const std::string& session_id) { + for (SessionIdMap::iterator it = sessions_.begin(); + it != sessions_.end(); + ++it) { + if (it->second == session_id) + return it->first; + } + + // If |session_id| is null, then use the single reference id. + if (session_id.empty() && sessions_.size() == 1) + return sessions_.begin()->first; + + return INVALID_REFERENCE_ID; +} + +const std::string& ProxyDecryptor::LookupSessionId(uint32 reference_id) { + DCHECK_NE(reference_id, INVALID_REFERENCE_ID); + + // Session may not exist if error happens during GenerateKeyRequest(). + SessionIdMap::iterator it = sessions_.find(reference_id); + return (it != sessions_.end()) ? it->second : EmptyString(); } } // namespace content diff --git a/content/renderer/media/crypto/proxy_decryptor.h b/content/renderer/media/crypto/proxy_decryptor.h index 686270f..de745c1 100644 --- a/content/renderer/media/crypto/proxy_decryptor.h +++ b/content/renderer/media/crypto/proxy_decryptor.h @@ -5,6 +5,7 @@ #ifndef CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_ #define CONTENT_RENDERER_MEDIA_CRYPTO_PROXY_DECRYPTOR_H_ +#include <map> #include <string> #include <vector> @@ -33,11 +34,26 @@ class RendererMediaPlayerManager; // ProxyDecryptor is for EME v0.1b only. It should not be used for the WD API. // A decryptor proxy that creates a real decryptor object on demand and // forwards decryptor calls to it. +// +// Now that the Pepper API calls use reference ID to match responses with +// requests, this class maintains a mapping between reference ID and session ID. +// Callers of this class expect session IDs in the responses. +// // TODO(xhwang): Currently we don't support run-time switching among decryptor // objects. Fix this when needed. // TODO(xhwang): The ProxyDecryptor is not a Decryptor. Find a better name! -class ProxyDecryptor : public media::MediaKeys { +class ProxyDecryptor { public: + // These are similar to the callbacks in media_keys.h, but pass back the + // session ID rather than a reference ID. + typedef base::Callback<void(const std::string& session_id)> KeyAddedCB; + typedef base::Callback<void(const std::string& session_id, + media::MediaKeys::KeyError error_code, + int system_code)> KeyErrorCB; + typedef base::Callback<void(const std::string& session_id, + const std::vector<uint8>& message, + const std::string& default_url)> KeyMessageCB; + ProxyDecryptor( #if defined(ENABLE_PEPPER_CDMS) blink::WebMediaPlayerClient* web_media_player_client, @@ -46,9 +62,9 @@ class ProxyDecryptor : public media::MediaKeys { RendererMediaPlayerManager* manager, int media_keys_id, #endif // defined(ENABLE_PEPPER_CDMS) - const media::KeyAddedCB& key_added_cb, - const media::KeyErrorCB& key_error_cb, - const media::KeyMessageCB& key_message_cb); + const KeyAddedCB& key_added_cb, + const KeyErrorCB& key_error_cb, + const KeyMessageCB& key_message_cb); virtual ~ProxyDecryptor(); // Only call this once. @@ -60,29 +76,40 @@ class ProxyDecryptor : public media::MediaKeys { // NULL immediately and reset. void SetDecryptorReadyCB(const media::DecryptorReadyCB& decryptor_ready_cb); - // MediaKeys implementation. // May only be called after InitializeCDM() succeeds. - virtual bool GenerateKeyRequest(const std::string& type, - const uint8* init_data, - int init_data_length) OVERRIDE; - virtual void AddKey(const uint8* key, int key_length, - const uint8* init_data, int init_data_length, - const std::string& session_id) OVERRIDE; - virtual void CancelKeyRequest(const std::string& session_id) OVERRIDE; + bool GenerateKeyRequest(const std::string& type, + const uint8* init_data, + int init_data_length); + void AddKey(const uint8* key, int key_length, + const uint8* init_data, int init_data_length, + const std::string& session_id); + void CancelKeyRequest(const std::string& session_id); private: + // This is reference_id <-> session_id map. + typedef std::map<uint32, std::string> SessionIdMap; + // Helper function to create MediaKeys to handle the given |key_system|. scoped_ptr<media::MediaKeys> CreateMediaKeys(const std::string& key_system, const GURL& frame_url); // Callbacks for firing key events. - void KeyAdded(const std::string& session_id); - void KeyError(const std::string& session_id, + void KeyAdded(uint32 reference_id); + void KeyError(uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code); - void KeyMessage(const std::string& session_id, + void KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url); + void SetSessionId(uint32 reference_id, const std::string& session_id); + + // Helper function to determine reference_id for the provided |session_id|. + uint32 LookupReferenceId(const std::string& session_id); + + // Helper function to determine session_id for the provided |reference_id|. + // The returned session_id is only valid on the main thread, and should be + // stored by copy. + const std::string& LookupSessionId(uint32 reference_id); base::WeakPtrFactory<ProxyDecryptor> weak_ptr_factory_; @@ -103,9 +130,9 @@ class ProxyDecryptor : public media::MediaKeys { scoped_ptr<media::MediaKeys> media_keys_; // Callbacks for firing key events. - media::KeyAddedCB key_added_cb_; - media::KeyErrorCB key_error_cb_; - media::KeyMessageCB key_message_cb_; + KeyAddedCB key_added_cb_; + KeyErrorCB key_error_cb_; + KeyMessageCB key_message_cb_; // Protects the |decryptor_|. Note that |decryptor_| itself should be thread // safe as per the Decryptor interface. @@ -113,6 +140,13 @@ class ProxyDecryptor : public media::MediaKeys { media::DecryptorReadyCB decryptor_ready_cb_; + // Reference IDs are used to uniquely track sessions so that CDM callbacks + // can get mapped to the correct session ID. Reference ID should be unique + // per renderer process for debugging purposes. + static uint32 next_reference_id_; + + SessionIdMap sessions_; + DISALLOW_COPY_AND_ASSIGN(ProxyDecryptor); }; diff --git a/content/renderer/media/webcontentdecryptionmodule_impl.cc b/content/renderer/media/webcontentdecryptionmodule_impl.cc index d601adc..4878d96 100644 --- a/content/renderer/media/webcontentdecryptionmodule_impl.cc +++ b/content/renderer/media/webcontentdecryptionmodule_impl.cc @@ -20,61 +20,60 @@ namespace content { -// Forwards the session ID-based callbacks of the MediaKeys interface to the +// Forwards the reference ID-based callbacks of the MediaKeys interface to the // appropriate session object. -class SessionIdAdapter { +class ReferenceIdAdapter { public: - SessionIdAdapter(); - ~SessionIdAdapter(); + ReferenceIdAdapter(); + ~ReferenceIdAdapter(); // On success, creates a MediaKeys, returns it in |media_keys|, returns true. bool Initialize(const std::string& key_system, scoped_ptr<media::MediaKeys>* media_keys); // Adds a session to the internal map. Does not take ownership of the session. - void AddSession(const std::string& session_id, + void AddSession(uint32 reference_id, WebContentDecryptionModuleSessionImpl* session); // Removes a session from the internal map. - void RemoveSession(const std::string& session_id); + void RemoveSession(uint32 reference_id); private: - typedef std::map<std::string, WebContentDecryptionModuleSessionImpl*> - SessionMap; + typedef std::map<uint32, WebContentDecryptionModuleSessionImpl*> SessionMap; // Callbacks for firing key events. - void KeyAdded(const std::string& session_id); - void KeyError(const std::string& session_id, + void KeyAdded(uint32 reference_id); + void KeyError(uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code); - void KeyMessage(const std::string& session_id, + void KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& destination_url); + void SetSessionId(uint32 reference_id, const std::string& session_id); // Helper function of the callbacks. - WebContentDecryptionModuleSessionImpl* GetSession( - const std::string& session_id); + WebContentDecryptionModuleSessionImpl* GetSession(uint32 reference_id); - SessionMap sessions_; + base::WeakPtrFactory<ReferenceIdAdapter> weak_ptr_factory_; - base::WeakPtrFactory<SessionIdAdapter> weak_ptr_factory_; + SessionMap sessions_; - DISALLOW_COPY_AND_ASSIGN(SessionIdAdapter); + DISALLOW_COPY_AND_ASSIGN(ReferenceIdAdapter); }; -SessionIdAdapter::SessionIdAdapter() +ReferenceIdAdapter::ReferenceIdAdapter() : weak_ptr_factory_(this) { } -SessionIdAdapter::~SessionIdAdapter() { +ReferenceIdAdapter::~ReferenceIdAdapter() { } -bool SessionIdAdapter::Initialize(const std::string& key_system, - scoped_ptr<media::MediaKeys>* media_keys) { +bool ReferenceIdAdapter::Initialize(const std::string& key_system, + scoped_ptr<media::MediaKeys>* media_keys) { DCHECK(media_keys); DCHECK(!*media_keys); - base::WeakPtr<SessionIdAdapter> weak_this = weak_ptr_factory_.GetWeakPtr(); + base::WeakPtr<ReferenceIdAdapter> weak_this = weak_ptr_factory_.GetWeakPtr(); scoped_ptr<media::MediaKeys> created_media_keys = ContentDecryptionModuleFactory::Create( // TODO(ddorwin): Address lower in the stack: http://crbug.com/252065 @@ -91,9 +90,10 @@ bool SessionIdAdapter::Initialize(const std::string& key_system, // TODO(ddorwin): Get the URL for the frame containing the MediaKeys. GURL(), #endif // defined(ENABLE_PEPPER_CDMS) - base::Bind(&SessionIdAdapter::KeyAdded, weak_this), - base::Bind(&SessionIdAdapter::KeyError, weak_this), - base::Bind(&SessionIdAdapter::KeyMessage, weak_this)); + base::Bind(&ReferenceIdAdapter::KeyAdded, weak_this), + base::Bind(&ReferenceIdAdapter::KeyError, weak_this), + base::Bind(&ReferenceIdAdapter::KeyMessage, weak_this), + base::Bind(&ReferenceIdAdapter::SetSessionId, weak_this)); if (!created_media_keys) return false; @@ -101,41 +101,43 @@ bool SessionIdAdapter::Initialize(const std::string& key_system, return true; } -void SessionIdAdapter::AddSession( - const std::string& session_id, +void ReferenceIdAdapter::AddSession( + uint32 reference_id, WebContentDecryptionModuleSessionImpl* session) { - DCHECK(sessions_.find(session_id) == sessions_.end()); - sessions_[session_id] = session; + DCHECK(sessions_.find(reference_id) == sessions_.end()); + sessions_[reference_id] = session; } -void SessionIdAdapter::RemoveSession(const std::string& session_id) { - DCHECK(sessions_.find(session_id) != sessions_.end()); - sessions_.erase(session_id); +void ReferenceIdAdapter::RemoveSession(uint32 reference_id) { + DCHECK(sessions_.find(reference_id) != sessions_.end()); + sessions_.erase(reference_id); } -void SessionIdAdapter::KeyAdded(const std::string& session_id) { - GetSession(session_id)->KeyAdded(); +void ReferenceIdAdapter::KeyAdded(uint32 reference_id) { + GetSession(reference_id)->KeyAdded(); } -void SessionIdAdapter::KeyError(const std::string& session_id, - media::MediaKeys::KeyError error_code, - int system_code) { - GetSession(session_id)->KeyError(error_code, system_code); +void ReferenceIdAdapter::KeyError(uint32 reference_id, + media::MediaKeys::KeyError error_code, + int system_code) { + GetSession(reference_id)->KeyError(error_code, system_code); } -void SessionIdAdapter::KeyMessage(const std::string& session_id, - const std::vector<uint8>& message, - const std::string& destination_url) { - GetSession(session_id)->KeyMessage(message, destination_url); +void ReferenceIdAdapter::KeyMessage(uint32 reference_id, + const std::vector<uint8>& message, + const std::string& destination_url) { + GetSession(reference_id)->KeyMessage(message, destination_url); } -WebContentDecryptionModuleSessionImpl* SessionIdAdapter::GetSession( - const std::string& session_id) { - // TODO(ddorwin): Map session IDs correctly. For now, we only support one. - std::string session_object_id = ""; - WebContentDecryptionModuleSessionImpl* session = sessions_[session_object_id]; - DCHECK(session); // It must have been present. - return session; +void ReferenceIdAdapter::SetSessionId(uint32 reference_id, + const std::string& session_id) { + GetSession(reference_id)->SetSessionId(session_id); +} + +WebContentDecryptionModuleSessionImpl* ReferenceIdAdapter::GetSession( + uint32 reference_id) { + DCHECK(sessions_.find(reference_id) != sessions_.end()); + return sessions_[reference_id]; } //------------------------------------------------------------------------------ @@ -149,10 +151,10 @@ WebContentDecryptionModuleImpl::Create(const string16& key_system) { return NULL; } - // SessionIdAdapter creates the MediaKeys so it can provide its callbacks to + // ReferenceIdAdapter creates the MediaKeys so it can provide its callbacks to // during creation of the MediaKeys. scoped_ptr<media::MediaKeys> media_keys; - scoped_ptr<SessionIdAdapter> adapter(new SessionIdAdapter()); + scoped_ptr<ReferenceIdAdapter> adapter(new ReferenceIdAdapter()); if (!adapter->Initialize(UTF16ToASCII(key_system), &media_keys)) return NULL; @@ -161,7 +163,7 @@ WebContentDecryptionModuleImpl::Create(const string16& key_system) { WebContentDecryptionModuleImpl::WebContentDecryptionModuleImpl( scoped_ptr<media::MediaKeys> media_keys, - scoped_ptr<SessionIdAdapter> adapter) + scoped_ptr<ReferenceIdAdapter> adapter) : media_keys_(media_keys.Pass()), adapter_(adapter.Pass()) { } @@ -181,14 +183,12 @@ WebContentDecryptionModuleImpl::createSession( base::Bind(&WebContentDecryptionModuleImpl::OnSessionClosed, base::Unretained(this))); - // TODO(ddorwin): session_id is not populated yet! - adapter_->AddSession(session->session_id(), session); + adapter_->AddSession(session->reference_id(), session); return session; } -void WebContentDecryptionModuleImpl::OnSessionClosed( - const std::string& session_id) { - adapter_->RemoveSession(session_id); +void WebContentDecryptionModuleImpl::OnSessionClosed(uint32 reference_id) { + adapter_->RemoveSession(reference_id); } } // namespace content diff --git a/content/renderer/media/webcontentdecryptionmodule_impl.h b/content/renderer/media/webcontentdecryptionmodule_impl.h index 442b657..a457bca 100644 --- a/content/renderer/media/webcontentdecryptionmodule_impl.h +++ b/content/renderer/media/webcontentdecryptionmodule_impl.h @@ -18,7 +18,7 @@ class MediaKeys; namespace content { class WebContentDecryptionModuleSessionImpl; -class SessionIdAdapter; +class ReferenceIdAdapter; class WebContentDecryptionModuleImpl : public blink::WebContentDecryptionModule { @@ -34,13 +34,13 @@ class WebContentDecryptionModuleImpl private: // Takes ownership of |media_keys| and |adapter|. WebContentDecryptionModuleImpl(scoped_ptr<media::MediaKeys> media_keys, - scoped_ptr<SessionIdAdapter> adapter); + scoped_ptr<ReferenceIdAdapter> adapter); // Called when a WebContentDecryptionModuleSessionImpl is closed. - void OnSessionClosed(const std::string& session_id); + void OnSessionClosed(uint32 reference_id); scoped_ptr<media::MediaKeys> media_keys_; - scoped_ptr<SessionIdAdapter> adapter_; + scoped_ptr<ReferenceIdAdapter> adapter_; DISALLOW_COPY_AND_ASSIGN(WebContentDecryptionModuleImpl); }; diff --git a/content/renderer/media/webcontentdecryptionmodulesession_impl.cc b/content/renderer/media/webcontentdecryptionmodulesession_impl.cc index b991ad1..fb71437 100644 --- a/content/renderer/media/webcontentdecryptionmodulesession_impl.cc +++ b/content/renderer/media/webcontentdecryptionmodulesession_impl.cc @@ -11,15 +11,21 @@ namespace content { +static const uint32 kStartingReferenceId = 1; +uint32 WebContentDecryptionModuleSessionImpl::next_reference_id_ = + kStartingReferenceId; +COMPILE_ASSERT(kStartingReferenceId != media::MediaKeys::kInvalidReferenceId, + invalid_starting_value); + WebContentDecryptionModuleSessionImpl::WebContentDecryptionModuleSessionImpl( media::MediaKeys* media_keys, Client* client, const SessionClosedCB& session_closed_cb) : media_keys_(media_keys), client_(client), - session_closed_cb_(session_closed_cb) { + session_closed_cb_(session_closed_cb), + reference_id_(next_reference_id_++) { DCHECK(media_keys_); - // TODO(ddorwin): Populate session_id_ from the real implementation. } WebContentDecryptionModuleSessionImpl:: @@ -41,22 +47,22 @@ void WebContentDecryptionModuleSessionImpl::generateKeyRequest( return; } - media_keys_->GenerateKeyRequest(UTF16ToASCII(mime_type), - init_data, init_data_length); + media_keys_->GenerateKeyRequest( + reference_id_, UTF16ToASCII(mime_type), init_data, init_data_length); } void WebContentDecryptionModuleSessionImpl::update(const uint8* key, size_t key_length) { DCHECK(key); - media_keys_->AddKey(key, key_length, NULL, 0, session_id_); + media_keys_->AddKey(reference_id_, key, key_length, NULL, 0); } void WebContentDecryptionModuleSessionImpl::close() { - media_keys_->CancelKeyRequest(session_id_); - // Detach from the CDM. + // TODO(jrummell): We shouldn't detach here because closed and other events + // may be fired in the latest version of the spec. http://crbug.com/309235 if (!session_closed_cb_.is_null()) - base::ResetAndReturn(&session_closed_cb_).Run(session_id_); + base::ResetAndReturn(&session_closed_cb_).Run(reference_id_); } void WebContentDecryptionModuleSessionImpl::KeyAdded() { @@ -78,4 +84,15 @@ void WebContentDecryptionModuleSessionImpl::KeyMessage( GURL(destination_url)); } +void WebContentDecryptionModuleSessionImpl::SetSessionId( + const std::string& session_id) { + // Due to heartbeat messages, SetSessionId() can get called multiple times. + // TODO(jrummell): Once all CDMs are updated to support reference ids, + // SetSessionId() should only be called once, and the second check can be + // removed. + DCHECK(session_id_.empty() || session_id_ == session_id) + << "Session ID may not be changed once set."; + session_id_ = session_id; +} + } // namespace content diff --git a/content/renderer/media/webcontentdecryptionmodulesession_impl.h b/content/renderer/media/webcontentdecryptionmodulesession_impl.h index 126c232..d920e2d 100644 --- a/content/renderer/media/webcontentdecryptionmodulesession_impl.h +++ b/content/renderer/media/webcontentdecryptionmodulesession_impl.h @@ -23,7 +23,7 @@ namespace content { class WebContentDecryptionModuleSessionImpl : public blink::WebContentDecryptionModuleSession { public: - typedef base::Callback<void(const std::string& session_id)> SessionClosedCB; + typedef base::Callback<void(uint32 reference_id)> SessionClosedCB; WebContentDecryptionModuleSessionImpl( media::MediaKeys* media_keys, @@ -41,11 +41,14 @@ class WebContentDecryptionModuleSessionImpl const std::string& session_id() const { return session_id_; } + uint32 reference_id() const { return reference_id_; } + // Callbacks. void KeyAdded(); void KeyError(media::MediaKeys::KeyError error_code, int system_code); void KeyMessage(const std::vector<uint8>& message, const std::string& destination_url); + void SetSessionId(const std::string& session_id); private: // Non-owned pointers. @@ -54,8 +57,17 @@ class WebContentDecryptionModuleSessionImpl SessionClosedCB session_closed_cb_; + // Session ID is the user visible ID for this session generated by the CDM. + // This value is not set until the CDM calls SetSessionId(). std::string session_id_; + // Reference ID is used to uniquely track this object so that CDM callbacks + // can get routed to the correct object. + const uint32 reference_id_; + + // Reference ID should be unique per renderer process for debugging purposes. + static uint32 next_reference_id_; + DISALLOW_COPY_AND_ASSIGN(WebContentDecryptionModuleSessionImpl); }; diff --git a/content/renderer/pepper/content_decryptor_delegate.cc b/content/renderer/pepper/content_decryptor_delegate.cc index 27cb71d..f1b4e96 100644 --- a/content/renderer/pepper/content_decryptor_delegate.cc +++ b/content/renderer/pepper/content_decryptor_delegate.cc @@ -262,28 +262,29 @@ ContentDecryptorDelegate::ContentDecryptorDelegate( ContentDecryptorDelegate::~ContentDecryptorDelegate() { } -void ContentDecryptorDelegate::Initialize(const std::string& key_system, - bool can_challenge_platform) { +void ContentDecryptorDelegate::Initialize(const std::string& key_system) { DCHECK(!key_system.empty()); DCHECK(key_system_.empty()); key_system_ = key_system; plugin_decryption_interface_->Initialize( pp_instance_, - StringVar::StringToPPVar(key_system_), - PP_FromBool(can_challenge_platform)); + StringVar::StringToPPVar(key_system_)); } void ContentDecryptorDelegate::SetKeyEventCallbacks( const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, - const media::KeyMessageCB& key_message_cb) { + const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb) { key_added_cb_ = key_added_cb; key_error_cb_ = key_error_cb; key_message_cb_ = key_message_cb; + set_session_id_cb_ = set_session_id_cb; } -bool ContentDecryptorDelegate::GenerateKeyRequest(const std::string& type, +bool ContentDecryptorDelegate::GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) { PP_Var init_data_array = @@ -292,12 +293,13 @@ bool ContentDecryptorDelegate::GenerateKeyRequest(const std::string& type, plugin_decryption_interface_->GenerateKeyRequest( pp_instance_, + reference_id, StringVar::StringToPPVar(type), init_data_array); return true; } -bool ContentDecryptorDelegate::AddKey(const std::string& session_id, +bool ContentDecryptorDelegate::AddKey(uint32 reference_id, const uint8* key, int key_length, const uint8* init_data, @@ -310,17 +312,12 @@ bool ContentDecryptorDelegate::AddKey(const std::string& session_id, init_data_length, init_data); plugin_decryption_interface_->AddKey( - pp_instance_, - StringVar::StringToPPVar(session_id), - key_array, - init_data_array); + pp_instance_, reference_id, key_array, init_data_array); return true; } -bool ContentDecryptorDelegate::CancelKeyRequest(const std::string& session_id) { - plugin_decryption_interface_->CancelKeyRequest( - pp_instance_, - StringVar::StringToPPVar(session_id)); +bool ContentDecryptorDelegate::CancelKeyRequest(uint32 reference_id) { + plugin_decryption_interface_->CancelKeyRequest(pp_instance_, reference_id); return true; } @@ -597,36 +594,19 @@ bool ContentDecryptorDelegate::DecryptAndDecodeVideo( return true; } -void ContentDecryptorDelegate::NeedKey(PP_Var key_system_var, - PP_Var session_id_var, - PP_Var init_data_var) { - // TODO(ddorwin): Remove from PPB_ContentDecryptor_Private. - NOTREACHED(); -} - -void ContentDecryptorDelegate::KeyAdded(PP_Var key_system_var, - PP_Var session_id_var) { +void ContentDecryptorDelegate::KeyAdded(uint32 reference_id) { if (key_added_cb_.is_null()) return; - StringVar* session_id_string = StringVar::FromPPVar(session_id_var); - if (!session_id_string) { - key_error_cb_.Run(std::string(), media::MediaKeys::kUnknownError, 0); - return; - } - - key_added_cb_.Run(session_id_string->value()); + key_added_cb_.Run(reference_id); } -void ContentDecryptorDelegate::KeyMessage(PP_Var key_system_var, - PP_Var session_id_var, +void ContentDecryptorDelegate::KeyMessage(uint32 reference_id, PP_Var message_var, PP_Var default_url_var) { if (key_message_cb_.is_null()) return; - StringVar* session_id_string = StringVar::FromPPVar(session_id_var); - ArrayBufferVar* message_array_buffer = ArrayBufferVar::FromPPVar(message_var); @@ -638,32 +618,38 @@ void ContentDecryptorDelegate::KeyMessage(PP_Var key_system_var, StringVar* default_url_string = StringVar::FromPPVar(default_url_var); - if (!session_id_string || !default_url_string) { - key_error_cb_.Run(std::string(), media::MediaKeys::kUnknownError, 0); + if (!default_url_string) { + key_error_cb_.Run(reference_id, media::MediaKeys::kUnknownError, 0); return; } - key_message_cb_.Run(session_id_string->value(), - message, - default_url_string->value()); + key_message_cb_.Run(reference_id, message, default_url_string->value()); } -void ContentDecryptorDelegate::KeyError(PP_Var key_system_var, - PP_Var session_id_var, +void ContentDecryptorDelegate::KeyError(uint32 reference_id, int32_t media_error, int32_t system_code) { if (key_error_cb_.is_null()) return; + key_error_cb_.Run(reference_id, + static_cast<media::MediaKeys::KeyError>(media_error), + system_code); +} + +void ContentDecryptorDelegate::SetSessionId(uint32 reference_id, + PP_Var session_id_var) { + if (set_session_id_cb_.is_null()) + return; + StringVar* session_id_string = StringVar::FromPPVar(session_id_var); + if (!session_id_string) { - key_error_cb_.Run(std::string(), media::MediaKeys::kUnknownError, 0); + key_error_cb_.Run(reference_id, media::MediaKeys::kUnknownError, 0); return; } - key_error_cb_.Run(session_id_string->value(), - static_cast<media::MediaKeys::KeyError>(media_error), - system_code); + set_session_id_cb_.Run(reference_id, session_id_string->value()); } void ContentDecryptorDelegate::DecoderInitializeDone( diff --git a/content/renderer/pepper/content_decryptor_delegate.h b/content/renderer/pepper/content_decryptor_delegate.h index efa7586..6d0962d 100644 --- a/content/renderer/pepper/content_decryptor_delegate.h +++ b/content/renderer/pepper/content_decryptor_delegate.h @@ -39,23 +39,24 @@ class ContentDecryptorDelegate { const PPP_ContentDecryptor_Private* plugin_decryption_interface); ~ContentDecryptorDelegate(); - void Initialize(const std::string& key_system, - const bool can_challenge_platform); + void Initialize(const std::string& key_system); void SetKeyEventCallbacks(const media::KeyAddedCB& key_added_cb, const media::KeyErrorCB& key_error_cb, - const media::KeyMessageCB& key_message_cb); + const media::KeyMessageCB& key_message_cb, + const media::SetSessionIdCB& set_session_id_cb); // Provides access to PPP_ContentDecryptor_Private. - bool GenerateKeyRequest(const std::string& type, + bool GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length); - bool AddKey(const std::string& session_id, + bool AddKey(uint32 reference_id, const uint8* key, int key_length, const uint8* init_data, int init_data_length); - bool CancelKeyRequest(const std::string& session_id); + bool CancelKeyRequest(uint32 reference_id); bool Decrypt(media::Decryptor::StreamType stream_type, const scoped_refptr<media::DecoderBuffer>& encrypted_buffer, const media::Decryptor::DecryptCB& decrypt_cb); @@ -79,18 +80,14 @@ class ContentDecryptorDelegate { const media::Decryptor::VideoDecodeCB& video_decode_cb); // PPB_ContentDecryptor_Private dispatching methods. - // TODO(ddorwin): Remove this method. - void NeedKey(PP_Var key_system, PP_Var session_id, PP_Var init_data); - // TODO(ddorwin): Remove key_system_var parameter from these methods. - void KeyAdded(PP_Var key_system, PP_Var session_id); - void KeyMessage(PP_Var key_system, - PP_Var session_id, + void KeyAdded(uint32 reference_id); + void KeyMessage(uint32 reference_id, PP_Var message, PP_Var default_url); - void KeyError(PP_Var key_system, - PP_Var session_id, + void KeyError(uint32 reference_id, int32_t media_error, int32_t system_code); + void SetSessionId(uint32 reference_id, PP_Var session_id_var); void DeliverBlock(PP_Resource decrypted_block, const PP_DecryptedBlockInfo* block_info); void DecoderInitializeDone(PP_DecryptorStreamType decoder_type, @@ -145,6 +142,7 @@ class ContentDecryptorDelegate { media::KeyAddedCB key_added_cb_; media::KeyErrorCB key_error_cb_; media::KeyMessageCB key_message_cb_; + media::SetSessionIdCB set_session_id_cb_; gfx::Size natural_size_; diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.cc b/content/renderer/pepper/pepper_plugin_instance_impl.cc index 08e22dc..76e6c62 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.cc +++ b/content/renderer/pepper/pepper_plugin_instance_impl.cc @@ -2219,27 +2219,29 @@ PP_Var PepperPluginInstanceImpl::GetDefaultCharSet(PP_Instance instance) { // Therefore, |content_decryptor_delegate_| must have been initialized when // the following methods are called. void PepperPluginInstanceImpl::KeyAdded(PP_Instance instance, - PP_Var key_system_var, - PP_Var session_id_var) { - content_decryptor_delegate_->KeyAdded(key_system_var, session_id_var); + uint32_t reference_id) { + content_decryptor_delegate_->KeyAdded(reference_id); } void PepperPluginInstanceImpl::KeyMessage(PP_Instance instance, - PP_Var key_system_var, - PP_Var session_id_var, + uint32_t reference_id, PP_Var message_var, PP_Var default_url_var) { content_decryptor_delegate_->KeyMessage( - key_system_var, session_id_var, message_var, default_url_var); + reference_id, message_var, default_url_var); } void PepperPluginInstanceImpl::KeyError(PP_Instance instance, - PP_Var key_system_var, - PP_Var session_id_var, + uint32_t reference_id, int32_t media_error, int32_t system_code) { - content_decryptor_delegate_->KeyError( - key_system_var, session_id_var, media_error, system_code); + content_decryptor_delegate_->KeyError(reference_id, media_error, system_code); +} + +void PepperPluginInstanceImpl::SetSessionId(PP_Instance instance, + uint32_t reference_id, + PP_Var session_id_var) { + content_decryptor_delegate_->SetSessionId(reference_id, session_id_var); } void PepperPluginInstanceImpl::DeliverBlock( diff --git a/content/renderer/pepper/pepper_plugin_instance_impl.h b/content/renderer/pepper/pepper_plugin_instance_impl.h index d94b802..8285a6d 100644 --- a/content/renderer/pepper/pepper_plugin_instance_impl.h +++ b/content/renderer/pepper/pepper_plugin_instance_impl.h @@ -445,18 +445,18 @@ class CONTENT_EXPORT PepperPluginInstanceImpl // PPB_ContentDecryptor_Private implementation. virtual void KeyAdded(PP_Instance instance, - PP_Var key_system, - PP_Var session_id) OVERRIDE; + uint32_t reference_id) OVERRIDE; virtual void KeyMessage(PP_Instance instance, - PP_Var key_system, - PP_Var session_id, + uint32_t reference_id, PP_Var message, PP_Var default_url) OVERRIDE; virtual void KeyError(PP_Instance instance, - PP_Var key_system, - PP_Var session_id, + uint32_t reference_id, int32_t media_error, int32_t system_code) OVERRIDE; + virtual void SetSessionId(PP_Instance instance, + uint32_t reference_id, + PP_Var session_id_var) OVERRIDE; virtual void DeliverBlock(PP_Instance instance, PP_Resource decrypted_block, const PP_DecryptedBlockInfo* block_info) OVERRIDE; diff --git a/media/base/android/media_drm_bridge.cc b/media/base/android/media_drm_bridge.cc index d1a6a05..8b5d59e 100644 --- a/media/base/android/media_drm_bridge.cc +++ b/media/base/android/media_drm_bridge.cc @@ -11,6 +11,7 @@ #include "base/location.h" #include "base/logging.h" #include "base/message_loop/message_loop_proxy.h" +#include "base/strings/string_util.h" #include "jni/MediaDrmBridge_jni.h" #include "media/base/android/media_player_manager.h" @@ -235,7 +236,8 @@ MediaDrmBridge::~MediaDrmBridge() { Java_MediaDrmBridge_release(env, j_media_drm_.obj()); } -bool MediaDrmBridge::GenerateKeyRequest(const std::string& type, +bool MediaDrmBridge::GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) { std::vector<uint8> pssh_data; @@ -246,28 +248,29 @@ bool MediaDrmBridge::GenerateKeyRequest(const std::string& type, ScopedJavaLocalRef<jbyteArray> j_pssh_data = base::android::ToJavaByteArray(env, &pssh_data[0], pssh_data.size()); ScopedJavaLocalRef<jstring> j_mime = ConvertUTF8ToJavaString(env, type); + pending_key_request_reference_ids_.push(reference_id); Java_MediaDrmBridge_generateKeyRequest( env, j_media_drm_.obj(), j_pssh_data.obj(), j_mime.obj()); return true; } -void MediaDrmBridge::AddKey(const uint8* key, int key_length, - const uint8* init_data, int init_data_length, - const std::string& session_id) { +void MediaDrmBridge::AddKey(uint32 reference_id, + const uint8* key, int key_length, + const uint8* init_data, int init_data_length) { DVLOG(1) << __FUNCTION__; JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jbyteArray> j_key_data = base::android::ToJavaByteArray(env, key, key_length); ScopedJavaLocalRef<jstring> j_session_id = - ConvertUTF8ToJavaString(env, session_id); + ConvertUTF8ToJavaString(env, LookupSessionId(reference_id)); Java_MediaDrmBridge_addKey( env, j_media_drm_.obj(), j_session_id.obj(), j_key_data.obj()); } -void MediaDrmBridge::CancelKeyRequest(const std::string& session_id) { +void MediaDrmBridge::CancelKeyRequest(uint32 reference_id) { JNIEnv* env = AttachCurrentThread(); ScopedJavaLocalRef<jstring> j_session_id = - ConvertUTF8ToJavaString(env, session_id); + ConvertUTF8ToJavaString(env, LookupSessionId(reference_id)); Java_MediaDrmBridge_cancelKeyRequest( env, j_media_drm_.obj(), j_session_id.obj()); } @@ -300,22 +303,28 @@ void MediaDrmBridge::OnKeyMessage(JNIEnv* env, jbyteArray j_message, jstring j_destination_url) { std::string session_id = ConvertJavaStringToUTF8(env, j_session_id); + uint32_t reference_id = DetermineReferenceId(session_id); std::vector<uint8> message; JavaByteArrayToByteVector(env, j_message, &message); std::string destination_url = ConvertJavaStringToUTF8(env, j_destination_url); - manager_->OnKeyMessage(media_keys_id_, session_id, message, destination_url); + manager_->OnSetSessionId(media_keys_id_, reference_id, session_id); + manager_->OnKeyMessage( + media_keys_id_, reference_id, message, destination_url); } void MediaDrmBridge::OnKeyAdded(JNIEnv* env, jobject, jstring j_session_id) { std::string session_id = ConvertJavaStringToUTF8(env, j_session_id); - manager_->OnKeyAdded(media_keys_id_, session_id); + uint32_t reference_id = DetermineReferenceId(session_id); + manager_->OnKeyAdded(media_keys_id_, reference_id); } void MediaDrmBridge::OnKeyError(JNIEnv* env, jobject, jstring j_session_id) { // |j_session_id| can be NULL, in which case we'll return an empty string. std::string session_id = ConvertJavaStringToUTF8(env, j_session_id); - manager_->OnKeyError(media_keys_id_, session_id, MediaKeys::kUnknownError, 0); + uint32 reference_id = DetermineReferenceId(session_id); + manager_->OnKeyError( + media_keys_id_, reference_id, MediaKeys::kUnknownError, 0); } ScopedJavaLocalRef<jobject> MediaDrmBridge::GetMediaCrypto() { @@ -354,4 +363,36 @@ void MediaDrmBridge::OnResetDeviceCredentialsCompleted( base::ResetAndReturn(&reset_credentials_cb_).Run(success); } +uint32_t MediaDrmBridge::DetermineReferenceId(const std::string& session_id) { + for (SessionMap::iterator it = session_map_.begin(); + it != session_map_.end(); + ++it) { + if (it->second == session_id) + return it->first; + } + + // There is no entry in the map; assume it came from the oldest + // GenerateKeyRequest() call. + DCHECK(!pending_key_request_reference_ids_.empty()); + uint32 reference_id = pending_key_request_reference_ids_.front(); + pending_key_request_reference_ids_.pop(); + + // If this is a valid |session_id|, add it to the list. Otherwise, avoid + // adding empty string as a mapping to prevent future calls with an empty + // string from using the wrong reference_id. + if (!session_id.empty()) { + DCHECK(session_map_.find(reference_id) == session_map_.end()); + DCHECK(!session_id.empty()); + session_map_[reference_id] = session_id; + } + + return reference_id; +} + +const std::string& MediaDrmBridge::LookupSessionId(uint32 reference_id) { + // Session may not exist if error happens during GenerateKeyRequest(). + SessionMap::iterator it = session_map_.find(reference_id); + return (it != session_map_.end()) ? it->second : EmptyString(); +} + } // namespace media diff --git a/media/base/android/media_drm_bridge.h b/media/base/android/media_drm_bridge.h index 520b54d..2443f65 100644 --- a/media/base/android/media_drm_bridge.h +++ b/media/base/android/media_drm_bridge.h @@ -6,6 +6,8 @@ #define MEDIA_BASE_ANDROID_MEDIA_DRM_BRIDGE_H_ #include <jni.h> +#include <map> +#include <queue> #include <string> #include <vector> @@ -59,13 +61,14 @@ class MEDIA_EXPORT MediaDrmBridge : public MediaKeys { static bool RegisterMediaDrmBridge(JNIEnv* env); // MediaKeys implementations. - virtual bool GenerateKeyRequest(const std::string& type, + virtual bool GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) OVERRIDE; - virtual void AddKey(const uint8* key, int key_length, - const uint8* init_data, int init_data_length, - const std::string& session_id) OVERRIDE; - virtual void CancelKeyRequest(const std::string& session_id) OVERRIDE; + virtual void AddKey(uint32 reference_id, + const uint8* key, int key_length, + const uint8* init_data, int init_data_length) OVERRIDE; + virtual void CancelKeyRequest(uint32 reference_id) OVERRIDE; // Returns a MediaCrypto object if it's already created. Returns a null object // otherwise. @@ -103,6 +106,9 @@ class MEDIA_EXPORT MediaDrmBridge : public MediaKeys { GURL frame_url() const { return frame_url_; } private: + // Map between session_id and reference_id. + typedef std::map<uint32_t, std::string> SessionMap; + static bool IsSecureDecoderRequired(SecurityLevel security_level); MediaDrmBridge(int media_keys_id, @@ -114,6 +120,13 @@ class MEDIA_EXPORT MediaDrmBridge : public MediaKeys { // Get the security level of the media. SecurityLevel GetSecurityLevel(); + // Determine the corresponding reference_id for |session_id|. + uint32_t DetermineReferenceId(const std::string& session_id); + + // Determine the corresponding session_id for |reference_id|. The returned + // value is only valid on the main thread, and should be stored by copy. + const std::string& LookupSessionId(uint32_t reference_id); + // ID of the MediaKeys object. int media_keys_id_; @@ -133,6 +146,14 @@ class MEDIA_EXPORT MediaDrmBridge : public MediaKeys { ResetCredentialsCB reset_credentials_cb_; + SessionMap session_map_; + + // As the response from GenerateKeyRequest() will be asynchronous, add this + // request to a queue and assume that the subsequent responses come back in + // the order issued. + // TODO(jrummell): Remove once the Java interface supports reference_id. + std::queue<uint32_t> pending_key_request_reference_ids_; + DISALLOW_COPY_AND_ASSIGN(MediaDrmBridge); }; diff --git a/media/base/android/media_player_manager.h b/media/base/android/media_player_manager.h index 668613b..ec15b35 100644 --- a/media/base/android/media_player_manager.h +++ b/media/base/android/media_player_manager.h @@ -87,25 +87,30 @@ class MEDIA_EXPORT MediaPlayerManager { // Called by the player to get a hardware protected surface. virtual void OnProtectedSurfaceRequested(int player_id) = 0; - // TODO(xhwang): The following three methods needs to be decoupled from + // TODO(xhwang): The following four methods needs to be decoupled from // MediaPlayerManager to support the W3C Working Draft version of the EME - // spec. + // spec. http://crbug.com/315312 // Called when MediaDrmBridge wants to send a KeyAdded. virtual void OnKeyAdded(int media_keys_id, - const std::string& session_id) = 0; + uint32 reference_id) = 0; // Called when MediaDrmBridge wants to send a KeyError. virtual void OnKeyError(int media_keys_id, - const std::string& session_id, + uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code) = 0; // Called when MediaDrmBridge wants to send a KeyMessage. virtual void OnKeyMessage(int media_keys_id, - const std::string& session_id, + uint32 reference_id, const std::vector<uint8>& message, const std::string& destination_url) = 0; + + // Called when MediaDrmBridge determines a SessionId. + virtual void OnSetSessionId(int media_keys_id, + uint32 reference_id, + const std::string& session_id) = 0; }; } // namespace media diff --git a/media/base/android/media_source_player_unittest.cc b/media/base/android/media_source_player_unittest.cc index 71b02e0..7afdf50 100644 --- a/media/base/android/media_source_player_unittest.cc +++ b/media/base/android/media_source_player_unittest.cc @@ -72,15 +72,18 @@ class MockMediaPlayerManager : public MediaPlayerManager { } virtual void OnProtectedSurfaceRequested(int player_id) OVERRIDE {} virtual void OnKeyAdded(int key_id, - const std::string& session_id) OVERRIDE {} + uint32 reference_id) OVERRIDE {} virtual void OnKeyError(int key_id, - const std::string& session_id, + uint32 reference_id, MediaKeys::KeyError error_code, int system_code) OVERRIDE {} virtual void OnKeyMessage(int key_id, - const std::string& session_id, + uint32 reference_id, const std::vector<uint8>& message, const std::string& destination_url) OVERRIDE {} + virtual void OnSetSessionId(int media_keys_id, + uint32 reference_id, + const std::string& session_id) OVERRIDE {} private: base::MessageLoop* message_loop_; diff --git a/media/base/media_keys.h b/media/base/media_keys.h index ff83f34..743d714 100644 --- a/media/base/media_keys.h +++ b/media/base/media_keys.h @@ -37,6 +37,8 @@ class MEDIA_EXPORT MediaKeys { kMaxKeyError // Must be last and greater than any legit value. }; + const static uint32 kInvalidReferenceId = 0; + MediaKeys(); virtual ~MediaKeys(); @@ -44,7 +46,8 @@ class MEDIA_EXPORT MediaKeys { // Returns true if generating key request succeeded, false otherwise. // Note: AddKey() and CancelKeyRequest() should only be called after // GenerateKeyRequest() returns true. - virtual bool GenerateKeyRequest(const std::string& type, + virtual bool GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) = 0; @@ -52,12 +55,14 @@ class MEDIA_EXPORT MediaKeys { // key. It can be any data that the key system accepts, such as a license. // If multiple calls of this function set different keys for the same // key ID, the older key will be replaced by the newer key. - virtual void AddKey(const uint8* key, int key_length, - const uint8* init_data, int init_data_length, - const std::string& session_id) = 0; + virtual void AddKey(uint32 reference_id, + const uint8* key, + int key_length, + const uint8* init_data, + int init_data_length) = 0; - // Cancels the key request specified by |session_id|. - virtual void CancelKeyRequest(const std::string& session_id) = 0; + // Cancels the key request specified by |reference_id|. + virtual void CancelKeyRequest(uint32 reference_id) = 0; // Gets the Decryptor object associated with the MediaKeys. Returns NULL if // no Decryptor object is associated. The returned object is only guaranteed @@ -70,15 +75,21 @@ class MEDIA_EXPORT MediaKeys { // Key event callbacks. See the spec for details: // http://dvcs.w3.org/hg/html-media/raw-file/eme-v0.1b/encrypted-media/encrypted-media.html#event-summary -typedef base::Callback<void(const std::string& session_id)> KeyAddedCB; +typedef base::Callback<void(uint32 reference_id)> KeyAddedCB; -typedef base::Callback<void(const std::string& session_id, +typedef base::Callback<void(uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code)> KeyErrorCB; -typedef base::Callback<void(const std::string& session_id, +typedef base::Callback<void(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url)> KeyMessageCB; + +// Called by the CDM when it generates the |session_id| as a result of a +// GenerateKeyRequest() call. Must be called before KeyMessageCB or KeyAddedCB +// events are fired. +typedef base::Callback<void(uint32 reference_id, + const std::string& session_id)> SetSessionIdCB; } // namespace media #endif // MEDIA_BASE_MEDIA_KEYS_H_ diff --git a/media/cdm/aes_decryptor.cc b/media/cdm/aes_decryptor.cc index fe840ff3..7c5857c 100644 --- a/media/cdm/aes_decryptor.cc +++ b/media/cdm/aes_decryptor.cc @@ -259,17 +259,19 @@ static scoped_refptr<DecoderBuffer> DecryptData(const DecoderBuffer& input, AesDecryptor::AesDecryptor(const KeyAddedCB& key_added_cb, const KeyErrorCB& key_error_cb, - const KeyMessageCB& key_message_cb) + const KeyMessageCB& key_message_cb, + const SetSessionIdCB& set_session_id_cb) : key_added_cb_(key_added_cb), key_error_cb_(key_error_cb), - key_message_cb_(key_message_cb) { -} + key_message_cb_(key_message_cb), + set_session_id_cb_(set_session_id_cb) {} AesDecryptor::~AesDecryptor() { STLDeleteValues(&key_map_); } -bool AesDecryptor::GenerateKeyRequest(const std::string& type, +bool AesDecryptor::GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) { std::string session_id_string(base::UintToString(next_session_id_++)); @@ -280,15 +282,16 @@ bool AesDecryptor::GenerateKeyRequest(const std::string& type, if (init_data && init_data_length) message.assign(init_data, init_data + init_data_length); - key_message_cb_.Run(session_id_string, message, std::string()); + set_session_id_cb_.Run(reference_id, session_id_string); + key_message_cb_.Run(reference_id, message, std::string()); return true; } -void AesDecryptor::AddKey(const uint8* key, +void AesDecryptor::AddKey(uint32 reference_id, + const uint8* key, int key_length, const uint8* init_data, - int init_data_length, - const std::string& session_id) { + int init_data_length) { CHECK(key); CHECK_GT(key_length, 0); @@ -301,9 +304,6 @@ void AesDecryptor::AddKey(const uint8* key, // key and |init_data| is the key id), if |key| is not valid JSON, then // attempt to process it as a raw key. - // TODO(xhwang): Add |session_id| check after we figure out how: - // https://www.w3.org/Bugs/Public/show_bug.cgi?id=16550 - std::string key_string(reinterpret_cast<const char*>(key), key_length); JWKKeys jwk_keys; if (ExtractJWKKeys(key_string, &jwk_keys)) { @@ -313,12 +313,12 @@ void AesDecryptor::AddKey(const uint8* key, // Make sure that at least one key was extracted. if (jwk_keys.empty()) { - key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); + key_error_cb_.Run(reference_id, MediaKeys::kUnknownError, 0); return; } for (JWKKeys::iterator it = jwk_keys.begin() ; it != jwk_keys.end(); ++it) { if (!AddDecryptionKey(it->first, it->second)) { - key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); + key_error_cb_.Run(reference_id, MediaKeys::kUnknownError, 0); return; } } @@ -329,7 +329,7 @@ void AesDecryptor::AddKey(const uint8* key, if (key_string.length() != static_cast<size_t>(DecryptConfig::kDecryptionKeySize)) { DVLOG(1) << "Invalid key length: " << key_string.length(); - key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); + key_error_cb_.Run(reference_id, MediaKeys::kUnknownError, 0); return; } @@ -347,7 +347,7 @@ void AesDecryptor::AddKey(const uint8* key, init_data_length); if (!AddDecryptionKey(key_id_string, key_string)) { // Error logged in AddDecryptionKey() - key_error_cb_.Run(session_id, MediaKeys::kUnknownError, 0); + key_error_cb_.Run(reference_id, MediaKeys::kUnknownError, 0); return; } } @@ -358,10 +358,10 @@ void AesDecryptor::AddKey(const uint8* key, if (!new_video_key_cb_.is_null()) new_video_key_cb_.Run(); - key_added_cb_.Run(session_id); + key_added_cb_.Run(reference_id); } -void AesDecryptor::CancelKeyRequest(const std::string& session_id) { +void AesDecryptor::CancelKeyRequest(uint32 reference_id) { } Decryptor* AesDecryptor::GetDecryptor() { diff --git a/media/cdm/aes_decryptor.h b/media/cdm/aes_decryptor.h index 3ab4bc0..d1f9341 100644 --- a/media/cdm/aes_decryptor.h +++ b/media/cdm/aes_decryptor.h @@ -29,17 +29,21 @@ class MEDIA_EXPORT AesDecryptor : public MediaKeys, public Decryptor { public: AesDecryptor(const KeyAddedCB& key_added_cb, const KeyErrorCB& key_error_cb, - const KeyMessageCB& key_message_cb); + const KeyMessageCB& key_message_cb, + const SetSessionIdCB& set_session_id_cb); virtual ~AesDecryptor(); // MediaKeys implementation. - virtual bool GenerateKeyRequest(const std::string& type, + virtual bool GenerateKeyRequest(uint32 reference_id, + const std::string& type, const uint8* init_data, int init_data_length) OVERRIDE; - virtual void AddKey(const uint8* key, int key_length, - const uint8* init_data, int init_data_length, - const std::string& session_id) OVERRIDE; - virtual void CancelKeyRequest(const std::string& session_id) OVERRIDE; + virtual void AddKey(uint32 reference_id, + const uint8* key, + int key_length, + const uint8* init_data, + int init_data_length) OVERRIDE; + virtual void CancelKeyRequest(uint32 reference_id) OVERRIDE; virtual Decryptor* GetDecryptor() OVERRIDE; // Decryptor implementation. @@ -99,6 +103,7 @@ class MEDIA_EXPORT AesDecryptor : public MediaKeys, public Decryptor { KeyAddedCB key_added_cb_; KeyErrorCB key_error_cb_; KeyMessageCB key_message_cb_; + SetSessionIdCB set_session_id_cb_; // KeyMap owns the DecryptionKey* and must delete them when they are // not needed any more. diff --git a/media/cdm/aes_decryptor_unittest.cc b/media/cdm/aes_decryptor_unittest.cc index 3adc861..b52a6195 100644 --- a/media/cdm/aes_decryptor_unittest.cc +++ b/media/cdm/aes_decryptor_unittest.cc @@ -192,7 +192,8 @@ class AesDecryptorTest : public testing::Test { : decryptor_( base::Bind(&AesDecryptorTest::KeyAdded, base::Unretained(this)), base::Bind(&AesDecryptorTest::KeyError, base::Unretained(this)), - base::Bind(&AesDecryptorTest::KeyMessage, base::Unretained(this))), + base::Bind(&AesDecryptorTest::KeyMessage, base::Unretained(this)), + base::Bind(&AesDecryptorTest::SetSession, base::Unretained(this))), decrypt_cb_(base::Bind(&AesDecryptorTest::BufferDecrypted, base::Unretained(this))), original_data_(kOriginalData, kOriginalData + kOriginalDataSize), @@ -210,11 +211,12 @@ class AesDecryptorTest : public testing::Test { protected: void GenerateKeyRequest(const std::vector<uint8>& key_id) { + reference_id_ = 6; DCHECK(!key_id.empty()); - EXPECT_CALL(*this, KeyMessage(StrNe(std::string()), key_id, "")) - .WillOnce(SaveArg<0>(&session_id_string_)); + EXPECT_CALL(*this, SetSession(reference_id_, StrNe(std::string()))); + EXPECT_CALL(*this, KeyMessage(reference_id_, key_id, "")); EXPECT_TRUE(decryptor_.GenerateKeyRequest( - std::string(), &key_id[0], key_id.size())); + reference_id_, std::string(), &key_id[0], key_id.size())); } enum AddKeyExpectation { @@ -230,33 +232,33 @@ class AesDecryptorTest : public testing::Test { DCHECK(!key.empty()); if (result == KEY_ADDED) { - EXPECT_CALL(*this, KeyAdded(session_id_string_)); + EXPECT_CALL(*this, KeyAdded(reference_id_)); } else if (result == KEY_ERROR) { - EXPECT_CALL(*this, KeyError(session_id_string_, - MediaKeys::kUnknownError, 0)); + EXPECT_CALL(*this, KeyError(reference_id_, MediaKeys::kUnknownError, 0)); } else { NOTREACHED(); } - decryptor_.AddKey(&key[0], key.size(), &key_id[0], key_id.size(), - session_id_string_); + decryptor_.AddKey( + reference_id_, &key[0], key.size(), &key_id[0], key_id.size()); } void AddKeyAndExpect(const std::string& key, AddKeyExpectation result) { DCHECK(!key.empty()); if (result == KEY_ADDED) { - EXPECT_CALL(*this, KeyAdded(session_id_string_)); + EXPECT_CALL(*this, KeyAdded(reference_id_)); } else if (result == KEY_ERROR) { - EXPECT_CALL(*this, - KeyError(session_id_string_, MediaKeys::kUnknownError, 0)); + EXPECT_CALL(*this, KeyError(reference_id_, MediaKeys::kUnknownError, 0)); } else { NOTREACHED(); } - decryptor_.AddKey(reinterpret_cast<const uint8*>(key.c_str()), key.length(), - NULL, 0, - session_id_string_); + decryptor_.AddKey(reference_id_, + reinterpret_cast<const uint8*>(key.c_str()), + key.length(), + NULL, + 0); } MOCK_METHOD2(BufferDecrypted, void(Decryptor::Status, @@ -307,15 +309,17 @@ class AesDecryptorTest : public testing::Test { } } - MOCK_METHOD1(KeyAdded, void(const std::string&)); - MOCK_METHOD3(KeyError, void(const std::string&, - MediaKeys::KeyError, int)); - MOCK_METHOD3(KeyMessage, void(const std::string& session_id, - const std::vector<uint8>& message, - const std::string& default_url)); + MOCK_METHOD1(KeyAdded, void(uint32 reference_id)); + MOCK_METHOD3(KeyError, void(uint32 reference_id, MediaKeys::KeyError, int)); + MOCK_METHOD3(KeyMessage, + void(uint32 reference_id, + const std::vector<uint8>& message, + const std::string& default_url)); + MOCK_METHOD2(SetSession, + void(uint32 reference_id, const std::string& session_id)); AesDecryptor decryptor_; - std::string session_id_string_; + uint32 reference_id_; AesDecryptor::DecryptCB decrypt_cb_; // Constants for testing. @@ -329,8 +333,31 @@ class AesDecryptorTest : public testing::Test { }; TEST_F(AesDecryptorTest, GenerateKeyRequestWithNullInitData) { - EXPECT_CALL(*this, KeyMessage(StrNe(std::string()), IsEmpty(), "")); - EXPECT_TRUE(decryptor_.GenerateKeyRequest(std::string(), NULL, 0)); + reference_id_ = 8; + EXPECT_CALL(*this, KeyMessage(reference_id_, IsEmpty(), "")); + EXPECT_CALL(*this, SetSession(reference_id_, StrNe(std::string()))); + EXPECT_TRUE( + decryptor_.GenerateKeyRequest(reference_id_, std::string(), NULL, 0)); +} + +TEST_F(AesDecryptorTest, MultipleGenerateKeyRequest) { + uint32 reference_id1 = 10; + EXPECT_CALL(*this, KeyMessage(reference_id1, IsEmpty(), "")); + EXPECT_CALL(*this, SetSession(reference_id1, StrNe(std::string()))); + EXPECT_TRUE( + decryptor_.GenerateKeyRequest(reference_id1, std::string(), NULL, 0)); + + uint32 reference_id2 = 11; + EXPECT_CALL(*this, KeyMessage(reference_id2, IsEmpty(), "")); + EXPECT_CALL(*this, SetSession(reference_id2, StrNe(std::string()))); + EXPECT_TRUE( + decryptor_.GenerateKeyRequest(reference_id2, std::string(), NULL, 0)); + + uint32 reference_id3 = 23; + EXPECT_CALL(*this, KeyMessage(reference_id3, IsEmpty(), "")); + EXPECT_CALL(*this, SetSession(reference_id3, StrNe(std::string()))); + EXPECT_TRUE( + decryptor_.GenerateKeyRequest(reference_id3, std::string(), NULL, 0)); } TEST_F(AesDecryptorTest, NormalDecryption) { diff --git a/media/cdm/ppapi/cdm_adapter.cc b/media/cdm/ppapi/cdm_adapter.cc index f8adb03..1da9d15 100644 --- a/media/cdm/ppapi/cdm_adapter.cc +++ b/media/cdm/ppapi/cdm_adapter.cc @@ -236,8 +236,7 @@ bool CdmAdapter::CreateCdmInstance(const std::string& key_system) { // No KeyErrors should be reported in this function because they cannot be // bubbled up in the WD EME API. Those errors will be reported during session // creation (aka GenerateKeyRequest). -void CdmAdapter::Initialize(const std::string& key_system, - bool can_challenge_platform) { +void CdmAdapter::Initialize(const std::string& key_system) { PP_DCHECK(!key_system.empty()); PP_DCHECK(key_system_.empty() || (key_system_ == key_system && cdm_)); @@ -248,12 +247,13 @@ void CdmAdapter::Initialize(const std::string& key_system, key_system_ = key_system; } -void CdmAdapter::GenerateKeyRequest(const std::string& type, +void CdmAdapter::GenerateKeyRequest(uint32_t reference_id, + const std::string& type, pp::VarArrayBuffer init_data) { // Initialize() doesn't report an error, so GenerateKeyRequest() can be called // even if Initialize() failed. if (!cdm_) { - SendUnknownKeyError(key_system_, std::string()); + SendUnknownKeyError(reference_id); return; } @@ -267,22 +267,20 @@ void CdmAdapter::GenerateKeyRequest(const std::string& type, PP_DCHECK(0 < url_components.host.len); #endif // defined(CHECK_DOCUMENT_URL) - cdm::Status status = cdm_->GenerateKeyRequest( - type.data(), type.size(), - static_cast<const uint8_t*>(init_data.Map()), - init_data.ByteLength()); - PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); - if (status != cdm::kSuccess) - SendUnknownKeyError(key_system_, std::string()); + cdm_->GenerateKeyRequest(reference_id, + type.data(), + type.size(), + static_cast<const uint8_t*>(init_data.Map()), + init_data.ByteLength()); } -void CdmAdapter::AddKey(const std::string& session_id, +void CdmAdapter::AddKey(uint32_t reference_id, pp::VarArrayBuffer key, pp::VarArrayBuffer init_data) { // TODO(jrummell): In EME WD, AddKey() can only be called on valid sessions. // We should be able to DCHECK(cdm_) when addressing http://crbug.com/249976. if (!cdm_) { - SendUnknownKeyError(key_system_, session_id); + SendUnknownKeyError(reference_id); return; } @@ -292,36 +290,43 @@ void CdmAdapter::AddKey(const std::string& session_id, const uint32_t init_data_size = init_data.ByteLength(); PP_DCHECK(!init_data_ptr == !init_data_size); - if (!key_ptr || !key_size) { - SendUnknownKeyError(key_system_, session_id); + if (!key_ptr || key_size <= 0) { + SendUnknownKeyError(reference_id); return; } - - cdm::Status status = cdm_->AddKey(session_id.data(), session_id.size(), - key_ptr, key_size, - init_data_ptr, init_data_size); - PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); - if (status != cdm::kSuccess) { - SendUnknownKeyError(key_system_, session_id); - return; + CdmWrapper::Result result = cdm_->AddKey( + reference_id, key_ptr, key_size, init_data_ptr, init_data_size); + switch (result) { + case CdmWrapper::NO_ACTION: + break; + case CdmWrapper::CALL_KEY_ADDED: + SendKeyAdded(reference_id); + break; + case CdmWrapper::CALL_KEY_ERROR: + SendUnknownKeyError(reference_id); + break; } - - SendKeyAdded(key_system_, session_id); } -void CdmAdapter::CancelKeyRequest(const std::string& session_id) { +void CdmAdapter::CancelKeyRequest(uint32_t reference_id) { // TODO(jrummell): In EME WD, AddKey() can only be called on valid sessions. // We should be able to DCHECK(cdm_) when addressing http://crbug.com/249976. if (!cdm_) { - SendUnknownKeyError(key_system_, session_id); + SendUnknownKeyError(reference_id); return; } - cdm::Status status = cdm_->CancelKeyRequest(session_id.data(), - session_id.size()); - PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); - if (status != cdm::kSuccess) - SendUnknownKeyError(key_system_, session_id); + CdmWrapper::Result result = cdm_->CancelKeyRequest(reference_id); + switch (result) { + case CdmWrapper::NO_ACTION: + break; + case CdmWrapper::CALL_KEY_ADDED: + PP_NOTREACHED(); + break; + case CdmWrapper::CALL_KEY_ERROR: + SendUnknownKeyError(reference_id); + break; + } } // Note: In the following decryption/decoding related functions, errors are NOT @@ -527,10 +532,17 @@ void CdmAdapter::SendKeyMessage( const char* message, uint32_t message_length, const char* default_url, uint32_t default_url_length) { PP_DCHECK(!key_system_.empty()); + + std::string session_id_str(session_id, session_id_length); + PP_DCHECK(!session_id_str.empty()); + uint32_t reference_id = cdm_->DetermineReferenceId(session_id_str); + + PostOnMain(callback_factory_.NewCallback( + &CdmAdapter::SetSessionId, reference_id, session_id_str)); + PostOnMain(callback_factory_.NewCallback( &CdmAdapter::KeyMessage, - SessionInfo(key_system_, - std::string(session_id, session_id_length)), + reference_id, std::vector<uint8>(message, message + message_length), std::string(default_url, default_url_length))); } @@ -539,10 +551,10 @@ void CdmAdapter::SendKeyError(const char* session_id, uint32_t session_id_length, cdm::MediaKeyError error_code, uint32_t system_code) { - SendKeyErrorInternal(key_system_, - std::string(session_id, session_id_length), - error_code, - system_code); + std::string session_id_str(session_id, session_id_length); + uint32_t reference_id = cdm_->DetermineReferenceId(session_id_str); + + SendKeyErrorInternal(reference_id, error_code, system_code); } void CdmAdapter::GetPrivateData(int32_t* instance, @@ -551,41 +563,32 @@ void CdmAdapter::GetPrivateData(int32_t* instance, *get_interface = pp::Module::Get()->get_browser_interface(); } -void CdmAdapter::SendUnknownKeyError(const std::string& key_system, - const std::string& session_id) { - SendKeyErrorInternal(key_system, session_id, cdm::kUnknownError, 0); +void CdmAdapter::SendUnknownKeyError(uint32_t reference_id) { + SendKeyErrorInternal(reference_id, cdm::kUnknownError, 0); } -void CdmAdapter::SendKeyAdded(const std::string& key_system, - const std::string& session_id) { - PostOnMain(callback_factory_.NewCallback( - &CdmAdapter::KeyAdded, - SessionInfo(key_system_, session_id))); +void CdmAdapter::SendKeyAdded(uint32_t reference_id) { + PostOnMain( + callback_factory_.NewCallback(&CdmAdapter::KeyAdded, reference_id)); } -void CdmAdapter::SendKeyErrorInternal(const std::string& key_system, - const std::string& session_id, +void CdmAdapter::SendKeyErrorInternal(uint32_t reference_id, cdm::MediaKeyError error_code, uint32_t system_code) { - PostOnMain(callback_factory_.NewCallback(&CdmAdapter::KeyError, - SessionInfo(key_system_, session_id), - error_code, - system_code)); + PostOnMain(callback_factory_.NewCallback( + &CdmAdapter::KeyError, reference_id, error_code, system_code)); } -void CdmAdapter::KeyAdded(int32_t result, const SessionInfo& session_info) { +void CdmAdapter::KeyAdded(int32_t result, uint32_t reference_id) { PP_DCHECK(result == PP_OK); - PP_DCHECK(!session_info.key_system.empty()); - pp::ContentDecryptor_Private::KeyAdded(session_info.key_system, - session_info.session_id); + pp::ContentDecryptor_Private::KeyAdded(reference_id); } void CdmAdapter::KeyMessage(int32_t result, - const SessionInfo& session_info, + uint32_t reference_id, const std::vector<uint8>& message, const std::string& default_url) { PP_DCHECK(result == PP_OK); - PP_DCHECK(!session_info.key_system.empty()); pp::VarArrayBuffer message_array_buffer(message.size()); if (message.size() > 0) { @@ -593,18 +596,24 @@ void CdmAdapter::KeyMessage(int32_t result, } pp::ContentDecryptor_Private::KeyMessage( - session_info.key_system, session_info.session_id, - message_array_buffer, default_url); + reference_id, + message_array_buffer, + default_url); } void CdmAdapter::KeyError(int32_t result, - const SessionInfo& session_info, + uint32_t reference_id, cdm::MediaKeyError error_code, uint32_t system_code) { PP_DCHECK(result == PP_OK); - pp::ContentDecryptor_Private::KeyError( - session_info.key_system, session_info.session_id, - error_code, system_code); + pp::ContentDecryptor_Private::KeyError(reference_id, error_code, system_code); +} + +void CdmAdapter::SetSessionId(int32_t result, + uint32_t reference_id, + const std::string& session_id) { + PP_DCHECK(result == PP_OK); + pp::ContentDecryptor_Private::SetSessionId(reference_id, session_id); } void CdmAdapter::DeliverBlock(int32_t result, diff --git a/media/cdm/ppapi/cdm_adapter.h b/media/cdm/ppapi/cdm_adapter.h index 441dfe9..0542c5d 100644 --- a/media/cdm/ppapi/cdm_adapter.h +++ b/media/cdm/ppapi/cdm_adapter.h @@ -51,15 +51,14 @@ class CdmAdapter : public pp::Instance, // PPP_ContentDecryptor_Private implementation. // Note: Results of calls to these methods must be reported through the // PPB_ContentDecryptor_Private interface. - // TODO(jrummell): |can_challenge_platform| should be removed. - virtual void Initialize(const std::string& key_system, - bool can_challenge_platform) OVERRIDE; - virtual void GenerateKeyRequest(const std::string& type, + virtual void Initialize(const std::string& key_system) OVERRIDE; + virtual void GenerateKeyRequest(uint32_t reference_id, + const std::string& type, pp::VarArrayBuffer init_data) OVERRIDE; - virtual void AddKey(const std::string& session_id, + virtual void AddKey(uint32_t reference_id, pp::VarArrayBuffer key, pp::VarArrayBuffer init_data) OVERRIDE; - virtual void CancelKeyRequest(const std::string& session_id) OVERRIDE; + virtual void CancelKeyRequest(uint32_t reference_id) OVERRIDE; virtual void Decrypt( pp::Buffer_Dev encrypted_buffer, const PP_EncryptedBlockInfo& encrypted_block_info) OVERRIDE; @@ -105,45 +104,33 @@ class CdmAdapter : public pp::Instance, cdm::Status decoder_status) OVERRIDE; private: - struct SessionInfo { - SessionInfo(const std::string& key_system_in, - const std::string& session_id_in) - : key_system(key_system_in), - session_id(session_id_in) {} - const std::string key_system; - const std::string session_id; - }; - typedef linked_ptr<DecryptedBlockImpl> LinkedDecryptedBlock; typedef linked_ptr<VideoFrameImpl> LinkedVideoFrame; typedef linked_ptr<AudioFramesImpl> LinkedAudioFrames; bool CreateCdmInstance(const std::string& key_system); - void SendUnknownKeyError(const std::string& key_system, - const std::string& session_id); - - void SendKeyAdded(const std::string& key_system, - const std::string& session_id); - - // TODO(jrummell): Drop the |key_system| parameter. - void SendKeyErrorInternal(const std::string& key_system, - const std::string& session_id, + void SendUnknownKeyError(uint32_t reference_id); + void SendKeyAdded(uint32_t reference_id); + void SendKeyErrorInternal(uint32_t reference_id, cdm::MediaKeyError error_code, uint32_t system_code); // <code>PPB_ContentDecryptor_Private</code> dispatchers. These are passed to // <code>callback_factory_</code> to ensure that calls into // <code>PPP_ContentDecryptor_Private</code> are asynchronous. - void KeyAdded(int32_t result, const SessionInfo& session_info); + void KeyAdded(int32_t result, uint32_t reference_id); void KeyMessage(int32_t result, - const SessionInfo& session_info, + uint32_t reference_id, const std::vector<uint8>& message, const std::string& default_url); void KeyError(int32_t result, - const SessionInfo& session_info, + uint32_t reference_id, cdm::MediaKeyError error_code, uint32_t system_code); + void SetSessionId(int32_t result, + uint32_t reference_id, + const std::string& session_id); void DeliverBlock(int32_t result, const cdm::Status& status, const LinkedDecryptedBlock& decrypted_block, @@ -172,7 +159,6 @@ class CdmAdapter : public pp::Instance, bool IsValidVideoFrame(const LinkedVideoFrame& video_frame); - #if defined(OS_CHROMEOS) void SendPlatformChallengeDone(int32_t result); void EnableProtectionDone(int32_t result); diff --git a/media/cdm/ppapi/cdm_wrapper.h b/media/cdm/ppapi/cdm_wrapper.h index 166d89c..8d3003a 100644 --- a/media/cdm/ppapi/cdm_wrapper.h +++ b/media/cdm/ppapi/cdm_wrapper.h @@ -5,6 +5,10 @@ #ifndef MEDIA_CDM_PPAPI_CDM_WRAPPER_H_ #define MEDIA_CDM_PPAPI_CDM_WRAPPER_H_ +#include <map> +#include <queue> +#include <string> + #include "base/basictypes.h" #include "media/cdm/ppapi/api/content_decryption_module.h" #include "media/cdm/ppapi/cdm_helpers.h" @@ -31,6 +35,16 @@ namespace media { // (just a shim layer in most cases), everything is done in this header file. class CdmWrapper { public: + // CDM_1 and CDM_2 methods AddKey() and CancelKeyRequest() may require + // callbacks to fire. Use this enum to indicate the additional calls required. + // TODO(jrummell): Remove return value once CDM_1 and CDM_2 are no longer + // supported. + enum Result { + NO_ACTION, + CALL_KEY_ADDED, + CALL_KEY_ERROR + }; + static CdmWrapper* Create(const char* key_system, uint32_t key_system_size, GetCdmHostFunc get_cdm_host_func, @@ -38,18 +52,17 @@ class CdmWrapper { virtual ~CdmWrapper() {}; - virtual cdm::Status GenerateKeyRequest(const char* type, - uint32_t type_size, - const uint8_t* init_data, - uint32_t init_data_size) = 0; - virtual cdm::Status AddKey(const char* session_id, - uint32_t session_id_size, - const uint8_t* key, - uint32_t key_size, - const uint8_t* key_id, - uint32_t key_id_size) = 0; - virtual cdm::Status CancelKeyRequest(const char* session_id, - uint32_t session_id_size) = 0; + virtual void GenerateKeyRequest(uint32_t reference_id, + const char* type, + uint32_t type_size, + const uint8_t* init_data, + uint32_t init_data_size) = 0; + virtual Result AddKey(uint32_t reference_id, + const uint8_t* key, + uint32_t key_size, + const uint8_t* key_id, + uint32_t key_id_size) = 0; + virtual Result CancelKeyRequest(uint32_t reference_id) = 0; virtual void TimerExpired(void* context) = 0; virtual cdm::Status Decrypt(const cdm::InputBuffer& encrypted_buffer, cdm::DecryptedBlock* decrypted_buffer) = 0; @@ -71,8 +84,39 @@ class CdmWrapper { uint32_t link_mask, uint32_t output_protection_mask) = 0; + // ContentDecryptionModule_1 and ContentDecryptionModule_2 interface methods + // AddKey() and CancelKeyRequest() (older versions of Update() and Close(), + // respectively) pass in the session_id rather than the reference_id. As well, + // Host_1 and Host_2 callbacks SendKeyMessage() and SendKeyError() include the + // session ID, but the actual callbacks need the reference ID. + // + // The following functions maintain the reference_id <-> session_id mapping. + // These can be removed once _1 and _2 interfaces are no longer supported. + + // Determine the corresponding reference_id for |session_id|. + virtual uint32_t DetermineReferenceId(const std::string& session_id) = 0; + + // Determine the corresponding session_id for |reference_id|. + virtual const std::string LookupSessionId(uint32_t reference_id) = 0; + protected: - CdmWrapper() {}; + typedef std::map<uint32_t, std::string> SessionMap; + static const uint32_t kInvalidReferenceId = 0; + + CdmWrapper() : current_key_request_reference_id_(kInvalidReferenceId) {} + + // Map between session_id and reference_id. + SessionMap session_map_; + + // As the response from GenerateKeyRequest() may be synchronous or + // asynchronous, keep track of the current request during the call to handle + // synchronous responses or errors. If no response received, add this request + // to a queue and assume that the subsequent responses come back in the order + // issued. + // TODO(jrummell): Remove once all supported CDM host interfaces support + // reference_id. + uint32_t current_key_request_reference_id_; + std::queue<uint32_t> pending_key_request_reference_ids_; private: DISALLOW_COPY_AND_ASSIGN(CdmWrapper); @@ -102,26 +146,92 @@ class CdmWrapperImpl : public CdmWrapper { cdm_->Destroy(); } - virtual cdm::Status GenerateKeyRequest(const char* type, - uint32_t type_size, - const uint8_t* init_data, - uint32_t init_data_size) OVERRIDE { - return cdm_->GenerateKeyRequest(type, type_size, init_data, init_data_size); + // TODO(jrummell): In CDM_3 all key callbacks will use reference_id, so there + // is no need to keep track of the current/pending request IDs. As well, the + // definition for AddKey() and CancelKeyRequest() require the CDM to always + // send a response (success or error), so the callbacks are not required. + // Simplify the following 3 routines when CDM_3 is supported. + + virtual void GenerateKeyRequest(uint32_t reference_id, + const char* type, + uint32_t type_size, + const uint8_t* init_data, + uint32_t init_data_size) OVERRIDE { + // As it is possible for CDMs to reply synchronously during the call to + // GenerateKeyRequest(), keep track of |reference_id|. + current_key_request_reference_id_ = reference_id; + + cdm::Status status = + cdm_->GenerateKeyRequest(type, type_size, init_data, init_data_size); + PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); + if (status != cdm::kSuccess) { + // If GenerateKeyRequest() failed, no subsequent asynchronous replies + // will be sent. Verify that a response was sent synchronously. + PP_DCHECK(current_key_request_reference_id_ == kInvalidReferenceId); + current_key_request_reference_id_ = kInvalidReferenceId; + return; + } + + if (current_key_request_reference_id_) { + // If this request is still pending (SendKeyMessage() or SendKeyError() + // not called synchronously), add |reference_id| to the end of the queue. + // Without CDM support, it is impossible to match SendKeyMessage() + // (or SendKeyError()) responses to the |reference_id|. Doing the best + // we can by keeping track of this in a queue, and assuming the responses + // come back in order. + pending_key_request_reference_ids_.push(reference_id); + current_key_request_reference_id_ = kInvalidReferenceId; + } } - virtual cdm::Status AddKey(const char* session_id, - uint32_t session_id_size, - const uint8_t* key, - uint32_t key_size, - const uint8_t* key_id, - uint32_t key_id_size) OVERRIDE { - return cdm_->AddKey( - session_id, session_id_size, key, key_size, key_id, key_id_size); + virtual Result AddKey(uint32_t reference_id, + const uint8_t* key, + uint32_t key_size, + const uint8_t* key_id, + uint32_t key_id_size) OVERRIDE { + const std::string session_id = LookupSessionId(reference_id); + if (session_id.empty()) { + // Possible if AddKey() called before GenerateKeyRequest(). + return CALL_KEY_ERROR; + } + + cdm::Status status = cdm_->AddKey(session_id.data(), + session_id.size(), + key, + key_size, + key_id, + key_id_size); + PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); + if (status != cdm::kSuccess) { + // http://crbug.com/310345: CDMs should send a KeyError message if they + // return a failure, so no need to do it twice. Remove this once all CDMs + // have been updated. + return CALL_KEY_ERROR; + } + + return CALL_KEY_ADDED; } - virtual cdm::Status CancelKeyRequest(const char* session_id, - uint32_t session_id_size) OVERRIDE { - return cdm_->CancelKeyRequest(session_id, session_id_size); + virtual Result CancelKeyRequest(uint32_t reference_id) OVERRIDE { + const std::string session_id = LookupSessionId(reference_id); + if (session_id.empty()) { + // Possible if CancelKeyRequest() called before GenerateKeyRequest(). + return CALL_KEY_ERROR; + } + + session_map_.erase(reference_id); + cdm::Status status = + cdm_->CancelKeyRequest(session_id.data(), session_id.size()); + + PP_DCHECK(status == cdm::kSuccess || status == cdm::kSessionError); + if (status != cdm::kSuccess) { + // http://crbug.com/310345: CDMs should send a KeyError message if they + // return a failure, so no need to do it twice. Remove this once all CDMs + // have been updated. + return CALL_KEY_ERROR; + } + + return NO_ACTION; } virtual void TimerExpired(void* context) OVERRIDE { @@ -174,6 +284,45 @@ class CdmWrapperImpl : public CdmWrapper { cdm_->OnQueryOutputProtectionStatus(link_mask, output_protection_mask); } + uint32_t DetermineReferenceId(const std::string& session_id) { + for (SessionMap::iterator it = session_map_.begin(); + it != session_map_.end(); + ++it) { + if (it->second == session_id) + return it->first; + } + + // There is no entry in the map; assume it came from the current + // GenerateKeyRequest() call (if possible). If no current request, + // assume it came from the oldest GenerateKeyRequest() call. + uint32_t reference_id = current_key_request_reference_id_; + if (current_key_request_reference_id_) { + // Only 1 response is allowed for the current GenerateKeyRequest(). + current_key_request_reference_id_ = kInvalidReferenceId; + } else { + PP_DCHECK(!pending_key_request_reference_ids_.empty()); + reference_id = pending_key_request_reference_ids_.front(); + pending_key_request_reference_ids_.pop(); + } + + // If this is a valid |session_id|, add it to the list. Otherwise, avoid + // adding empty string as a mapping to prevent future calls with an empty + // string from using the wrong reference_id. + if (!session_id.empty()) { + PP_DCHECK(session_map_.find(reference_id) == session_map_.end()); + PP_DCHECK(!session_id.empty()); + session_map_[reference_id] = session_id; + } + + return reference_id; + } + + const std::string LookupSessionId(uint32_t reference_id) { + // Session may not exist if error happens during GenerateKeyRequest(). + SessionMap::iterator it = session_map_.find(reference_id); + return (it != session_map_.end()) ? it->second : std::string(); + } + private: CdmWrapperImpl(CdmInterface* cdm) : cdm_(cdm) { PP_DCHECK(cdm_); diff --git a/media/cdm/ppapi/clear_key_cdm.cc b/media/cdm/ppapi/clear_key_cdm.cc index 279e1ce..3728eff 100644 --- a/media/cdm/ppapi/clear_key_cdm.cc +++ b/media/cdm/ppapi/clear_key_cdm.cc @@ -153,42 +153,56 @@ const char* GetCdmVersion() { namespace media { -ClearKeyCdm::Client::Client() : status_(kKeyError) {} +// Since all the calls to AesDecryptor are synchronous, pass a dummy value for +// reference_id that is never exposed outside this class. +// TODO(jrummell): Remove usage of this when the CDM interface is updated +// to use reference_id. + +ClearKeyCdm::Client::Client() + : status_(kNone), error_code_(MediaKeys::kUnknownError), system_code_(0) {} ClearKeyCdm::Client::~Client() {} void ClearKeyCdm::Client::Reset() { - status_ = kKeyError; + status_ = kNone; session_id_.clear(); key_message_.clear(); default_url_.clear(); + error_code_ = MediaKeys::kUnknownError; + system_code_ = 0; } -void ClearKeyCdm::Client::KeyAdded(const std::string& session_id) { - status_ = kKeyAdded; - session_id_ = session_id; +void ClearKeyCdm::Client::KeyAdded(uint32 reference_id) { + status_ = static_cast<Status>(status_ | kKeyAdded); } -void ClearKeyCdm::Client::KeyError(const std::string& session_id, +void ClearKeyCdm::Client::KeyError(uint32 reference_id, media::MediaKeys::KeyError error_code, int system_code) { - status_ = kKeyError; - session_id_ = session_id; + status_ = static_cast<Status>(status_ | kKeyError); + error_code_ = error_code; + system_code_ = system_code; } -void ClearKeyCdm::Client::KeyMessage(const std::string& session_id, +void ClearKeyCdm::Client::KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url) { - status_ = kKeyMessage; - session_id_ = session_id; + status_ = static_cast<Status>(status_ | kKeyMessage); key_message_ = message; default_url_ = default_url; } +void ClearKeyCdm::Client::SetSessionId(uint32 reference_id, + const std::string& session_id) { + status_ = static_cast<Status>(status_ | kSetSessionId); + session_id_ = session_id; +} + ClearKeyCdm::ClearKeyCdm(ClearKeyCdmHost* host) : decryptor_(base::Bind(&Client::KeyAdded, base::Unretained(&client_)), base::Bind(&Client::KeyError, base::Unretained(&client_)), - base::Bind(&Client::KeyMessage, base::Unretained(&client_))), + base::Bind(&Client::KeyMessage, base::Unretained(&client_)), + base::Bind(&Client::SetSessionId, base::Unretained(&client_))), host_(host), timer_delay_ms_(kInitialTimerDelayMs), timer_set_(false) { @@ -210,11 +224,16 @@ cdm::Status ClearKeyCdm::GenerateKeyRequest(const char* type, DVLOG(1) << "GenerateKeyRequest()"; base::AutoLock auto_lock(client_lock_); ScopedResetter<Client> auto_resetter(&client_); - decryptor_.GenerateKeyRequest(std::string(type, type_size), + decryptor_.GenerateKeyRequest(MediaKeys::kInvalidReferenceId, + std::string(type, type_size), init_data, init_data_size); - if (client_.status() != Client::kKeyMessage) { - host_->SendKeyError(NULL, 0, cdm::kUnknownError, 0); + if (client_.status() != (Client::kKeyMessage | Client::kSetSessionId)) { + // Use values returned to client if possible. + host_->SendKeyError(client_.session_id().data(), + client_.session_id().size(), + static_cast<cdm::MediaKeyError>(client_.error_code()), + client_.system_code()); return cdm::kSessionError; } @@ -239,11 +258,16 @@ cdm::Status ClearKeyCdm::AddKey(const char* session_id, DVLOG(1) << "AddKey()"; base::AutoLock auto_lock(client_lock_); ScopedResetter<Client> auto_resetter(&client_); - decryptor_.AddKey(key, key_size, key_id, key_id_size, - std::string(session_id, session_id_size)); - - if (client_.status() != Client::kKeyAdded) + decryptor_.AddKey(MediaKeys::kInvalidReferenceId, + key, key_size, + key_id, key_id_size); + + if (client_.status() != Client::kKeyAdded) { + host_->SendKeyError(session_id, session_id_size, + static_cast<cdm::MediaKeyError>(client_.error_code()), + client_.system_code()); return cdm::kSessionError; + } if (!timer_set_) { ScheduleNextHeartBeat(); @@ -258,7 +282,17 @@ cdm::Status ClearKeyCdm::CancelKeyRequest(const char* session_id, DVLOG(1) << "CancelKeyRequest()"; base::AutoLock auto_lock(client_lock_); ScopedResetter<Client> auto_resetter(&client_); - decryptor_.CancelKeyRequest(std::string(session_id, session_id_size)); + decryptor_.CancelKeyRequest(MediaKeys::kInvalidReferenceId); + + // No message normally sent by CancelKeyRequest(), but if an error occurred, + // report it as a failure. + if (client_.status() == Client::kKeyError) { + host_->SendKeyError(session_id, session_id_size, + static_cast<cdm::MediaKeyError>(client_.error_code()), + client_.system_code()); + return cdm::kSessionError; + } + return cdm::kSuccess; } diff --git a/media/cdm/ppapi/clear_key_cdm.h b/media/cdm/ppapi/clear_key_cdm.h index 1da325d..c8d0703 100644 --- a/media/cdm/ppapi/clear_key_cdm.h +++ b/media/cdm/ppapi/clear_key_cdm.h @@ -71,10 +71,14 @@ class ClearKeyCdm : public ClearKeyCdmInterface { // this Client class as well. Investigate this possibility. class Client { public: + // TODO(jrummell): Remove bitmask and rename kNone to kInvalid once CDM + // interface supports reference_id passing completely. enum Status { - kKeyAdded, - kKeyError, - kKeyMessage + kNone = 0, + kKeyAdded = 1 << 0, + kKeyError = 1 << 1, + kKeyMessage = 1 << 2, + kSetSessionId = 1 << 3 }; Client(); @@ -84,23 +88,28 @@ class ClearKeyCdm : public ClearKeyCdmInterface { const std::string& session_id() { return session_id_; } const std::vector<uint8>& key_message() { return key_message_; } const std::string& default_url() { return default_url_; } + MediaKeys::KeyError error_code() { return error_code_; } + int system_code() { return system_code_; } // Resets the Client to a clean state. void Reset(); - void KeyAdded(const std::string& session_id); - void KeyError(const std::string& session_id, + void KeyAdded(uint32 reference_id); + void KeyError(uint32 reference_id, MediaKeys::KeyError error_code, int system_code); - void KeyMessage(const std::string& session_id, + void KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url); + void SetSessionId(uint32 reference_id, const std::string& session_id); private: Status status_; std::string session_id_; std::vector<uint8> key_message_; std::string default_url_; + MediaKeys::KeyError error_code_; + int system_code_; }; // Prepares next heartbeat message and sets a timer for it. diff --git a/media/filters/pipeline_integration_test.cc b/media/filters/pipeline_integration_test.cc index b92c37f..221e641 100644 --- a/media/filters/pipeline_integration_test.cc +++ b/media/filters/pipeline_integration_test.cc @@ -79,31 +79,34 @@ class FakeEncryptedMedia { public: virtual ~AppBase() {} - virtual void KeyAdded(const std::string& session_id) = 0; + virtual void KeyAdded(uint32 reference_id) = 0; // Errors are not expected unless overridden. - virtual void KeyError(const std::string& session_id, + virtual void KeyError(uint32 reference_id, MediaKeys::KeyError error_code, int system_code) { FAIL() << "Unexpected Key Error"; } - virtual void KeyMessage(const std::string& session_id, + virtual void KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url) = 0; + virtual void SetSession(uint32 reference_id, + const std::string& session_id) = 0; + virtual void NeedKey(const std::string& type, const std::vector<uint8>& init_data, AesDecryptor* decryptor) = 0; }; FakeEncryptedMedia(AppBase* app) - : decryptor_(base::Bind(&FakeEncryptedMedia::KeyAdded, - base::Unretained(this)), - base::Bind(&FakeEncryptedMedia::KeyError, - base::Unretained(this)), - base::Bind(&FakeEncryptedMedia::KeyMessage, - base::Unretained(this))), + : decryptor_( + base::Bind(&FakeEncryptedMedia::KeyAdded, base::Unretained(this)), + base::Bind(&FakeEncryptedMedia::KeyError, base::Unretained(this)), + base::Bind(&FakeEncryptedMedia::KeyMessage, base::Unretained(this)), + base::Bind(&FakeEncryptedMedia::SetSession, + base::Unretained(this))), app_(app) { } @@ -112,20 +115,24 @@ class FakeEncryptedMedia { } // Callbacks for firing key events. Delegate to |app_|. - void KeyAdded(const std::string& session_id) { - app_->KeyAdded(session_id); + void KeyAdded(uint32 reference_id) { + app_->KeyAdded(reference_id); } - void KeyError(const std::string& session_id, + void KeyError(uint32 reference_id, MediaKeys::KeyError error_code, int system_code) { - app_->KeyError(session_id, error_code, system_code); + app_->KeyError(reference_id, error_code, system_code); } - void KeyMessage(const std::string& session_id, + void KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url) { - app_->KeyMessage(session_id, message, default_url); + app_->KeyMessage(reference_id, message, default_url); + } + + void SetSession(uint32 reference_id, const std::string& session_id) { + app_->SetSession(reference_id, session_id); } void NeedKey(const std::string& type, @@ -141,28 +148,36 @@ class FakeEncryptedMedia { // Provides |kSecretKey| in response to needkey. class KeyProvidingApp : public FakeEncryptedMedia::AppBase { public: - virtual void KeyAdded(const std::string& session_id) OVERRIDE { - EXPECT_FALSE(session_id.empty()); + KeyProvidingApp() : current_reference_id_(0) {} + + virtual void KeyAdded(uint32 reference_id) OVERRIDE { + EXPECT_GT(reference_id, 0u); } - virtual void KeyMessage(const std::string& session_id, + virtual void KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url) OVERRIDE { - EXPECT_FALSE(session_id.empty()); + EXPECT_GT(reference_id, 0u); EXPECT_FALSE(message.empty()); - current_session_id_ = session_id; + current_reference_id_ = reference_id; + } + + virtual void SetSession(uint32 reference_id, + const std::string& session_id) OVERRIDE { + EXPECT_GT(reference_id, 0u); + EXPECT_FALSE(session_id.empty()); } virtual void NeedKey(const std::string& type, const std::vector<uint8>& init_data, AesDecryptor* decryptor) OVERRIDE { - if (current_session_id_.empty()) { - EXPECT_TRUE(decryptor->GenerateKeyRequest(type, kInitData, - arraysize(kInitData))); + if (current_reference_id_ == 0u) { + EXPECT_TRUE(decryptor->GenerateKeyRequest( + 12, type, kInitData, arraysize(kInitData))); } - EXPECT_FALSE(current_session_id_.empty()); + EXPECT_EQ(current_reference_id_, 12u); // Clear Key really needs the key ID in |init_data|. For WebM, they are the // same, but this is not the case for ISO CENC. Therefore, provide the @@ -174,29 +189,36 @@ class KeyProvidingApp : public FakeEncryptedMedia::AppBase { key_id_length = arraysize(kKeyId); } - decryptor->AddKey(kSecretKey, arraysize(kSecretKey), - key_id, key_id_length, current_session_id_); + decryptor->AddKey(current_reference_id_, + kSecretKey, arraysize(kSecretKey), + key_id, key_id_length); } - std::string current_session_id_; + uint32 current_reference_id_; }; // Ignores needkey and does not perform a license request class NoResponseApp : public FakeEncryptedMedia::AppBase { public: - virtual void KeyAdded(const std::string& session_id) OVERRIDE { - EXPECT_FALSE(session_id.empty()); + virtual void KeyAdded(uint32 reference_id) OVERRIDE { + EXPECT_GT(reference_id, 0u); FAIL() << "Unexpected KeyAdded"; } - virtual void KeyMessage(const std::string& session_id, + virtual void KeyMessage(uint32 reference_id, const std::vector<uint8>& message, const std::string& default_url) OVERRIDE { - EXPECT_FALSE(session_id.empty()); + EXPECT_GT(reference_id, 0u); EXPECT_FALSE(message.empty()); FAIL() << "Unexpected KeyMessage"; } + virtual void SetSession(uint32 reference_id, + const std::string& session_id) OVERRIDE { + EXPECT_GT(reference_id, 0u); + EXPECT_FALSE(session_id.empty()); + } + virtual void NeedKey(const std::string& type, const std::vector<uint8>& init_data, AesDecryptor* decryptor) OVERRIDE { diff --git a/ppapi/api/private/ppb_content_decryptor_private.idl b/ppapi/api/private/ppb_content_decryptor_private.idl index fbf4663..8577de2 100644 --- a/ppapi/api/private/ppb_content_decryptor_private.idl +++ b/ppapi/api/private/ppb_content_decryptor_private.idl @@ -12,7 +12,6 @@ [generate_thunk] label Chrome { - M31 = 0.7, M32 = 0.8 }; @@ -37,16 +36,12 @@ interface PPB_ContentDecryptor_Private { * The CDM must call <code>KeyAdded()</code> when the sequence is completed, * and, in response, the browser must notify the web application. * - * @param[in] key_system A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the name of the key system. - * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which a key + * was added. */ void KeyAdded( [in] PP_Instance instance, - [in] PP_Var key_system, - [in] PP_Var session_id); + [in] uint32_t reference_id); /** * A message or request has been generated for key_system in the CDM, and @@ -62,11 +57,8 @@ interface PPB_ContentDecryptor_Private { * <code>AddKey()</code> and <code>KeyMessage()</code> calls required to * prepare for decryption. * - * @param[in] key_system A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the name of the key system. - * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which the message + * is intended. * * @param[in] message A <code>PP_Var</code> of type * <code>PP_VARTYPE_ARRAY_BUFFER</code> that contains the message. @@ -76,8 +68,7 @@ interface PPB_ContentDecryptor_Private { */ void KeyMessage( [in] PP_Instance instance, - [in] PP_Var key_system, - [in] PP_Var session_id, + [in] uint32_t reference_id, [in] PP_Var message, [in] PP_Var default_url); @@ -85,11 +76,8 @@ interface PPB_ContentDecryptor_Private { * An error occurred in a <code>PPP_ContentDecryptor_Private</code> method, * or within the plugin implementing the interface. * - * @param[in] key_system A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the name of the key system. - * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which the error + * is intended. * * @param[in] media_error A MediaKeyError. * @@ -97,12 +85,26 @@ interface PPB_ContentDecryptor_Private { */ void KeyError( [in] PP_Instance instance, - [in] PP_Var key_system, - [in] PP_Var session_id, + [in] uint32_t reference_id, [in] int32_t media_error, [in] int32_t system_code); /** + * A session ID has been generated by the CDM for a session. + * + * @param[in] reference_id A reference for the session for which the session + * id is intended. + * + * @param[in] session_id A <code>PP_Var</code> of type + * <code>PP_VARTYPE_STRING</code> containing the session ID. + * + */ + void SetSessionId( + [in] PP_Instance instance, + [in] uint32_t reference_id, + [in] PP_Var session_id); + + /** * Called after the <code>Decrypt()</code> method on the * <code>PPP_ContentDecryptor_Private</code> interface completes to * deliver decrypted_block to the browser for decoding and rendering. diff --git a/ppapi/api/private/ppp_content_decryptor_private.idl b/ppapi/api/private/ppp_content_decryptor_private.idl index 5eba37a..0136ff0 100644 --- a/ppapi/api/private/ppp_content_decryptor_private.idl +++ b/ppapi/api/private/ppp_content_decryptor_private.idl @@ -9,7 +9,7 @@ * Decryption Modules, not normal plugins. */ label Chrome { - M31 = 0.7 + M32 = 0.8 }; /** @@ -25,15 +25,10 @@ interface PPP_ContentDecryptor_Private { * * @param[in] key_system A <code>PP_Var</code> of type * <code>PP_VARTYPE_STRING</code> containing the name of the key system. - * - * @param[in] can_challenge_platform A <code>PP_Bool</code> that - * indicates if the underlying host platform can be challenged; - * i.e., verified as a trusted platform. */ void Initialize( [in] PP_Instance instance, - [in] PP_Var key_system, - [in] PP_Bool can_challenge_platform); + [in] PP_Var key_system); /** * Generates a key request. key_system specifies the key or licensing system @@ -45,6 +40,9 @@ interface PPP_ContentDecryptor_Private { * browser by the CDM via <code>KeyMessage()</code> on the * <code>PPB_ContentDecryptor_Private</code> interface. * + * @param[in] reference_id A reference for the session for which the key + * should be generated. + * * @param[in] type A <code>PP_Var</code> of type * <code>PP_VARTYPE_STRING</code> containing the MIME type for init_data. * @@ -54,6 +52,7 @@ interface PPP_ContentDecryptor_Private { */ void GenerateKeyRequest( [in] PP_Instance instance, + [in] uint32_t reference_id, [in] PP_Var type, [in] PP_Var init_data); @@ -68,8 +67,8 @@ interface PPP_ContentDecryptor_Private { * <code>PPB_ContentDecryptor_Private</code> interface, and the browser * must notify the web application. * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which the key + * should be added. * * @param[in] key A <code>PP_Var</code> of type * <code>PP_VARTYPE_ARRAYBUFFER</code> containing the decryption key, license, @@ -81,19 +80,19 @@ interface PPP_ContentDecryptor_Private { */ void AddKey( [in] PP_Instance instance, - [in] PP_Var session_id, + [in] uint32_t reference_id, [in] PP_Var key, [in] PP_Var init_data); /** * Cancels a pending key request for the specified session ID. * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which the key + * request should be cancelled. */ void CancelKeyRequest( [in] PP_Instance instance, - [in] PP_Var session_id); + [in] uint32_t reference_id); /** * Decrypts the block and returns the unencrypted block via diff --git a/ppapi/c/private/ppb_content_decryptor_private.h b/ppapi/c/private/ppb_content_decryptor_private.h index 5e3d1aa..72bd457 100644 --- a/ppapi/c/private/ppb_content_decryptor_private.h +++ b/ppapi/c/private/ppb_content_decryptor_private.h @@ -4,7 +4,7 @@ */ /* From private/ppb_content_decryptor_private.idl, - * modified Thu Oct 10 14:49:51 2013. + * modified Mon Oct 21 17:11:33 2013. */ #ifndef PPAPI_C_PRIVATE_PPB_CONTENT_DECRYPTOR_PRIVATE_H_ @@ -18,10 +18,10 @@ #include "ppapi/c/pp_var.h" #include "ppapi/c/private/pp_content_decryptor.h" -#define PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_7 \ - "PPB_ContentDecryptor_Private;0.7" +#define PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_8 \ + "PPB_ContentDecryptor_Private;0.8" #define PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE \ - PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_7 + PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_8 /** * @file @@ -42,7 +42,7 @@ * browser side support for the Content Decryption Module (CDM) for v0.1 of the * proposed Encrypted Media Extensions: http://goo.gl/rbdnR */ -struct PPB_ContentDecryptor_Private_0_7 { +struct PPB_ContentDecryptor_Private_0_8 { /** * A key has been added as the result of a call to the <code>AddKey()</code> * method on the <code>PPP_ContentDecryptor_Private</code> interface. @@ -56,15 +56,10 @@ struct PPB_ContentDecryptor_Private_0_7 { * The CDM must call <code>KeyAdded()</code> when the sequence is completed, * and, in response, the browser must notify the web application. * - * @param[in] key_system A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the name of the key system. - * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which a key + * was added. */ - void (*KeyAdded)(PP_Instance instance, - struct PP_Var key_system, - struct PP_Var session_id); + void (*KeyAdded)(PP_Instance instance, uint32_t reference_id); /** * A message or request has been generated for key_system in the CDM, and * must be sent to the web application. @@ -79,11 +74,8 @@ struct PPB_ContentDecryptor_Private_0_7 { * <code>AddKey()</code> and <code>KeyMessage()</code> calls required to * prepare for decryption. * - * @param[in] key_system A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the name of the key system. - * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which the message + * is intended. * * @param[in] message A <code>PP_Var</code> of type * <code>PP_VARTYPE_ARRAY_BUFFER</code> that contains the message. @@ -92,30 +84,38 @@ struct PPB_ContentDecryptor_Private_0_7 { * <code>PP_VARTYPE_STRING</code> containing the default URL for the message. */ void (*KeyMessage)(PP_Instance instance, - struct PP_Var key_system, - struct PP_Var session_id, + uint32_t reference_id, struct PP_Var message, struct PP_Var default_url); /** * An error occurred in a <code>PPP_ContentDecryptor_Private</code> method, * or within the plugin implementing the interface. * - * @param[in] key_system A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the name of the key system. - * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which the error + * is intended. * * @param[in] media_error A MediaKeyError. * * @param[in] system_error A system error code. */ void (*KeyError)(PP_Instance instance, - struct PP_Var key_system, - struct PP_Var session_id, + uint32_t reference_id, int32_t media_error, int32_t system_code); /** + * A session ID has been generated by the CDM for a session. + * + * @param[in] reference_id A reference for the session for which the session + * id is intended. + * + * @param[in] session_id A <code>PP_Var</code> of type + * <code>PP_VARTYPE_STRING</code> containing the session ID. + * + */ + void (*SetSessionId)(PP_Instance instance, + uint32_t reference_id, + struct PP_Var session_id); + /** * Called after the <code>Decrypt()</code> method on the * <code>PPP_ContentDecryptor_Private</code> interface completes to * deliver decrypted_block to the browser for decoding and rendering. @@ -244,7 +244,7 @@ struct PPB_ContentDecryptor_Private_0_7 { const struct PP_DecryptedSampleInfo* decrypted_sample_info); }; -typedef struct PPB_ContentDecryptor_Private_0_7 PPB_ContentDecryptor_Private; +typedef struct PPB_ContentDecryptor_Private_0_8 PPB_ContentDecryptor_Private; /** * @} */ diff --git a/ppapi/c/private/ppp_content_decryptor_private.h b/ppapi/c/private/ppp_content_decryptor_private.h index 69763df..97ecf0d 100644 --- a/ppapi/c/private/ppp_content_decryptor_private.h +++ b/ppapi/c/private/ppp_content_decryptor_private.h @@ -4,7 +4,7 @@ */ /* From private/ppp_content_decryptor_private.idl, - * modified Wed Sep 18 16:14:30 2013. + * modified Fri Oct 18 18:11:09 2013. */ #ifndef PPAPI_C_PRIVATE_PPP_CONTENT_DECRYPTOR_PRIVATE_H_ @@ -18,10 +18,10 @@ #include "ppapi/c/pp_var.h" #include "ppapi/c/private/pp_content_decryptor.h" -#define PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_7 \ - "PPP_ContentDecryptor_Private;0.7" +#define PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_8 \ + "PPP_ContentDecryptor_Private;0.8" #define PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE \ - PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_7 + PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_8 /** * @file @@ -42,20 +42,14 @@ * Decryption Module (CDM) for v0.1 of the proposed Encrypted Media Extensions: * http://goo.gl/rbdnR */ -struct PPP_ContentDecryptor_Private_0_7 { +struct PPP_ContentDecryptor_Private_0_8 { /** * Initialize for the specified key system. * * @param[in] key_system A <code>PP_Var</code> of type * <code>PP_VARTYPE_STRING</code> containing the name of the key system. - * - * @param[in] can_challenge_platform A <code>PP_Bool</code> that - * indicates if the underlying host platform can be challenged; - * i.e., verified as a trusted platform. */ - void (*Initialize)(PP_Instance instance, - struct PP_Var key_system, - PP_Bool can_challenge_platform); + void (*Initialize)(PP_Instance instance, struct PP_Var key_system); /** * Generates a key request. key_system specifies the key or licensing system * to use. type contains the MIME type of init_data. init_data is a data @@ -66,6 +60,9 @@ struct PPP_ContentDecryptor_Private_0_7 { * browser by the CDM via <code>KeyMessage()</code> on the * <code>PPB_ContentDecryptor_Private</code> interface. * + * @param[in] reference_id A reference for the session for which the key + * should be generated. + * * @param[in] type A <code>PP_Var</code> of type * <code>PP_VARTYPE_STRING</code> containing the MIME type for init_data. * @@ -74,6 +71,7 @@ struct PPP_ContentDecryptor_Private_0_7 { * initialization data. */ void (*GenerateKeyRequest)(PP_Instance instance, + uint32_t reference_id, struct PP_Var type, struct PP_Var init_data); /** @@ -87,8 +85,8 @@ struct PPP_ContentDecryptor_Private_0_7 { * <code>PPB_ContentDecryptor_Private</code> interface, and the browser * must notify the web application. * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which the key + * should be added. * * @param[in] key A <code>PP_Var</code> of type * <code>PP_VARTYPE_ARRAYBUFFER</code> containing the decryption key, license, @@ -99,16 +97,16 @@ struct PPP_ContentDecryptor_Private_0_7 { * initialization data. */ void (*AddKey)(PP_Instance instance, - struct PP_Var session_id, + uint32_t reference_id, struct PP_Var key, struct PP_Var init_data); /** * Cancels a pending key request for the specified session ID. * - * @param[in] session_id A <code>PP_Var</code> of type - * <code>PP_VARTYPE_STRING</code> containing the session ID. + * @param[in] reference_id A reference for the session for which the key + * request should be cancelled. */ - void (*CancelKeyRequest)(PP_Instance instance, struct PP_Var session_id); + void (*CancelKeyRequest)(PP_Instance instance, uint32_t reference_id); /** * Decrypts the block and returns the unencrypted block via * <code>DeliverBlock()</code> on the @@ -235,7 +233,7 @@ struct PPP_ContentDecryptor_Private_0_7 { const struct PP_EncryptedBlockInfo* encrypted_block_info); }; -typedef struct PPP_ContentDecryptor_Private_0_7 PPP_ContentDecryptor_Private; +typedef struct PPP_ContentDecryptor_Private_0_8 PPP_ContentDecryptor_Private; /** * @} */ diff --git a/ppapi/cpp/private/content_decryptor_private.cc b/ppapi/cpp/private/content_decryptor_private.cc index 8c7dcd2..905b115 100644 --- a/ppapi/cpp/private/content_decryptor_private.cc +++ b/ppapi/cpp/private/content_decryptor_private.cc @@ -24,8 +24,7 @@ static const char kPPPContentDecryptorInterface[] = PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE; void Initialize(PP_Instance instance, - PP_Var key_system_arg, - PP_Bool can_challenge_platform) { + PP_Var key_system_arg) { void* object = Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); if (!object) @@ -36,11 +35,11 @@ void Initialize(PP_Instance instance, return; static_cast<ContentDecryptor_Private*>(object)->Initialize( - key_system_var.AsString(), - PP_ToBool(can_challenge_platform)); + key_system_var.AsString()); } void GenerateKeyRequest(PP_Instance instance, + uint32_t reference_id, PP_Var type_arg, PP_Var init_data_arg) { void* object = @@ -58,12 +57,13 @@ void GenerateKeyRequest(PP_Instance instance, pp::VarArrayBuffer init_data_array_buffer(init_data_var); static_cast<ContentDecryptor_Private*>(object)->GenerateKeyRequest( + reference_id, type_var.AsString(), init_data_array_buffer); } void AddKey(PP_Instance instance, - PP_Var session_id_arg, + uint32_t reference_id, PP_Var key_arg, PP_Var init_data_arg) { void* object = @@ -71,10 +71,6 @@ void AddKey(PP_Instance instance, if (!object) return; - pp::Var session_id_var(pp::PASS_REF, session_id_arg); - if (!session_id_var.is_string()) - return; - pp::Var key_var(pp::PASS_REF, key_arg); if (!key_var.is_array_buffer()) return; @@ -85,25 +81,20 @@ void AddKey(PP_Instance instance, return; pp::VarArrayBuffer init_data(init_data_var); - static_cast<ContentDecryptor_Private*>(object)->AddKey( - session_id_var.AsString(), + reference_id, key, init_data); } -void CancelKeyRequest(PP_Instance instance, PP_Var session_id_arg) { +void CancelKeyRequest(PP_Instance instance, uint32_t reference_id) { void* object = Instance::GetPerInstanceObject(instance, kPPPContentDecryptorInterface); if (!object) return; - pp::Var session_id_var(pp::PASS_REF, session_id_arg); - if (!session_id_var.is_string()) - return; - static_cast<ContentDecryptor_Private*>(object)->CancelKeyRequest( - session_id_var.AsString()); + reference_id); } @@ -226,51 +217,50 @@ ContentDecryptor_Private::~ContentDecryptor_Private() { this); } -void ContentDecryptor_Private::KeyAdded(const std::string& key_system, - const std::string& session_id) { +void ContentDecryptor_Private::KeyAdded(uint32_t reference_id) { if (has_interface<PPB_ContentDecryptor_Private>()) { - pp::Var key_system_var(key_system); - pp::Var session_id_var(session_id); get_interface<PPB_ContentDecryptor_Private>()->KeyAdded( associated_instance_.pp_instance(), - key_system_var.pp_var(), - session_id_var.pp_var()); + reference_id); } } -void ContentDecryptor_Private::KeyMessage(const std::string& key_system, - const std::string& session_id, +void ContentDecryptor_Private::KeyMessage(uint32_t reference_id, pp::VarArrayBuffer message, const std::string& default_url) { if (has_interface<PPB_ContentDecryptor_Private>()) { - pp::Var key_system_var(key_system); - pp::Var session_id_var(session_id); pp::Var default_url_var(default_url); get_interface<PPB_ContentDecryptor_Private>()->KeyMessage( associated_instance_.pp_instance(), - key_system_var.pp_var(), - session_id_var.pp_var(), + reference_id, message.pp_var(), default_url_var.pp_var()); } } -void ContentDecryptor_Private::KeyError(const std::string& key_system, - const std::string& session_id, +void ContentDecryptor_Private::KeyError(uint32_t reference_id, int32_t media_error, int32_t system_code) { if (has_interface<PPB_ContentDecryptor_Private>()) { - pp::Var key_system_var(key_system); - pp::Var session_id_var(session_id); get_interface<PPB_ContentDecryptor_Private>()->KeyError( associated_instance_.pp_instance(), - key_system_var.pp_var(), - session_id_var.pp_var(), + reference_id, media_error, system_code); } } +void ContentDecryptor_Private::SetSessionId(uint32_t reference_id, + const std::string& session_id) { + if (has_interface<PPB_ContentDecryptor_Private>()) { + pp::Var session_id_var(session_id); + get_interface<PPB_ContentDecryptor_Private>()->SetSessionId( + associated_instance_.pp_instance(), + reference_id, + session_id_var.pp_var()); + } +} + void ContentDecryptor_Private::DeliverBlock( pp::Buffer_Dev decrypted_block, const PP_DecryptedBlockInfo& decrypted_block_info) { diff --git a/ppapi/cpp/private/content_decryptor_private.h b/ppapi/cpp/private/content_decryptor_private.h index ff98569..e8a93dc 100644 --- a/ppapi/cpp/private/content_decryptor_private.h +++ b/ppapi/cpp/private/content_decryptor_private.h @@ -31,14 +31,14 @@ class ContentDecryptor_Private { // TODO(tomfinegan): This could be optimized to pass pp::Var instead of // strings. The change would allow the CDM wrapper to reuse vars when // replying to the browser. - virtual void Initialize(const std::string& key_system, - bool can_challenge_platform) = 0; - virtual void GenerateKeyRequest(const std::string& type, + virtual void Initialize(const std::string& key_system) = 0; + virtual void GenerateKeyRequest(uint32_t reference_id, + const std::string& type, pp::VarArrayBuffer init_data) = 0; - virtual void AddKey(const std::string& session_id, + virtual void AddKey(uint32_t reference_id, pp::VarArrayBuffer key, pp::VarArrayBuffer init_data) = 0; - virtual void CancelKeyRequest(const std::string& session_id) = 0; + virtual void CancelKeyRequest(uint32_t reference_id) = 0; virtual void Decrypt(pp::Buffer_Dev encrypted_buffer, const PP_EncryptedBlockInfo& encrypted_block_info) = 0; virtual void InitializeAudioDecoder( @@ -59,16 +59,14 @@ class ContentDecryptor_Private { // PPB_ContentDecryptor_Private methods for passing data from the decryptor // to the browser. - void KeyAdded(const std::string& key_system, - const std::string& session_id); - void KeyMessage(const std::string& key_system, - const std::string& session_id, + void KeyAdded(uint32_t reference_id); + void KeyMessage(uint32_t reference_id, pp::VarArrayBuffer message, const std::string& default_url); - void KeyError(const std::string& key_system, - const std::string& session_id, + void KeyError(uint32_t reference_id, int32_t media_error, int32_t system_code); + void SetSessionId(uint32_t reference_id, const std::string& session_id); // The plugin must not hold a reference to the encrypted buffer resource // provided to Decrypt() when it calls this method. The browser will reuse diff --git a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c index bb65441..98175e8 100644 --- a/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c +++ b/ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c @@ -198,7 +198,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_2; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDecoder_Dev_0_16; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Selection_Dev_0_3; -static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Ext_CrxFileSystem_Private_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileIO_Private_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_FileRefPrivate_0_1; @@ -234,7 +234,7 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_UMA_Private_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoDestination_Private_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_VideoSource_Private_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_X509Certificate_Private_0_1; -static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7; +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Instance_Private_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Ext_Alarms_Dev_0_1; static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_Ext_Events_Dev_0_1; @@ -2483,54 +2483,59 @@ static struct PP_Var Pnacl_M13_PPP_Selection_Dev_GetSelectedText(PP_Instance ins /* Not generating wrapper methods for PPP_Zoom_Dev_0_3 */ -/* Begin wrapper methods for PPB_ContentDecryptor_Private_0_7 */ +/* Begin wrapper methods for PPB_ContentDecryptor_Private_0_8 */ -static void Pnacl_M31_PPB_ContentDecryptor_Private_KeyAdded(PP_Instance instance, struct PP_Var* key_system, struct PP_Var* session_id) { - const struct PPB_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7.real_iface; - iface->KeyAdded(instance, *key_system, *session_id); +static void Pnacl_M32_PPB_ContentDecryptor_Private_KeyAdded(PP_Instance instance, uint32_t reference_id) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; + iface->KeyAdded(instance, reference_id); } -static void Pnacl_M31_PPB_ContentDecryptor_Private_KeyMessage(PP_Instance instance, struct PP_Var* key_system, struct PP_Var* session_id, struct PP_Var* message, struct PP_Var* default_url) { - const struct PPB_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7.real_iface; - iface->KeyMessage(instance, *key_system, *session_id, *message, *default_url); +static void Pnacl_M32_PPB_ContentDecryptor_Private_KeyMessage(PP_Instance instance, uint32_t reference_id, struct PP_Var* message, struct PP_Var* default_url) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; + iface->KeyMessage(instance, reference_id, *message, *default_url); } -static void Pnacl_M31_PPB_ContentDecryptor_Private_KeyError(PP_Instance instance, struct PP_Var* key_system, struct PP_Var* session_id, int32_t media_error, int32_t system_code) { - const struct PPB_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7.real_iface; - iface->KeyError(instance, *key_system, *session_id, media_error, system_code); +static void Pnacl_M32_PPB_ContentDecryptor_Private_KeyError(PP_Instance instance, uint32_t reference_id, int32_t media_error, int32_t system_code) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; + iface->KeyError(instance, reference_id, media_error, system_code); } -static void Pnacl_M31_PPB_ContentDecryptor_Private_DeliverBlock(PP_Instance instance, PP_Resource decrypted_block, const struct PP_DecryptedBlockInfo* decrypted_block_info) { - const struct PPB_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPB_ContentDecryptor_Private_SetSessionId(PP_Instance instance, uint32_t reference_id, struct PP_Var* session_id) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; + iface->SetSessionId(instance, reference_id, *session_id); +} + +static void Pnacl_M32_PPB_ContentDecryptor_Private_DeliverBlock(PP_Instance instance, PP_Resource decrypted_block, const struct PP_DecryptedBlockInfo* decrypted_block_info) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; iface->DeliverBlock(instance, decrypted_block, decrypted_block_info); } -static void Pnacl_M31_PPB_ContentDecryptor_Private_DecoderInitializeDone(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id, PP_Bool success) { - const struct PPB_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPB_ContentDecryptor_Private_DecoderInitializeDone(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id, PP_Bool success) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; iface->DecoderInitializeDone(instance, decoder_type, request_id, success); } -static void Pnacl_M31_PPB_ContentDecryptor_Private_DecoderDeinitializeDone(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) { - const struct PPB_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPB_ContentDecryptor_Private_DecoderDeinitializeDone(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; iface->DecoderDeinitializeDone(instance, decoder_type, request_id); } -static void Pnacl_M31_PPB_ContentDecryptor_Private_DecoderResetDone(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) { - const struct PPB_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPB_ContentDecryptor_Private_DecoderResetDone(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; iface->DecoderResetDone(instance, decoder_type, request_id); } -static void Pnacl_M31_PPB_ContentDecryptor_Private_DeliverFrame(PP_Instance instance, PP_Resource decrypted_frame, const struct PP_DecryptedFrameInfo* decrypted_frame_info) { - const struct PPB_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPB_ContentDecryptor_Private_DeliverFrame(PP_Instance instance, PP_Resource decrypted_frame, const struct PP_DecryptedFrameInfo* decrypted_frame_info) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; iface->DeliverFrame(instance, decrypted_frame, decrypted_frame_info); } -static void Pnacl_M31_PPB_ContentDecryptor_Private_DeliverSamples(PP_Instance instance, PP_Resource audio_frames, const struct PP_DecryptedSampleInfo* decrypted_sample_info) { - const struct PPB_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPB_ContentDecryptor_Private_DeliverSamples(PP_Instance instance, PP_Resource audio_frames, const struct PP_DecryptedSampleInfo* decrypted_sample_info) { + const struct PPB_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8.real_iface; iface->DeliverSamples(instance, audio_frames, decrypted_sample_info); } -/* End wrapper methods for PPB_ContentDecryptor_Private_0_7 */ +/* End wrapper methods for PPB_ContentDecryptor_Private_0_8 */ /* Begin wrapper methods for PPB_Ext_CrxFileSystem_Private_0_1 */ @@ -3812,79 +3817,79 @@ static void Pnacl_M19_PPB_X509Certificate_Private_GetField(struct PP_Var* _struc /* End wrapper methods for PPB_X509Certificate_Private_0_1 */ -/* Begin wrapper methods for PPP_ContentDecryptor_Private_0_7 */ +/* Begin wrapper methods for PPP_ContentDecryptor_Private_0_8 */ -static void Pnacl_M31_PPP_ContentDecryptor_Private_Initialize(PP_Instance instance, struct PP_Var key_system, PP_Bool can_challenge_platform) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; - void (*temp_fp)(PP_Instance instance, struct PP_Var* key_system, PP_Bool can_challenge_platform) = - ((void (*)(PP_Instance instance, struct PP_Var* key_system, PP_Bool can_challenge_platform))iface->Initialize); - temp_fp(instance, &key_system, can_challenge_platform); +static void Pnacl_M32_PPP_ContentDecryptor_Private_Initialize(PP_Instance instance, struct PP_Var key_system) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; + void (*temp_fp)(PP_Instance instance, struct PP_Var* key_system) = + ((void (*)(PP_Instance instance, struct PP_Var* key_system))iface->Initialize); + temp_fp(instance, &key_system); } -static void Pnacl_M31_PPP_ContentDecryptor_Private_GenerateKeyRequest(PP_Instance instance, struct PP_Var type, struct PP_Var init_data) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; - void (*temp_fp)(PP_Instance instance, struct PP_Var* type, struct PP_Var* init_data) = - ((void (*)(PP_Instance instance, struct PP_Var* type, struct PP_Var* init_data))iface->GenerateKeyRequest); - temp_fp(instance, &type, &init_data); +static void Pnacl_M32_PPP_ContentDecryptor_Private_GenerateKeyRequest(PP_Instance instance, uint32_t reference_id, struct PP_Var type, struct PP_Var init_data) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; + void (*temp_fp)(PP_Instance instance, uint32_t reference_id, struct PP_Var* type, struct PP_Var* init_data) = + ((void (*)(PP_Instance instance, uint32_t reference_id, struct PP_Var* type, struct PP_Var* init_data))iface->GenerateKeyRequest); + temp_fp(instance, reference_id, &type, &init_data); } -static void Pnacl_M31_PPP_ContentDecryptor_Private_AddKey(PP_Instance instance, struct PP_Var session_id, struct PP_Var key, struct PP_Var init_data) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; - void (*temp_fp)(PP_Instance instance, struct PP_Var* session_id, struct PP_Var* key, struct PP_Var* init_data) = - ((void (*)(PP_Instance instance, struct PP_Var* session_id, struct PP_Var* key, struct PP_Var* init_data))iface->AddKey); - temp_fp(instance, &session_id, &key, &init_data); +static void Pnacl_M32_PPP_ContentDecryptor_Private_AddKey(PP_Instance instance, uint32_t reference_id, struct PP_Var key, struct PP_Var init_data) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; + void (*temp_fp)(PP_Instance instance, uint32_t reference_id, struct PP_Var* key, struct PP_Var* init_data) = + ((void (*)(PP_Instance instance, uint32_t reference_id, struct PP_Var* key, struct PP_Var* init_data))iface->AddKey); + temp_fp(instance, reference_id, &key, &init_data); } -static void Pnacl_M31_PPP_ContentDecryptor_Private_CancelKeyRequest(PP_Instance instance, struct PP_Var session_id) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; - void (*temp_fp)(PP_Instance instance, struct PP_Var* session_id) = - ((void (*)(PP_Instance instance, struct PP_Var* session_id))iface->CancelKeyRequest); - temp_fp(instance, &session_id); +static void Pnacl_M32_PPP_ContentDecryptor_Private_CancelKeyRequest(PP_Instance instance, uint32_t reference_id) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; + void (*temp_fp)(PP_Instance instance, uint32_t reference_id) = + ((void (*)(PP_Instance instance, uint32_t reference_id))iface->CancelKeyRequest); + temp_fp(instance, reference_id); } -static void Pnacl_M31_PPP_ContentDecryptor_Private_Decrypt(PP_Instance instance, PP_Resource encrypted_block, const struct PP_EncryptedBlockInfo* encrypted_block_info) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPP_ContentDecryptor_Private_Decrypt(PP_Instance instance, PP_Resource encrypted_block, const struct PP_EncryptedBlockInfo* encrypted_block_info) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; void (*temp_fp)(PP_Instance instance, PP_Resource encrypted_block, const struct PP_EncryptedBlockInfo* encrypted_block_info) = ((void (*)(PP_Instance instance, PP_Resource encrypted_block, const struct PP_EncryptedBlockInfo* encrypted_block_info))iface->Decrypt); temp_fp(instance, encrypted_block, encrypted_block_info); } -static void Pnacl_M31_PPP_ContentDecryptor_Private_InitializeAudioDecoder(PP_Instance instance, const struct PP_AudioDecoderConfig* decoder_config, PP_Resource codec_extra_data) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPP_ContentDecryptor_Private_InitializeAudioDecoder(PP_Instance instance, const struct PP_AudioDecoderConfig* decoder_config, PP_Resource codec_extra_data) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; void (*temp_fp)(PP_Instance instance, const struct PP_AudioDecoderConfig* decoder_config, PP_Resource codec_extra_data) = ((void (*)(PP_Instance instance, const struct PP_AudioDecoderConfig* decoder_config, PP_Resource codec_extra_data))iface->InitializeAudioDecoder); temp_fp(instance, decoder_config, codec_extra_data); } -static void Pnacl_M31_PPP_ContentDecryptor_Private_InitializeVideoDecoder(PP_Instance instance, const struct PP_VideoDecoderConfig* decoder_config, PP_Resource codec_extra_data) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPP_ContentDecryptor_Private_InitializeVideoDecoder(PP_Instance instance, const struct PP_VideoDecoderConfig* decoder_config, PP_Resource codec_extra_data) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; void (*temp_fp)(PP_Instance instance, const struct PP_VideoDecoderConfig* decoder_config, PP_Resource codec_extra_data) = ((void (*)(PP_Instance instance, const struct PP_VideoDecoderConfig* decoder_config, PP_Resource codec_extra_data))iface->InitializeVideoDecoder); temp_fp(instance, decoder_config, codec_extra_data); } -static void Pnacl_M31_PPP_ContentDecryptor_Private_DeinitializeDecoder(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPP_ContentDecryptor_Private_DeinitializeDecoder(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; void (*temp_fp)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) = ((void (*)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id))iface->DeinitializeDecoder); temp_fp(instance, decoder_type, request_id); } -static void Pnacl_M31_PPP_ContentDecryptor_Private_ResetDecoder(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPP_ContentDecryptor_Private_ResetDecoder(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; void (*temp_fp)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id) = ((void (*)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id))iface->ResetDecoder); temp_fp(instance, decoder_type, request_id); } -static void Pnacl_M31_PPP_ContentDecryptor_Private_DecryptAndDecode(PP_Instance instance, PP_DecryptorStreamType decoder_type, PP_Resource encrypted_buffer, const struct PP_EncryptedBlockInfo* encrypted_block_info) { - const struct PPP_ContentDecryptor_Private_0_7 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7.real_iface; +static void Pnacl_M32_PPP_ContentDecryptor_Private_DecryptAndDecode(PP_Instance instance, PP_DecryptorStreamType decoder_type, PP_Resource encrypted_buffer, const struct PP_EncryptedBlockInfo* encrypted_block_info) { + const struct PPP_ContentDecryptor_Private_0_8 *iface = Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8.real_iface; void (*temp_fp)(PP_Instance instance, PP_DecryptorStreamType decoder_type, PP_Resource encrypted_buffer, const struct PP_EncryptedBlockInfo* encrypted_block_info) = ((void (*)(PP_Instance instance, PP_DecryptorStreamType decoder_type, PP_Resource encrypted_buffer, const struct PP_EncryptedBlockInfo* encrypted_block_info))iface->DecryptAndDecode); temp_fp(instance, decoder_type, encrypted_buffer, encrypted_block_info); } -/* End wrapper methods for PPP_ContentDecryptor_Private_0_7 */ +/* End wrapper methods for PPP_ContentDecryptor_Private_0_8 */ /* Not generating wrapper methods for PPP_Flash_BrowserOperations_1_0 */ @@ -4797,16 +4802,17 @@ struct PPP_Selection_Dev_0_3 Pnacl_Wrappers_PPP_Selection_Dev_0_3 = { /* Not generating wrapper interface for PPP_Zoom_Dev_0_3 */ -struct PPB_ContentDecryptor_Private_0_7 Pnacl_Wrappers_PPB_ContentDecryptor_Private_0_7 = { - .KeyAdded = (void (*)(PP_Instance instance, struct PP_Var key_system, struct PP_Var session_id))&Pnacl_M31_PPB_ContentDecryptor_Private_KeyAdded, - .KeyMessage = (void (*)(PP_Instance instance, struct PP_Var key_system, struct PP_Var session_id, struct PP_Var message, struct PP_Var default_url))&Pnacl_M31_PPB_ContentDecryptor_Private_KeyMessage, - .KeyError = (void (*)(PP_Instance instance, struct PP_Var key_system, struct PP_Var session_id, int32_t media_error, int32_t system_code))&Pnacl_M31_PPB_ContentDecryptor_Private_KeyError, - .DeliverBlock = (void (*)(PP_Instance instance, PP_Resource decrypted_block, const struct PP_DecryptedBlockInfo* decrypted_block_info))&Pnacl_M31_PPB_ContentDecryptor_Private_DeliverBlock, - .DecoderInitializeDone = (void (*)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id, PP_Bool success))&Pnacl_M31_PPB_ContentDecryptor_Private_DecoderInitializeDone, - .DecoderDeinitializeDone = (void (*)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id))&Pnacl_M31_PPB_ContentDecryptor_Private_DecoderDeinitializeDone, - .DecoderResetDone = (void (*)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id))&Pnacl_M31_PPB_ContentDecryptor_Private_DecoderResetDone, - .DeliverFrame = (void (*)(PP_Instance instance, PP_Resource decrypted_frame, const struct PP_DecryptedFrameInfo* decrypted_frame_info))&Pnacl_M31_PPB_ContentDecryptor_Private_DeliverFrame, - .DeliverSamples = (void (*)(PP_Instance instance, PP_Resource audio_frames, const struct PP_DecryptedSampleInfo* decrypted_sample_info))&Pnacl_M31_PPB_ContentDecryptor_Private_DeliverSamples +struct PPB_ContentDecryptor_Private_0_8 Pnacl_Wrappers_PPB_ContentDecryptor_Private_0_8 = { + .KeyAdded = (void (*)(PP_Instance instance, uint32_t reference_id))&Pnacl_M32_PPB_ContentDecryptor_Private_KeyAdded, + .KeyMessage = (void (*)(PP_Instance instance, uint32_t reference_id, struct PP_Var message, struct PP_Var default_url))&Pnacl_M32_PPB_ContentDecryptor_Private_KeyMessage, + .KeyError = (void (*)(PP_Instance instance, uint32_t reference_id, int32_t media_error, int32_t system_code))&Pnacl_M32_PPB_ContentDecryptor_Private_KeyError, + .SetSessionId = (void (*)(PP_Instance instance, uint32_t reference_id, struct PP_Var session_id))&Pnacl_M32_PPB_ContentDecryptor_Private_SetSessionId, + .DeliverBlock = (void (*)(PP_Instance instance, PP_Resource decrypted_block, const struct PP_DecryptedBlockInfo* decrypted_block_info))&Pnacl_M32_PPB_ContentDecryptor_Private_DeliverBlock, + .DecoderInitializeDone = (void (*)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id, PP_Bool success))&Pnacl_M32_PPB_ContentDecryptor_Private_DecoderInitializeDone, + .DecoderDeinitializeDone = (void (*)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id))&Pnacl_M32_PPB_ContentDecryptor_Private_DecoderDeinitializeDone, + .DecoderResetDone = (void (*)(PP_Instance instance, PP_DecryptorStreamType decoder_type, uint32_t request_id))&Pnacl_M32_PPB_ContentDecryptor_Private_DecoderResetDone, + .DeliverFrame = (void (*)(PP_Instance instance, PP_Resource decrypted_frame, const struct PP_DecryptedFrameInfo* decrypted_frame_info))&Pnacl_M32_PPB_ContentDecryptor_Private_DeliverFrame, + .DeliverSamples = (void (*)(PP_Instance instance, PP_Resource audio_frames, const struct PP_DecryptedSampleInfo* decrypted_sample_info))&Pnacl_M32_PPB_ContentDecryptor_Private_DeliverSamples }; struct PPB_Ext_CrxFileSystem_Private_0_1 Pnacl_Wrappers_PPB_Ext_CrxFileSystem_Private_0_1 = { @@ -5150,17 +5156,17 @@ struct PPB_X509Certificate_Private_0_1 Pnacl_Wrappers_PPB_X509Certificate_Privat .GetField = (struct PP_Var (*)(PP_Resource resource, PP_X509Certificate_Private_Field field))&Pnacl_M19_PPB_X509Certificate_Private_GetField }; -struct PPP_ContentDecryptor_Private_0_7 Pnacl_Wrappers_PPP_ContentDecryptor_Private_0_7 = { - .Initialize = &Pnacl_M31_PPP_ContentDecryptor_Private_Initialize, - .GenerateKeyRequest = &Pnacl_M31_PPP_ContentDecryptor_Private_GenerateKeyRequest, - .AddKey = &Pnacl_M31_PPP_ContentDecryptor_Private_AddKey, - .CancelKeyRequest = &Pnacl_M31_PPP_ContentDecryptor_Private_CancelKeyRequest, - .Decrypt = &Pnacl_M31_PPP_ContentDecryptor_Private_Decrypt, - .InitializeAudioDecoder = &Pnacl_M31_PPP_ContentDecryptor_Private_InitializeAudioDecoder, - .InitializeVideoDecoder = &Pnacl_M31_PPP_ContentDecryptor_Private_InitializeVideoDecoder, - .DeinitializeDecoder = &Pnacl_M31_PPP_ContentDecryptor_Private_DeinitializeDecoder, - .ResetDecoder = &Pnacl_M31_PPP_ContentDecryptor_Private_ResetDecoder, - .DecryptAndDecode = &Pnacl_M31_PPP_ContentDecryptor_Private_DecryptAndDecode +struct PPP_ContentDecryptor_Private_0_8 Pnacl_Wrappers_PPP_ContentDecryptor_Private_0_8 = { + .Initialize = &Pnacl_M32_PPP_ContentDecryptor_Private_Initialize, + .GenerateKeyRequest = &Pnacl_M32_PPP_ContentDecryptor_Private_GenerateKeyRequest, + .AddKey = &Pnacl_M32_PPP_ContentDecryptor_Private_AddKey, + .CancelKeyRequest = &Pnacl_M32_PPP_ContentDecryptor_Private_CancelKeyRequest, + .Decrypt = &Pnacl_M32_PPP_ContentDecryptor_Private_Decrypt, + .InitializeAudioDecoder = &Pnacl_M32_PPP_ContentDecryptor_Private_InitializeAudioDecoder, + .InitializeVideoDecoder = &Pnacl_M32_PPP_ContentDecryptor_Private_InitializeVideoDecoder, + .DeinitializeDecoder = &Pnacl_M32_PPP_ContentDecryptor_Private_DeinitializeDecoder, + .ResetDecoder = &Pnacl_M32_PPP_ContentDecryptor_Private_ResetDecoder, + .DecryptAndDecode = &Pnacl_M32_PPP_ContentDecryptor_Private_DecryptAndDecode }; /* Not generating wrapper interface for PPP_Flash_BrowserOperations_1_0 */ @@ -5593,9 +5599,9 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_Selection_Dev_0_3 = { .real_iface = NULL }; -static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7 = { - .iface_macro = PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_7, - .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_ContentDecryptor_Private_0_7, +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8 = { + .iface_macro = PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_8, + .wrapped_iface = (void *) &Pnacl_Wrappers_PPB_ContentDecryptor_Private_0_8, .real_iface = NULL }; @@ -5809,9 +5815,9 @@ static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPB_X509Certificate_Private_0 .real_iface = NULL }; -static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7 = { - .iface_macro = PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_7, - .wrapped_iface = (void *) &Pnacl_Wrappers_PPP_ContentDecryptor_Private_0_7, +static struct __PnaclWrapperInfo Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8 = { + .iface_macro = PPP_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_8, + .wrapped_iface = (void *) &Pnacl_Wrappers_PPP_ContentDecryptor_Private_0_8, .real_iface = NULL }; @@ -5905,7 +5911,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = { &Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_2, &Pnacl_WrapperInfo_PPB_VideoCapture_Dev_0_3, &Pnacl_WrapperInfo_PPB_VideoDecoder_Dev_0_16, - &Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_7, + &Pnacl_WrapperInfo_PPB_ContentDecryptor_Private_0_8, &Pnacl_WrapperInfo_PPB_Ext_CrxFileSystem_Private_0_1, &Pnacl_WrapperInfo_PPB_FileIO_Private_0_1, &Pnacl_WrapperInfo_PPB_FileRefPrivate_0_1, @@ -5951,7 +5957,7 @@ static struct __PnaclWrapperInfo *s_ppb_wrappers[] = { static struct __PnaclWrapperInfo *s_ppp_wrappers[] = { &Pnacl_WrapperInfo_PPP_Messaging_1_0, &Pnacl_WrapperInfo_PPP_Selection_Dev_0_3, - &Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_7, + &Pnacl_WrapperInfo_PPP_ContentDecryptor_Private_0_8, &Pnacl_WrapperInfo_PPP_Instance_Private_0_1, NULL }; diff --git a/ppapi/proxy/ppapi_messages.h b/ppapi/proxy/ppapi_messages.h index efca461..daa9445 100644 --- a/ppapi/proxy/ppapi_messages.h +++ b/ppapi/proxy/ppapi_messages.h @@ -642,22 +642,22 @@ IPC_MESSAGE_ROUTED3( int32_t /* result */) // PPP_ContentDecryptor_Dev -IPC_MESSAGE_ROUTED3(PpapiMsg_PPPContentDecryptor_Initialize, +IPC_MESSAGE_ROUTED2(PpapiMsg_PPPContentDecryptor_Initialize, PP_Instance /* instance */, - ppapi::proxy::SerializedVar /* key_system, String */, - bool /* can_challenge_platform */) -IPC_MESSAGE_ROUTED3(PpapiMsg_PPPContentDecryptor_GenerateKeyRequest, + ppapi::proxy::SerializedVar /* key_system, String */) +IPC_MESSAGE_ROUTED4(PpapiMsg_PPPContentDecryptor_GenerateKeyRequest, PP_Instance /* instance */, + uint32_t /* reference_id */, ppapi::proxy::SerializedVar /* type, String */, ppapi::proxy::SerializedVar /* init_data, ArrayBuffer */) IPC_MESSAGE_ROUTED4(PpapiMsg_PPPContentDecryptor_AddKey, PP_Instance /* instance */, - ppapi::proxy::SerializedVar /* session_id, String */, + uint32_t /* reference_id */, ppapi::proxy::SerializedVar /* key, ArrayBuffer */, ppapi::proxy::SerializedVar /* init_data, ArrayBuffer */) IPC_MESSAGE_ROUTED2(PpapiMsg_PPPContentDecryptor_CancelKeyRequest, PP_Instance /* instance */, - ppapi::proxy::SerializedVar /* session_id, String */) + uint32_t /* reference_id */) IPC_MESSAGE_ROUTED3(PpapiMsg_PPPContentDecryptor_Decrypt, PP_Instance /* instance */, ppapi::proxy::PPPDecryptor_Buffer /* buffer */, @@ -980,22 +980,23 @@ IPC_SYNC_MESSAGE_ROUTED2_2( ppapi::proxy::SerializedHandle /* result_shm_handle */) // PPB_ContentDecryptor_Dev messages handled in PPB_Instance_Proxy. -IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBInstance_KeyAdded, +IPC_MESSAGE_ROUTED2(PpapiHostMsg_PPBInstance_KeyAdded, PP_Instance /* instance */, - ppapi::proxy::SerializedVar /* key_system, String */, - ppapi::proxy::SerializedVar /* session_id, String */) -IPC_MESSAGE_ROUTED5(PpapiHostMsg_PPBInstance_KeyMessage, + uint32_t /* reference_id */) +IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBInstance_KeyMessage, PP_Instance /* instance */, - ppapi::proxy::SerializedVar /* key_system, String */, - ppapi::proxy::SerializedVar /* session_id, String */, + uint32_t /* reference_id */, ppapi::proxy::SerializedVar /* message, ArrayBuffer */, ppapi::proxy::SerializedVar /* default_url, String */) -IPC_MESSAGE_ROUTED5(PpapiHostMsg_PPBInstance_KeyError, +IPC_MESSAGE_ROUTED4(PpapiHostMsg_PPBInstance_KeyError, PP_Instance /* instance */, - ppapi::proxy::SerializedVar /* key_system, String */, - ppapi::proxy::SerializedVar /* session_id, String */, + uint32_t /* reference_id */, int32_t /* media_error */, int32_t /* system_code */) +IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBInstance_SetSessionId, + PP_Instance /* instance */, + uint32_t /* reference_id */, + ppapi::proxy::SerializedVar /* session_id, String */) IPC_MESSAGE_ROUTED3(PpapiHostMsg_PPBInstance_DeliverBlock, PP_Instance /* instance */, PP_Resource /* decrypted_block, PPB_Buffer_Dev */, diff --git a/ppapi/proxy/ppb_instance_proxy.cc b/ppapi/proxy/ppb_instance_proxy.cc index 1a8fe76..40cd470 100644 --- a/ppapi/proxy/ppb_instance_proxy.cc +++ b/ppapi/proxy/ppb_instance_proxy.cc @@ -181,6 +181,8 @@ bool PPB_Instance_Proxy::OnMessageReceived(const IPC::Message& msg) { OnHostMsgKeyMessage) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_KeyError, OnHostMsgKeyError) + IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_SetSessionId, + OnHostMsgSetSessionId) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DeliverBlock, OnHostMsgDeliverBlock) IPC_MESSAGE_HANDLER(PpapiHostMsg_PPBInstance_DecoderInitializeDone, @@ -538,47 +540,51 @@ PP_Var PPB_Instance_Proxy::GetPluginReferrerURL( components); } -void PPB_Instance_Proxy::KeyAdded(PP_Instance instance, - PP_Var key_system, - PP_Var session_id) { +void PPB_Instance_Proxy::KeyAdded(PP_Instance instance, uint32_t reference_id) { dispatcher()->Send( new PpapiHostMsg_PPBInstance_KeyAdded( API_ID_PPB_INSTANCE, instance, - SerializedVarSendInput(dispatcher(), key_system), - SerializedVarSendInput(dispatcher(), session_id))); + reference_id)); } void PPB_Instance_Proxy::KeyMessage(PP_Instance instance, - PP_Var key_system, - PP_Var session_id, + uint32_t reference_id, PP_Var message, PP_Var default_url) { dispatcher()->Send( new PpapiHostMsg_PPBInstance_KeyMessage( API_ID_PPB_INSTANCE, instance, - SerializedVarSendInput(dispatcher(), key_system), - SerializedVarSendInput(dispatcher(), session_id), + reference_id, SerializedVarSendInput(dispatcher(), message), SerializedVarSendInput(dispatcher(), default_url))); } void PPB_Instance_Proxy::KeyError(PP_Instance instance, - PP_Var key_system, - PP_Var session_id, + uint32_t reference_id, int32_t media_error, int32_t system_code) { dispatcher()->Send( new PpapiHostMsg_PPBInstance_KeyError( API_ID_PPB_INSTANCE, instance, - SerializedVarSendInput(dispatcher(), key_system), - SerializedVarSendInput(dispatcher(), session_id), + reference_id, media_error, system_code)); } +void PPB_Instance_Proxy::SetSessionId(PP_Instance instance, + uint32_t reference_id, + PP_Var session_id) { + dispatcher()->Send( + new PpapiHostMsg_PPBInstance_SetSessionId( + API_ID_PPB_INSTANCE, + instance, + reference_id, + SerializedVarSendInput(dispatcher(), session_id))); +} + void PPB_Instance_Proxy::DeliverBlock(PP_Instance instance, PP_Resource decrypted_block, const PP_DecryptedBlockInfo* block_info) { @@ -1045,22 +1051,18 @@ void PPB_Instance_Proxy::OnHostMsgGetPluginReferrerURL( void PPB_Instance_Proxy::OnHostMsgKeyAdded( PP_Instance instance, - SerializedVarReceiveInput key_system, - SerializedVarReceiveInput session_id) { + uint32_t reference_id) { if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) return; EnterInstanceNoLock enter(instance); if (enter.succeeded()) { - enter.functions()->KeyAdded(instance, - key_system.Get(dispatcher()), - session_id.Get(dispatcher())); + enter.functions()->KeyAdded(instance, reference_id); } } void PPB_Instance_Proxy::OnHostMsgKeyMessage( PP_Instance instance, - SerializedVarReceiveInput key_system, - SerializedVarReceiveInput session_id, + uint32_t reference_id, SerializedVarReceiveInput message, SerializedVarReceiveInput default_url) { if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) @@ -1068,8 +1070,7 @@ void PPB_Instance_Proxy::OnHostMsgKeyMessage( EnterInstanceNoLock enter(instance); if (enter.succeeded()) { enter.functions()->KeyMessage(instance, - key_system.Get(dispatcher()), - session_id.Get(dispatcher()), + reference_id, message.Get(dispatcher()), default_url.Get(dispatcher())); } @@ -1077,8 +1078,7 @@ void PPB_Instance_Proxy::OnHostMsgKeyMessage( void PPB_Instance_Proxy::OnHostMsgKeyError( PP_Instance instance, - SerializedVarReceiveInput key_system, - SerializedVarReceiveInput session_id, + uint32_t reference_id, int32_t media_error, int32_t system_error) { if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) @@ -1086,13 +1086,26 @@ void PPB_Instance_Proxy::OnHostMsgKeyError( EnterInstanceNoLock enter(instance); if (enter.succeeded()) { enter.functions()->KeyError(instance, - key_system.Get(dispatcher()), - session_id.Get(dispatcher()), + reference_id, media_error, system_error); } } +void PPB_Instance_Proxy::OnHostMsgSetSessionId( + PP_Instance instance, + uint32_t reference_id, + SerializedVarReceiveInput session_id) { + if (!dispatcher()->permissions().HasPermission(PERMISSION_PRIVATE)) + return; + EnterInstanceNoLock enter(instance); + if (enter.succeeded()) { + enter.functions()->SetSessionId(instance, + reference_id, + session_id.Get(dispatcher())); + } +} + void PPB_Instance_Proxy::OnHostMsgDeliverBlock( PP_Instance instance, PP_Resource decrypted_block, diff --git a/ppapi/proxy/ppb_instance_proxy.h b/ppapi/proxy/ppb_instance_proxy.h index 5aaa2d1..4a892e5 100644 --- a/ppapi/proxy/ppb_instance_proxy.h +++ b/ppapi/proxy/ppb_instance_proxy.h @@ -118,18 +118,18 @@ class PPB_Instance_Proxy : public InterfaceProxy, PP_Instance instance, PP_URLComponents_Dev* components) OVERRIDE; virtual void KeyAdded(PP_Instance instance, - PP_Var key_system, - PP_Var session_id) OVERRIDE; + uint32_t reference_id) OVERRIDE; virtual void KeyMessage(PP_Instance instance, - PP_Var key_system, - PP_Var session_id, + uint32_t reference_id, PP_Var message, PP_Var default_url) OVERRIDE; virtual void KeyError(PP_Instance instance, - PP_Var key_system, - PP_Var session_id, + uint32_t reference_id, int32_t media_error, int32_t system_code) OVERRIDE; + virtual void SetSessionId(PP_Instance instance, + uint32_t reference_id, + PP_Var session_id) OVERRIDE; virtual void DeliverBlock(PP_Instance instance, PP_Resource decrypted_block, const PP_DecryptedBlockInfo* block_info) OVERRIDE; @@ -221,18 +221,18 @@ class PPB_Instance_Proxy : public InterfaceProxy, void OnHostMsgGetPluginReferrerURL(PP_Instance instance, SerializedVarReturnValue result); virtual void OnHostMsgKeyAdded(PP_Instance instance, - SerializedVarReceiveInput key_system, - SerializedVarReceiveInput session_id); + uint32_t reference_id); virtual void OnHostMsgKeyMessage(PP_Instance instance, - SerializedVarReceiveInput key_system, - SerializedVarReceiveInput session_id, + uint32_t reference_id, SerializedVarReceiveInput message, SerializedVarReceiveInput default_url); virtual void OnHostMsgKeyError(PP_Instance instance, - SerializedVarReceiveInput key_system, - SerializedVarReceiveInput session_id, + uint32_t reference_id, int32_t media_error, int32_t system_code); + virtual void OnHostMsgSetSessionId(PP_Instance instance, + uint32_t reference_id, + SerializedVarReceiveInput session_id); virtual void OnHostMsgDecoderInitializeDone( PP_Instance instance, PP_DecryptorStreamType decoder_type, diff --git a/ppapi/proxy/ppp_content_decryptor_private_proxy.cc b/ppapi/proxy/ppp_content_decryptor_private_proxy.cc index d32e632..12ee04e 100644 --- a/ppapi/proxy/ppp_content_decryptor_private_proxy.cc +++ b/ppapi/proxy/ppp_content_decryptor_private_proxy.cc @@ -110,8 +110,7 @@ bool InitializePppDecryptorBuffer(PP_Instance instance, } void Initialize(PP_Instance instance, - PP_Var key_system, - PP_Bool can_challenge_platform) { + PP_Var key_system) { HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); if (!dispatcher) { NOTREACHED(); @@ -122,11 +121,11 @@ void Initialize(PP_Instance instance, new PpapiMsg_PPPContentDecryptor_Initialize( API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, instance, - SerializedVarSendInput(dispatcher, key_system), - PP_ToBool(can_challenge_platform))); + SerializedVarSendInput(dispatcher, key_system))); } void GenerateKeyRequest(PP_Instance instance, + uint32_t reference_id, PP_Var type, PP_Var init_data) { HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); @@ -139,12 +138,13 @@ void GenerateKeyRequest(PP_Instance instance, new PpapiMsg_PPPContentDecryptor_GenerateKeyRequest( API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, instance, + reference_id, SerializedVarSendInput(dispatcher, type), SerializedVarSendInput(dispatcher, init_data))); } void AddKey(PP_Instance instance, - PP_Var session_id, + uint32_t reference_id, PP_Var key, PP_Var init_data) { HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); @@ -157,12 +157,12 @@ void AddKey(PP_Instance instance, new PpapiMsg_PPPContentDecryptor_AddKey( API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, instance, - SerializedVarSendInput(dispatcher, session_id), + reference_id, SerializedVarSendInput(dispatcher, key), SerializedVarSendInput(dispatcher, init_data))); } -void CancelKeyRequest(PP_Instance instance, PP_Var session_id) { +void CancelKeyRequest(PP_Instance instance, uint32_t reference_id) { HostDispatcher* dispatcher = HostDispatcher::GetForInstance(instance); if (!dispatcher) { NOTREACHED(); @@ -173,7 +173,7 @@ void CancelKeyRequest(PP_Instance instance, PP_Var session_id) { new PpapiMsg_PPPContentDecryptor_CancelKeyRequest( API_ID_PPP_CONTENT_DECRYPTOR_PRIVATE, instance, - SerializedVarSendInput(dispatcher, session_id))); + reference_id)); } void Decrypt(PP_Instance instance, @@ -434,24 +434,24 @@ bool PPP_ContentDecryptor_Private_Proxy::OnMessageReceived( void PPP_ContentDecryptor_Private_Proxy::OnMsgInitialize( PP_Instance instance, - SerializedVarReceiveInput key_system, - bool can_challenge_platform) { + SerializedVarReceiveInput key_system) { if (ppp_decryptor_impl_) { CallWhileUnlocked( ppp_decryptor_impl_->Initialize, instance, - ExtractReceivedVarAndAddRef(dispatcher(), &key_system), - PP_FromBool(can_challenge_platform)); + ExtractReceivedVarAndAddRef(dispatcher(), &key_system)); } } void PPP_ContentDecryptor_Private_Proxy::OnMsgGenerateKeyRequest( PP_Instance instance, + uint32_t reference_id, SerializedVarReceiveInput type, SerializedVarReceiveInput init_data) { if (ppp_decryptor_impl_) { CallWhileUnlocked(ppp_decryptor_impl_->GenerateKeyRequest, instance, + reference_id, ExtractReceivedVarAndAddRef(dispatcher(), &type), ExtractReceivedVarAndAddRef(dispatcher(), &init_data)); } @@ -459,13 +459,13 @@ void PPP_ContentDecryptor_Private_Proxy::OnMsgGenerateKeyRequest( void PPP_ContentDecryptor_Private_Proxy::OnMsgAddKey( PP_Instance instance, - SerializedVarReceiveInput session_id, + uint32_t reference_id, SerializedVarReceiveInput key, SerializedVarReceiveInput init_data) { if (ppp_decryptor_impl_) { CallWhileUnlocked(ppp_decryptor_impl_->AddKey, instance, - ExtractReceivedVarAndAddRef(dispatcher(), &session_id), + reference_id, ExtractReceivedVarAndAddRef(dispatcher(), &key), ExtractReceivedVarAndAddRef(dispatcher(), &init_data)); } @@ -473,11 +473,11 @@ void PPP_ContentDecryptor_Private_Proxy::OnMsgAddKey( void PPP_ContentDecryptor_Private_Proxy::OnMsgCancelKeyRequest( PP_Instance instance, - SerializedVarReceiveInput session_id) { + uint32_t reference_id) { if (ppp_decryptor_impl_) { CallWhileUnlocked(ppp_decryptor_impl_->CancelKeyRequest, instance, - ExtractReceivedVarAndAddRef(dispatcher(), &session_id)); + reference_id); } } diff --git a/ppapi/proxy/ppp_content_decryptor_private_proxy.h b/ppapi/proxy/ppp_content_decryptor_private_proxy.h index 2e4ad854..b4472f5 100644 --- a/ppapi/proxy/ppp_content_decryptor_private_proxy.h +++ b/ppapi/proxy/ppp_content_decryptor_private_proxy.h @@ -31,17 +31,17 @@ class PPP_ContentDecryptor_Private_Proxy : public InterfaceProxy { // Message handlers. void OnMsgInitialize(PP_Instance instance, - SerializedVarReceiveInput key_system, - bool can_challenge_platform); + SerializedVarReceiveInput key_system); void OnMsgGenerateKeyRequest(PP_Instance instance, + uint32_t reference_id, SerializedVarReceiveInput type, SerializedVarReceiveInput init_data); void OnMsgAddKey(PP_Instance instance, - SerializedVarReceiveInput session_id, + uint32_t reference_id, SerializedVarReceiveInput key, SerializedVarReceiveInput init_data); void OnMsgCancelKeyRequest(PP_Instance instance, - SerializedVarReceiveInput session_id); + uint32_t reference_id); void OnMsgDecrypt(PP_Instance instance, const PPPDecryptor_Buffer& encrypted_buffer, const std::string& serialized_encrypted_block_info); diff --git a/ppapi/thunk/interfaces_ppb_private.h b/ppapi/thunk/interfaces_ppb_private.h index 9aac89b..9002545 100644 --- a/ppapi/thunk/interfaces_ppb_private.h +++ b/ppapi/thunk/interfaces_ppb_private.h @@ -25,8 +25,8 @@ PROXIED_IFACE(PPB_Broker, PPB_BROKER_TRUSTED_INTERFACE_0_3, PROXIED_IFACE(PPB_Instance, PPB_BROWSERFONT_TRUSTED_INTERFACE_1_0, PPB_BrowserFont_Trusted_1_0) PROXIED_IFACE(PPB_Instance, - PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_7, - PPB_ContentDecryptor_Private_0_7) + PPB_CONTENTDECRYPTOR_PRIVATE_INTERFACE_0_8, + PPB_ContentDecryptor_Private_0_8) PROXIED_IFACE(PPB_Instance, PPB_CHARSET_TRUSTED_INTERFACE_1_0, PPB_CharSet_Trusted_1_0) PROXIED_IFACE(NoAPIName, PPB_FILECHOOSER_TRUSTED_INTERFACE_0_5, diff --git a/ppapi/thunk/ppb_content_decryptor_private_thunk.cc b/ppapi/thunk/ppb_content_decryptor_private_thunk.cc index a43d24d..201d526 100644 --- a/ppapi/thunk/ppb_content_decryptor_private_thunk.cc +++ b/ppapi/thunk/ppb_content_decryptor_private_thunk.cc @@ -3,7 +3,7 @@ // found in the LICENSE file. // From private/ppb_content_decryptor_private.idl, -// modified Thu Oct 10 14:49:51 2013. +// modified Thu Oct 17 15:03:48 2013. #include "ppapi/c/pp_errors.h" #include "ppapi/c/private/ppb_content_decryptor_private.h" @@ -18,46 +18,44 @@ namespace thunk { namespace { -void KeyAdded(PP_Instance instance, - struct PP_Var key_system, - struct PP_Var session_id) { +void KeyAdded(PP_Instance instance, uint32_t reference_id) { VLOG(4) << "PPB_ContentDecryptor_Private::KeyAdded()"; EnterInstance enter(instance); if (enter.failed()) return; - enter.functions()->KeyAdded(instance, key_system, session_id); + enter.functions()->KeyAdded(instance, reference_id); } void KeyMessage(PP_Instance instance, - struct PP_Var key_system, - struct PP_Var session_id, + uint32_t reference_id, struct PP_Var message, struct PP_Var default_url) { VLOG(4) << "PPB_ContentDecryptor_Private::KeyMessage()"; EnterInstance enter(instance); if (enter.failed()) return; - enter.functions()->KeyMessage(instance, - key_system, - session_id, - message, - default_url); + enter.functions()->KeyMessage(instance, reference_id, message, default_url); } void KeyError(PP_Instance instance, - struct PP_Var key_system, - struct PP_Var session_id, + uint32_t reference_id, int32_t media_error, int32_t system_code) { VLOG(4) << "PPB_ContentDecryptor_Private::KeyError()"; EnterInstance enter(instance); if (enter.failed()) return; - enter.functions()->KeyError(instance, - key_system, - session_id, - media_error, - system_code); + enter.functions()->KeyError(instance, reference_id, media_error, system_code); +} + +void SetSessionId(PP_Instance instance, + uint32_t reference_id, + struct PP_Var session_id) { + VLOG(4) << "PPB_ContentDecryptor_Private::SetSessionId()"; + EnterInstance enter(instance); + if (enter.failed()) + return; + enter.functions()->SetSessionId(instance, reference_id, session_id); } void DeliverBlock(PP_Instance instance, @@ -133,11 +131,12 @@ void DeliverSamples( decrypted_sample_info); } -const PPB_ContentDecryptor_Private_0_7 - g_ppb_contentdecryptor_private_thunk_0_7 = { +const PPB_ContentDecryptor_Private_0_8 + g_ppb_contentdecryptor_private_thunk_0_8 = { &KeyAdded, &KeyMessage, &KeyError, + &SetSessionId, &DeliverBlock, &DecoderInitializeDone, &DecoderDeinitializeDone, @@ -148,9 +147,9 @@ const PPB_ContentDecryptor_Private_0_7 } // namespace -const PPB_ContentDecryptor_Private_0_7* - GetPPB_ContentDecryptor_Private_0_7_Thunk() { - return &g_ppb_contentdecryptor_private_thunk_0_7; +const PPB_ContentDecryptor_Private_0_8* + GetPPB_ContentDecryptor_Private_0_8_Thunk() { + return &g_ppb_contentdecryptor_private_thunk_0_8; } } // namespace thunk diff --git a/ppapi/thunk/ppb_instance_api.h b/ppapi/thunk/ppb_instance_api.h index 93eba9c..60e4f07 100644 --- a/ppapi/thunk/ppb_instance_api.h +++ b/ppapi/thunk/ppb_instance_api.h @@ -143,18 +143,18 @@ class PPB_Instance_API { #if !defined(OS_NACL) // Content Decryptor. virtual void KeyAdded(PP_Instance instance, - PP_Var key_system, - PP_Var session_id) = 0; + uint32 reference_id) = 0; virtual void KeyMessage(PP_Instance instance, - PP_Var key_system, - PP_Var session_id, + uint32 reference_id, PP_Var message, PP_Var default_url) = 0; virtual void KeyError(PP_Instance instance, - PP_Var key_system, - PP_Var session_id, + uint32 reference_id, int32_t media_error, int32_t system_error) = 0; + virtual void SetSessionId(PP_Instance instance, + uint32 reference_id, + PP_Var session_id) = 0; virtual void DeliverBlock(PP_Instance instance, PP_Resource decrypted_block, const PP_DecryptedBlockInfo* block_info) = 0; |