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

Side by Side Diff: content/browser/media/cdm/browser_cdm_manager.cc

Issue 315733003: Separate BrowserCdmManager from BrowserMediaPlayerManager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Ready for review. Please diff against PS1 for easier life! Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/media/cdm/browser_cdm_manager.h"
6
7 #include "base/command_line.h"
8 #include "base/stl_util.h"
9 #include "content/common/media/cdm_messages.h"
10 #include "content/public/browser/browser_context.h"
11 #include "content/public/browser/render_frame_host.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/common/content_client.h"
16 #include "content/public/common/content_switches.h"
17 #include "media/base/browser_cdm.h"
18 #include "media/base/browser_cdm_factory.h"
19 #include "media/base/media_switches.h"
20
21 namespace content {
22
23 using media::MediaKeys;
ddorwin 2014/06/04 01:02:30 order
xhwang 2014/06/04 18:54:07 Done.
24 using media::BrowserCdm;
25
26 // Maximum lengths for various EME API parameters. These are checks to
27 // prevent unnecessarily large parameters from being passed around, and the
28 // lengths are somewhat arbitrary as the EME spec doesn't specify any limits.
29 const size_t kMaxInitDataLength = 64 * 1024; // 64 KB
30 const size_t kMaxSessionResponseLength = 64 * 1024; // 64 KB
31 const size_t kMaxKeySystemLength = 256;
32
33 // static
34 BrowserCdmManager* BrowserCdmManager::Create(RenderFrameHost* rfh) {
35 return new BrowserCdmManager(rfh);
36 }
37
38 BrowserCdmManager::BrowserCdmManager(RenderFrameHost* render_frame_host)
39 : render_frame_host_(render_frame_host),
40 web_contents_(WebContents::FromRenderFrameHost(render_frame_host)),
41 weak_ptr_factory_(this) {
42 }
43
44 BrowserCdmManager::~BrowserCdmManager() {
xhwang 2014/06/03 22:43:08 There could be some destruction order issues here.
45 for (CdmMap::iterator it = cdm_map_.begin(); it != cdm_map_.end(); ++it)
ddorwin 2014/06/04 01:02:30 Does stl_utils handle this?
xhwang 2014/06/04 18:54:07 Good point. Done.
46 delete it->second;
47 }
48
49 BrowserCdm* BrowserCdmManager::GetCdm(int cdm_id) {
50 CdmMap::const_iterator iter = cdm_map_.find(cdm_id);
51 return (iter == cdm_map_.end()) ? NULL : iter->second;
52 }
53
54 void BrowserCdmManager::OnSessionCreated(
55 int cdm_id,
56 uint32 session_id,
57 const std::string& web_session_id) {
58 Send(new CdmMsg_SessionCreated(
59 RoutingID(), cdm_id, session_id, web_session_id));
60 }
61
62 void BrowserCdmManager::OnSessionMessage(
63 int cdm_id,
64 uint32 session_id,
65 const std::vector<uint8>& message,
66 const GURL& destination_url) {
67 GURL verified_gurl = destination_url;
68 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) {
69 DLOG(WARNING) << "SessionMessage destination_url is invalid : "
70 << destination_url.possibly_invalid_spec();
71 verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url.
72 }
73
74 Send(new CdmMsg_SessionMessage(
75 RoutingID(), cdm_id, session_id, message, verified_gurl));
76 }
77
78 void BrowserCdmManager::OnSessionReady(int cdm_id, uint32 session_id) {
79 Send(new CdmMsg_SessionReady(RoutingID(), cdm_id, session_id));
80 }
81
82 void BrowserCdmManager::OnSessionClosed(int cdm_id, uint32 session_id) {
83 Send(new CdmMsg_SessionClosed(RoutingID(), cdm_id, session_id));
84 }
85
86 void BrowserCdmManager::OnSessionError(int cdm_id,
87 uint32 session_id,
88 MediaKeys::KeyError error_code,
89 uint32 system_code) {
90 Send(new CdmMsg_SessionError(
91 RoutingID(), cdm_id, session_id, error_code, system_code));
92 }
93
94 void BrowserCdmManager::OnInitializeCdm(int cdm_id,
95 const std::string& key_system,
96 const GURL& security_origin) {
97 if (key_system.size() > kMaxKeySystemLength) {
98 // This failure will be discovered and reported by OnCreateSession()
99 // as GetCdm() will return null.
100 NOTREACHED() << "Invalid key system: " << key_system;
101 return;
102 }
103
104 AddCdm(cdm_id, key_system, security_origin);
105 }
106
107 void BrowserCdmManager::OnCreateSession(
108 int cdm_id,
109 uint32 session_id,
110 CdmHostMsg_CreateSession_ContentType content_type,
111 const std::vector<uint8>& init_data) {
112 if (init_data.size() > kMaxInitDataLength) {
113 LOG(WARNING) << "InitData for ID: " << cdm_id
114 << " too long: " << init_data.size();
115 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
116 return;
117 }
118
119 // Convert the session content type into a MIME type. "audio" and "video"
120 // don't matter, so using "video" for the MIME type.
121 // Ref:
122 // https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypte d-media.html#dom-createsession
123 std::string mime_type;
124 switch (content_type) {
125 case CREATE_SESSION_TYPE_WEBM:
126 mime_type = "video/webm";
127 break;
128 case CREATE_SESSION_TYPE_MP4:
129 mime_type = "video/mp4";
130 break;
131 default:
132 NOTREACHED();
133 return;
134 }
135
136 if (CommandLine::ForCurrentProcess()
137 ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) {
138 CreateSessionIfPermitted(cdm_id, session_id, mime_type, init_data, true);
139 return;
140 }
141
142 BrowserCdm* cdm = GetCdm(cdm_id);
143 if (!cdm) {
144 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
145 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
146 return;
147 }
148
149 BrowserContext* context =
150 web_contents_->GetRenderProcessHost()->GetBrowserContext();
151
152 std::map<int, GURL>::const_iterator iter =
153 cdm_security_origin_map_.find(cdm_id);
154 if (iter == cdm_security_origin_map_.end()) {
155 NOTREACHED();
156 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
157 return;
158 }
159
160 context->RequestProtectedMediaIdentifierPermission(
161 web_contents_->GetRenderProcessHost()->GetID(),
162 web_contents_->GetRenderViewHost()->GetRoutingID(),
163 iter->second,
164 base::Bind(&BrowserCdmManager::CreateSessionIfPermitted,
165 weak_ptr_factory_.GetWeakPtr(),
166 cdm_id,
167 session_id,
168 mime_type,
169 init_data));
170 }
171
172 void BrowserCdmManager::OnUpdateSession(
173 int cdm_id,
174 uint32 session_id,
175 const std::vector<uint8>& response) {
176 BrowserCdm* cdm = GetCdm(cdm_id);
177 if (!cdm) {
178 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
179 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
180 return;
181 }
182
183 if (response.size() > kMaxSessionResponseLength) {
184 LOG(WARNING) << "Response for ID " << cdm_id
185 << " is too long: " << response.size();
186 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
187 return;
188 }
189
190 cdm->UpdateSession(session_id, &response[0], response.size());
191 }
192
193 void BrowserCdmManager::OnReleaseSession(int cdm_id, uint32 session_id) {
194 BrowserCdm* cdm = GetCdm(cdm_id);
195 if (!cdm) {
196 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
197 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
198 return;
199 }
200
201 cdm->ReleaseSession(session_id);
202 }
203
204 void BrowserCdmManager::OnDestroyCdm(int cdm_id) {
205 BrowserCdm* cdm = GetCdm(cdm_id);
206 if (!cdm)
207 return;
208
209 CancelAllPendingSessionCreations(cdm_id);
210 RemoveCdm(cdm_id);
211 }
212
213 void BrowserCdmManager::CancelAllPendingSessionCreations(int cdm_id) {
214 BrowserContext* context =
215 web_contents_->GetRenderProcessHost()->GetBrowserContext();
216 std::map<int, GURL>::const_iterator iter =
217 cdm_security_origin_map_.find(cdm_id);
218 if (iter == cdm_security_origin_map_.end())
219 return;
220 context->CancelProtectedMediaIdentifierPermissionRequests(
221 web_contents_->GetRenderProcessHost()->GetID(),
222 web_contents_->GetRenderViewHost()->GetRoutingID(),
223 iter->second);
224 }
225
226 void BrowserCdmManager::AddCdm(int cdm_id,
227 const std::string& key_system,
228 const GURL& security_origin) {
229 DCHECK(!GetCdm(cdm_id));
230 base::WeakPtr<BrowserCdmManager> weak_this = weak_ptr_factory_.GetWeakPtr();
231 scoped_ptr<BrowserCdm> cdm(media::CreateBrowserCdm(
232 key_system,
233 base::Bind(&BrowserCdmManager::OnSessionCreated, weak_this, cdm_id),
234 base::Bind(&BrowserCdmManager::OnSessionMessage, weak_this, cdm_id),
235 base::Bind(&BrowserCdmManager::OnSessionReady, weak_this, cdm_id),
236 base::Bind(&BrowserCdmManager::OnSessionClosed, weak_this, cdm_id),
237 base::Bind(&BrowserCdmManager::OnSessionError, weak_this, cdm_id)));
238
239 if (!cdm) {
240 // This failure will be discovered and reported by OnCreateSession()
241 // as GetCdm() will return null.
242 DVLOG(1) << "failed to create CDM.";
243 return;
244 }
245
246 cdm_map_[cdm_id] = cdm.release();
247 cdm_security_origin_map_[cdm_id] = security_origin;
248 }
249
250 void BrowserCdmManager::RemoveCdm(int cdm_id) {
251 // TODO(xhwang): Detach CDM from the player it's set to. In prefixed
252 // EME implementation the current code is fine because we always destroy the
253 // player before we destroy the DrmBridge. This will not always be the case
254 // in unprefixed EME implementation.
255 CdmMap::iterator iter = cdm_map_.find(cdm_id);
256 if (iter != cdm_map_.end()) {
257 delete iter->second;
258 cdm_map_.erase(iter);
259 }
260 cdm_security_origin_map_.erase(cdm_id);
261 }
262
263 int BrowserCdmManager::RoutingID() {
264 return render_frame_host_->GetRoutingID();
265 }
266
267 bool BrowserCdmManager::Send(IPC::Message* msg) {
268 return render_frame_host_->Send(msg);
269 }
270
271 void BrowserCdmManager::CreateSessionIfPermitted(
272 int cdm_id,
273 uint32 session_id,
274 const std::string& content_type,
275 const std::vector<uint8>& init_data,
276 bool permitted) {
277 if (!permitted) {
278 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
279 return;
280 }
281
282 BrowserCdm* cdm = GetCdm(cdm_id);
283 if (!cdm) {
284 DLOG(WARNING) << "No CDM for ID: " << cdm_id << " found";
285 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
286 return;
287 }
288
289 // This could fail, in which case a SessionError will be fired.
290 cdm->CreateSession(session_id, content_type, &init_data[0], init_data.size());
291 }
292
293 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698