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_SessionError, OnSessionError) |
| 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) { |
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, | |
82 uint32 session_id, | |
83 const std::string& web_session_id) { | |
84 if (web_session_id.length() > kMaxWebSessionIdLength) { | |
85 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | |
86 return; | |
87 } | |
88 | |
89 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | |
90 if (media_keys) | |
91 media_keys->OnSessionCreated(session_id, web_session_id); | |
92 } | |
93 | |
94 void RendererCdmManager::OnSessionMessage(int cdm_id, | 100 void RendererCdmManager::OnSessionMessage(int cdm_id, |
95 uint32 session_id, | 101 const std::string& session_id, |
96 const std::vector<uint8>& message, | 102 const std::vector<uint8>& message, |
97 const GURL& destination_url) { | 103 const GURL& destination_url) { |
98 if (message.size() > kMaxSessionMessageLength) { | 104 if (message.size() > kMaxSessionMessageLength) { |
99 OnSessionError(cdm_id, session_id, media::MediaKeys::kUnknownError, 0); | 105 NOTREACHED(); |
| 106 LOG(ERROR) << "Message is too long and dropped."; |
100 return; | 107 return; |
101 } | 108 } |
102 | 109 |
103 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | 110 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
104 if (media_keys) | 111 if (media_keys) |
105 media_keys->OnSessionMessage(session_id, message, destination_url); | 112 media_keys->OnSessionMessage(session_id, message, destination_url); |
106 } | 113 } |
107 | 114 |
108 void RendererCdmManager::OnSessionReady(int cdm_id, uint32 session_id) { | 115 void RendererCdmManager::OnSessionClosed(int cdm_id, |
109 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | 116 const std::string& session_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); | 117 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
116 if (media_keys) | 118 if (media_keys) |
117 media_keys->OnSessionClosed(session_id); | 119 media_keys->OnSessionClosed(session_id); |
118 } | 120 } |
119 | 121 |
120 void RendererCdmManager::OnSessionError(int cdm_id, | 122 void RendererCdmManager::OnSessionError(int cdm_id, |
121 uint32 session_id, | 123 const std::string& session_id, |
122 media::MediaKeys::KeyError error_code, | 124 MediaKeys::Exception exception, |
123 uint32 system_code) { | 125 uint32 system_code, |
| 126 const std::string& error_message) { |
124 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); | 127 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
125 if (media_keys) | 128 if (media_keys) |
126 media_keys->OnSessionError(session_id, error_code, system_code); | 129 media_keys->OnSessionError(session_id, exception, system_code, |
| 130 error_message); |
| 131 } |
| 132 |
| 133 void RendererCdmManager::OnSessionKeysChange( |
| 134 int cdm_id, |
| 135 const std::string& session_id, |
| 136 bool has_additional_usable_key, |
| 137 const std::vector<media::CdmKeyInformation>& key_info_vector) { |
| 138 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
| 139 if (!media_keys) |
| 140 return; |
| 141 |
| 142 media::CdmKeysInfo keys_info; |
| 143 keys_info.reserve(key_info_vector.size()); |
| 144 for (const auto& key_info : key_info_vector) |
| 145 keys_info.push_back(new media::CdmKeyInformation(key_info)); |
| 146 |
| 147 media_keys->OnSessionKeysChange(session_id, has_additional_usable_key, |
| 148 keys_info.Pass()); |
| 149 } |
| 150 |
| 151 void RendererCdmManager::OnSessionExpirationUpdate( |
| 152 int cdm_id, |
| 153 const std::string& session_id, |
| 154 const base::Time& new_expiry_time) { |
| 155 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
| 156 if (media_keys) |
| 157 media_keys->OnSessionExpirationUpdate(session_id, new_expiry_time); |
| 158 } |
| 159 |
| 160 void RendererCdmManager::OnPromiseResolved(int cdm_id, uint32_t promise_id) { |
| 161 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
| 162 if (media_keys) |
| 163 media_keys->OnPromiseResolved(promise_id); |
| 164 } |
| 165 |
| 166 void RendererCdmManager::OnPromiseResolvedWithSession( |
| 167 int cdm_id, |
| 168 uint32_t promise_id, |
| 169 const std::string& session_id) { |
| 170 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
| 171 if (media_keys) |
| 172 media_keys->OnPromiseResolvedWithSession(promise_id, session_id); |
| 173 } |
| 174 |
| 175 void RendererCdmManager::OnPromiseRejected(int cdm_id, |
| 176 uint32_t promise_id, |
| 177 MediaKeys::Exception exception, |
| 178 uint32_t system_code, |
| 179 const std::string& error_message) { |
| 180 ProxyMediaKeys* media_keys = GetMediaKeys(cdm_id); |
| 181 if (media_keys) |
| 182 media_keys->OnPromiseRejected(promise_id, exception, system_code, |
| 183 error_message); |
127 } | 184 } |
128 | 185 |
129 int RendererCdmManager::RegisterMediaKeys(ProxyMediaKeys* media_keys) { | 186 int RendererCdmManager::RegisterMediaKeys(ProxyMediaKeys* media_keys) { |
130 int cdm_id = next_cdm_id_++; | 187 int cdm_id = next_cdm_id_++; |
131 DCHECK_NE(cdm_id, media::CdmContext::kInvalidCdmId); | 188 DCHECK_NE(cdm_id, media::CdmContext::kInvalidCdmId); |
132 DCHECK(!ContainsKey(proxy_media_keys_map_, cdm_id)); | 189 DCHECK(!ContainsKey(proxy_media_keys_map_, cdm_id)); |
133 proxy_media_keys_map_[cdm_id] = media_keys; | 190 proxy_media_keys_map_[cdm_id] = media_keys; |
134 return cdm_id; | 191 return cdm_id; |
135 } | 192 } |
136 | 193 |
137 void RendererCdmManager::UnregisterMediaKeys(int cdm_id) { | 194 void RendererCdmManager::UnregisterMediaKeys(int cdm_id) { |
138 DCHECK(ContainsKey(proxy_media_keys_map_, cdm_id)); | 195 DCHECK(ContainsKey(proxy_media_keys_map_, cdm_id)); |
139 proxy_media_keys_map_.erase(cdm_id); | 196 proxy_media_keys_map_.erase(cdm_id); |
140 } | 197 } |
141 | 198 |
142 ProxyMediaKeys* RendererCdmManager::GetMediaKeys(int cdm_id) { | 199 ProxyMediaKeys* RendererCdmManager::GetMediaKeys(int cdm_id) { |
143 std::map<int, ProxyMediaKeys*>::iterator iter = | 200 std::map<int, ProxyMediaKeys*>::iterator iter = |
144 proxy_media_keys_map_.find(cdm_id); | 201 proxy_media_keys_map_.find(cdm_id); |
145 return (iter != proxy_media_keys_map_.end()) ? iter->second : NULL; | 202 return (iter != proxy_media_keys_map_.end()) ? iter->second : NULL; |
146 } | 203 } |
147 | 204 |
148 } // namespace content | 205 } // namespace content |
OLD | NEW |