Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/renderer/media/crypto/renderer_cdm_manager.h" | 5 #include "content/renderer/media/crypto/renderer_cdm_manager.h" |
| 6 | 6 |
| 7 #include "base/stl_util.h" | 7 #include "base/stl_util.h" |
| 8 #include "content/common/media/cdm_messages.h" | 8 #include "content/common/media/cdm_messages.h" |
| 9 #include "content/renderer/media/crypto/proxy_media_keys.h" | 9 #include "content/renderer/media/crypto/proxy_media_keys.h" |
| 10 #include "media/base/cdm_context.h" | 10 #include "media/base/cdm_context.h" |
| 11 | 11 |
| 12 namespace content { | 12 namespace content { |
| 13 | 13 |
| 14 using media::MediaKeys; | |
| 15 | |
| 14 // Maximum sizes for various EME API parameters. These are checks to prevent | 16 // Maximum sizes for various EME API parameters. These are checks to prevent |
| 15 // unnecessarily large messages from being passed around, and the sizes | 17 // unnecessarily large messages from being passed around, and the sizes |
| 16 // are somewhat arbitrary as the EME spec doesn't specify any limits. | 18 // are somewhat arbitrary as the EME spec doesn't specify any limits. |
| 17 const size_t kMaxWebSessionIdLength = 512; | 19 const size_t kMaxWebSessionIdLength = 512; |
| 18 const size_t kMaxSessionMessageLength = 10240; // 10 KB | 20 const size_t kMaxSessionMessageLength = 10240; // 10 KB |
| 19 | 21 |
| 20 RendererCdmManager::RendererCdmManager(RenderFrame* render_frame) | 22 RendererCdmManager::RendererCdmManager(RenderFrame* render_frame) |
| 21 : RenderFrameObserver(render_frame), | 23 : RenderFrameObserver(render_frame), |
| 22 next_cdm_id_(media::CdmContext::kInvalidCdmId + 1) { | 24 next_cdm_id_(media::CdmContext::kInvalidCdmId + 1) { |
| 23 } | 25 } |
| 24 | 26 |
| 25 RendererCdmManager::~RendererCdmManager() { | 27 RendererCdmManager::~RendererCdmManager() { |
| 26 DCHECK(proxy_media_keys_map_.empty()) | 28 DCHECK(proxy_media_keys_map_.empty()) |
| 27 << "RendererCdmManager is owned by RenderFrameImpl and is destroyed only " | 29 << "RendererCdmManager is owned by RenderFrameImpl and is destroyed only " |
| 28 "after all ProxyMediaKeys are destroyed and unregistered."; | 30 "after all ProxyMediaKeys are destroyed and unregistered."; |
| 29 } | 31 } |
| 30 | 32 |
| 31 bool RendererCdmManager::OnMessageReceived(const IPC::Message& msg) { | 33 bool RendererCdmManager::OnMessageReceived(const IPC::Message& msg) { |
| 32 bool handled = true; | 34 bool handled = true; |
| 33 IPC_BEGIN_MESSAGE_MAP(RendererCdmManager, msg) | 35 IPC_BEGIN_MESSAGE_MAP(RendererCdmManager, msg) |
| 34 IPC_MESSAGE_HANDLER(CdmMsg_SessionCreated, OnSessionCreated) | |
| 35 IPC_MESSAGE_HANDLER(CdmMsg_SessionMessage, OnSessionMessage) | 36 IPC_MESSAGE_HANDLER(CdmMsg_SessionMessage, OnSessionMessage) |
| 36 IPC_MESSAGE_HANDLER(CdmMsg_SessionReady, OnSessionReady) | |
| 37 IPC_MESSAGE_HANDLER(CdmMsg_SessionClosed, OnSessionClosed) | 37 IPC_MESSAGE_HANDLER(CdmMsg_SessionClosed, OnSessionClosed) |
| 38 IPC_MESSAGE_HANDLER(CdmMsg_SessionError, OnSessionError) | 38 IPC_MESSAGE_HANDLER(CdmMsg_LegacySessionError, OnLegacySessionError) |
| 39 IPC_MESSAGE_HANDLER(CdmMsg_SessionKeysChange, OnSessionKeysChange) | |
| 40 IPC_MESSAGE_HANDLER(CdmMsg_SessionExpirationUpdate, | |
| 41 OnSessionExpirationUpdate) | |
| 42 IPC_MESSAGE_HANDLER(CdmMsg_ResolvePromise, OnPromiseResolved) | |
| 43 IPC_MESSAGE_HANDLER(CdmMsg_ResolvePromiseWithSession, | |
| 44 OnPromiseResolvedWithSession) | |
| 45 IPC_MESSAGE_HANDLER(CdmMsg_RejectPromise, OnPromiseRejected) | |
| 39 IPC_MESSAGE_UNHANDLED(handled = false) | 46 IPC_MESSAGE_UNHANDLED(handled = false) |
| 40 IPC_END_MESSAGE_MAP() | 47 IPC_END_MESSAGE_MAP() |
| 41 return handled; | 48 return handled; |
| 42 } | 49 } |
| 43 | 50 |
| 44 void RendererCdmManager::InitializeCdm(int cdm_id, | 51 void RendererCdmManager::InitializeCdm(int cdm_id, |
| 45 ProxyMediaKeys* media_keys, | 52 ProxyMediaKeys* media_keys, |
| 46 const std::string& key_system, | 53 const std::string& key_system, |
| 47 const GURL& security_origin) { | 54 const GURL& security_origin) { |
| 48 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; | 55 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; |
| 49 Send(new CdmHostMsg_InitializeCdm( | 56 Send(new CdmHostMsg_InitializeCdm( |
| 50 routing_id(), cdm_id, key_system, security_origin)); | 57 routing_id(), cdm_id, key_system, security_origin)); |
| 51 } | 58 } |
| 52 | 59 |
| 53 void RendererCdmManager::CreateSession( | 60 void RendererCdmManager::SetServerCertificate( |
| 54 int cdm_id, | 61 int cdm_id, |
| 55 uint32 session_id, | 62 uint32_t promise_id, |
| 56 CdmHostMsg_CreateSession_ContentType content_type, | 63 const std::vector<uint8_t>& certificate) { |
|
jrummell
2015/01/15 18:56:23
nit: The other methods below all have DCHECK(GetMe
xhwang
2015/01/15 19:37:26
Done.
| |
| 57 const std::vector<uint8>& init_data) { | 64 Send(new CdmHostMsg_SetServerCertificate(routing_id(), cdm_id, promise_id, |
| 65 certificate)); | |
| 66 } | |
| 67 | |
| 68 void RendererCdmManager::CreateSessionAndGenerateRequest( | |
| 69 int cdm_id, | |
| 70 uint32_t promise_id, | |
| 71 CdmHostMsg_CreateSession_InitDataType init_data_type, | |
| 72 const std::vector<uint8_t>& init_data) { | |
| 58 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; | 73 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; |
| 59 Send(new CdmHostMsg_CreateSession( | 74 Send(new CdmHostMsg_CreateSessionAndGenerateRequest( |
| 60 routing_id(), cdm_id, session_id, content_type, init_data)); | 75 routing_id(), cdm_id, promise_id, init_data_type, init_data)); |
| 61 } | 76 } |
| 62 | 77 |
| 63 void RendererCdmManager::UpdateSession(int cdm_id, | 78 void RendererCdmManager::UpdateSession(int cdm_id, |
| 64 uint32 session_id, | 79 uint32_t promise_id, |
| 65 const std::vector<uint8>& response) { | 80 const std::string& session_id, |
| 81 const std::vector<uint8_t>& response) { | |
| 66 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; | 82 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; |
| 67 Send( | 83 Send(new CdmHostMsg_UpdateSession(routing_id(), cdm_id, promise_id, |
| 68 new CdmHostMsg_UpdateSession(routing_id(), cdm_id, session_id, response)); | 84 session_id, response)); |
| 69 } | 85 } |
| 70 | 86 |
| 71 void RendererCdmManager::ReleaseSession(int cdm_id, uint32 session_id) { | 87 void RendererCdmManager::CloseSession(int cdm_id, |
| 88 uint32_t promise_id, | |
| 89 const std::string& session_id) { | |
| 72 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; | 90 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; |
| 73 Send(new CdmHostMsg_ReleaseSession(routing_id(), cdm_id, session_id)); | 91 Send(new CdmHostMsg_CloseSession(routing_id(), cdm_id, promise_id, |
| 92 session_id)); | |
| 74 } | 93 } |
| 75 | 94 |
| 76 void RendererCdmManager::DestroyCdm(int cdm_id) { | 95 void RendererCdmManager::DestroyCdm(int cdm_id) { |
| 77 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; | 96 DCHECK(GetMediaKeys(cdm_id)) << "|cdm_id| not registered."; |
| 78 Send(new CdmHostMsg_DestroyCdm(routing_id(), cdm_id)); | 97 Send(new CdmHostMsg_DestroyCdm(routing_id(), cdm_id)); |
| 79 } | 98 } |
| 80 | 99 |
| 81 void RendererCdmManager::OnSessionCreated(int cdm_id, | 100 void RendererCdmManager::OnSessionMessage( |
| 82 uint32 session_id, | 101 int cdm_id, |
| 83 const std::string& web_session_id) { | 102 const std::string& session_id, |
| 84 if (web_session_id.length() > kMaxWebSessionIdLength) { | 103 media::MediaKeys::MessageType message_type, |
| 85 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 104 const std::vector<uint8>& message, |
| 105 const GURL& legacy_destination_url) { | |
| 106 if (message.size() > kMaxSessionMessageLength) { | |
| 107 NOTREACHED(); | |
| 108 LOG(ERROR) << "Message is too long and dropped."; | |
| 86 return; | 109 return; |
| 87 } | 110 } |
| 88 | 111 |
| 89 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | 112 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
| 90 if (media_keys) | 113 if (media_keys) |
| 91 media_keys->OnSessionCreated(session_id, web_session_id); | 114 media_keys->OnSessionMessage(session_id, message_type, message, |
| 115 legacy_destination_url); | |
| 92 } | 116 } |
| 93 | 117 |
| 94 void RendererCdmManager::OnSessionMessage(int cdm_id, | 118 void RendererCdmManager::OnSessionClosed(int cdm_id, |
| 95 uint32 session_id, | 119 const std::string& session_id) { |
| 96 const std::vector<uint8>& message, | |
| 97 const GURL& destination_url) { | |
| 98 if (message.size() > kMaxSessionMessageLength) { | |
| 99 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | |
| 100 return; | |
| 101 } | |
| 102 | |
| 103 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | |
| 104 if (media_keys) | |
| 105 media_keys->OnSessionMessage(session_id, message, destination_url); | |
| 106 } | |
| 107 | |
| 108 void RendererCdmManager::OnSessionReady(int cdm_id, uint32 session_id) { | |
| 109 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | |
| 110 if (media_keys) | |
| 111 media_keys->OnSessionReady(session_id); | |
| 112 } | |
| 113 | |
| 114 void RendererCdmManager::OnSessionClosed(int cdm_id, uint32 session_id) { | |
| 115 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | 120 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
| 116 if (media_keys) | 121 if (media_keys) |
| 117 media_keys->OnSessionClosed(session_id); | 122 media_keys->OnSessionClosed(session_id); |
| 118 } | 123 } |
| 119 | 124 |
| 120 void RendererCdmManager::OnSessionError(int cdm_id, | 125 void RendererCdmManager::OnLegacySessionError( |
| 121 uint32 session_id, | 126 int cdm_id, |
| 122 media::MediaKeys::KeyError error_code, | 127 const std::string& session_id, |
| 123 uint32 system_code) { | 128 MediaKeys::Exception exception, |
| 129 uint32 system_code, | |
| 130 const std::string& error_message) { | |
| 124 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | 131 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
| 125 if (media_keys) | 132 if (media_keys) |
| 126 media_keys->OnSessionError(session_id, error_code, system_code); | 133 media_keys->OnLegacySessionError(session_id, exception, system_code, |
| 134 error_message); | |
| 135 } | |
| 136 | |
| 137 void RendererCdmManager::OnSessionKeysChange( | |
| 138 int cdm_id, | |
| 139 const std::string& session_id, | |
| 140 bool has_additional_usable_key, | |
| 141 const std::vector<media::CdmKeyInformation>& key_info_vector) { | |
| 142 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | |
| 143 if (!media_keys) | |
| 144 return; | |
| 145 | |
| 146 media::CdmKeysInfo keys_info; | |
| 147 keys_info.reserve(key_info_vector.size()); | |
| 148 for (const auto& key_info : key_info_vector) | |
| 149 keys_info.push_back(new media::CdmKeyInformation(key_info)); | |
| 150 | |
| 151 media_keys->OnSessionKeysChange(session_id, has_additional_usable_key, | |
| 152 keys_info.Pass()); | |
| 153 } | |
| 154 | |
| 155 void RendererCdmManager::OnSessionExpirationUpdate( | |
| 156 int cdm_id, | |
| 157 const std::string& session_id, | |
| 158 const base::Time& new_expiry_time) { | |
| 159 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | |
| 160 if (media_keys) | |
| 161 media_keys->OnSessionExpirationUpdate(session_id, new_expiry_time); | |
| 162 } | |
| 163 | |
| 164 void RendererCdmManager::OnPromiseResolved(int cdm_id, uint32_t promise_id) { | |
| 165 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | |
| 166 if (media_keys) | |
| 167 media_keys->OnPromiseResolved(promise_id); | |
| 168 } | |
| 169 | |
| 170 void RendererCdmManager::OnPromiseResolvedWithSession( | |
| 171 int cdm_id, | |
| 172 uint32_t promise_id, | |
| 173 const std::string& session_id) { | |
| 174 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | |
| 175 if (media_keys) | |
| 176 media_keys->OnPromiseResolvedWithSession(promise_id, session_id); | |
| 177 } | |
| 178 | |
| 179 void RendererCdmManager::OnPromiseRejected(int cdm_id, | |
| 180 uint32_t promise_id, | |
| 181 MediaKeys::Exception exception, | |
| 182 uint32_t system_code, | |
| 183 const std::string& error_message) { | |
| 184 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | |
| 185 if (media_keys) | |
| 186 media_keys->OnPromiseRejected(promise_id, exception, system_code, | |
| 187 error_message); | |
| 127 } | 188 } |
| 128 | 189 |
| 129 int RendererCdmManager::RegisterMediaKeys(ProxyMediaKeys* media_keys) { | 190 int RendererCdmManager::RegisterMediaKeys(ProxyMediaKeys* media_keys) { |
| 130 int cdm_id = next_cdm_id_++; | 191 int cdm_id = next_cdm_id_++; |
| 131 DCHECK_NE(cdm_id, media::CdmContext::kInvalidCdmId); | 192 DCHECK_NE(cdm_id, media::CdmContext::kInvalidCdmId); |
| 132 DCHECK(!ContainsKey(proxy_media_keys_map_, cdm_id)); | 193 DCHECK(!ContainsKey(proxy_media_keys_map_, cdm_id)); |
| 133 proxy_media_keys_map_[cdm_id] = media_keys; | 194 proxy_media_keys_map_[cdm_id] = media_keys; |
| 134 return cdm_id; | 195 return cdm_id; |
| 135 } | 196 } |
| 136 | 197 |
| 137 void RendererCdmManager::UnregisterMediaKeys(int cdm_id) { | 198 void RendererCdmManager::UnregisterMediaKeys(int cdm_id) { |
| 138 DCHECK(ContainsKey(proxy_media_keys_map_, cdm_id)); | 199 DCHECK(ContainsKey(proxy_media_keys_map_, cdm_id)); |
| 139 proxy_media_keys_map_.erase(cdm_id); | 200 proxy_media_keys_map_.erase(cdm_id); |
| 140 } | 201 } |
| 141 | 202 |
| 142 ProxyMediaKeys* RendererCdmManager::GetMediaKeys(int cdm_id) { | 203 ProxyMediaKeys* RendererCdmManager::GetMediaKeys(int cdm_id) { |
| 143 std::map<int, ProxyMediaKeys*>::iterator iter = | 204 std::map<int, ProxyMediaKeys*>::iterator iter = |
| 144 proxy_media_keys_map_.find(cdm_id); | 205 proxy_media_keys_map_.find(cdm_id); |
| 145 return (iter != proxy_media_keys_map_.end()) ? iter->second : NULL; | 206 return (iter != proxy_media_keys_map_.end()) ? iter->second : NULL; |
| 146 } | 207 } |
| 147 | 208 |
| 148 } // namespace content | 209 } // namespace content |
| OLD | NEW |