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

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

Issue 318753010: Introduce the ENABLE_BROWSER_CDMS macro. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: MEDIA_EXPORT 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/android/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::BrowserCdm;
24 using media::MediaKeys;
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() {
45 STLDeleteValues(&cdm_map_);
46 }
47
48 BrowserCdm* BrowserCdmManager::GetCdm(int cdm_id) {
49 CdmMap::const_iterator iter = cdm_map_.find(cdm_id);
50 return (iter == cdm_map_.end()) ? NULL : iter->second;
51 }
52
53 void BrowserCdmManager::OnSessionCreated(
54 int cdm_id,
55 uint32 session_id,
56 const std::string& web_session_id) {
57 Send(new CdmMsg_SessionCreated(
58 RoutingID(), cdm_id, session_id, web_session_id));
59 }
60
61 void BrowserCdmManager::OnSessionMessage(
62 int cdm_id,
63 uint32 session_id,
64 const std::vector<uint8>& message,
65 const GURL& destination_url) {
66 GURL verified_gurl = destination_url;
67 if (!verified_gurl.is_valid() && !verified_gurl.is_empty()) {
68 DLOG(WARNING) << "SessionMessage destination_url is invalid : "
69 << destination_url.possibly_invalid_spec();
70 verified_gurl = GURL::EmptyGURL(); // Replace invalid destination_url.
71 }
72
73 Send(new CdmMsg_SessionMessage(
74 RoutingID(), cdm_id, session_id, message, verified_gurl));
75 }
76
77 void BrowserCdmManager::OnSessionReady(int cdm_id, uint32 session_id) {
78 Send(new CdmMsg_SessionReady(RoutingID(), cdm_id, session_id));
79 }
80
81 void BrowserCdmManager::OnSessionClosed(int cdm_id, uint32 session_id) {
82 Send(new CdmMsg_SessionClosed(RoutingID(), cdm_id, session_id));
83 }
84
85 void BrowserCdmManager::OnSessionError(int cdm_id,
86 uint32 session_id,
87 MediaKeys::KeyError error_code,
88 uint32 system_code) {
89 Send(new CdmMsg_SessionError(
90 RoutingID(), cdm_id, session_id, error_code, system_code));
91 }
92
93 void BrowserCdmManager::OnInitializeCdm(int cdm_id,
94 const std::string& key_system,
95 const GURL& security_origin) {
96 if (key_system.size() > kMaxKeySystemLength) {
97 // This failure will be discovered and reported by OnCreateSession()
98 // as GetCdm() will return null.
99 NOTREACHED() << "Invalid key system: " << key_system;
100 return;
101 }
102
103 AddCdm(cdm_id, key_system, security_origin);
104 }
105
106 void BrowserCdmManager::OnCreateSession(
107 int cdm_id,
108 uint32 session_id,
109 CdmHostMsg_CreateSession_ContentType content_type,
110 const std::vector<uint8>& init_data) {
111 if (init_data.size() > kMaxInitDataLength) {
112 LOG(WARNING) << "InitData for ID: " << cdm_id
113 << " too long: " << init_data.size();
114 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
115 return;
116 }
117
118 // Convert the session content type into a MIME type. "audio" and "video"
119 // don't matter, so using "video" for the MIME type.
120 // Ref:
121 // https://dvcs.w3.org/hg/html-media/raw-file/default/encrypted-media/encrypte d-media.html#dom-createsession
122 std::string mime_type;
123 switch (content_type) {
124 case CREATE_SESSION_TYPE_WEBM:
125 mime_type = "video/webm";
126 break;
127 case CREATE_SESSION_TYPE_MP4:
128 mime_type = "video/mp4";
129 break;
130 default:
131 NOTREACHED();
132 return;
133 }
134
135 #if defined(OS_ANDROID)
136 if (CommandLine::ForCurrentProcess()
137 ->HasSwitch(switches::kDisableInfobarForProtectedMediaIdentifier)) {
138 CreateSessionIfPermitted(cdm_id, session_id, mime_type, init_data, true);
139 return;
140 }
141 #endif
142
143 BrowserCdm* cdm = GetCdm(cdm_id);
144 if (!cdm) {
145 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
146 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
147 return;
148 }
149
150 BrowserContext* context =
151 web_contents_->GetRenderProcessHost()->GetBrowserContext();
152
153 std::map<int, GURL>::const_iterator iter =
154 cdm_security_origin_map_.find(cdm_id);
155 if (iter == cdm_security_origin_map_.end()) {
156 NOTREACHED();
157 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
158 return;
159 }
160
161 context->RequestProtectedMediaIdentifierPermission(
162 web_contents_->GetRenderProcessHost()->GetID(),
163 web_contents_->GetRenderViewHost()->GetRoutingID(),
164 iter->second,
165 base::Bind(&BrowserCdmManager::CreateSessionIfPermitted,
166 weak_ptr_factory_.GetWeakPtr(),
167 cdm_id,
168 session_id,
169 mime_type,
170 init_data));
171 }
172
173 void BrowserCdmManager::OnUpdateSession(
174 int cdm_id,
175 uint32 session_id,
176 const std::vector<uint8>& response) {
177 BrowserCdm* cdm = GetCdm(cdm_id);
178 if (!cdm) {
179 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
180 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
181 return;
182 }
183
184 if (response.size() > kMaxSessionResponseLength) {
185 LOG(WARNING) << "Response for ID " << cdm_id
186 << " is too long: " << response.size();
187 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
188 return;
189 }
190
191 cdm->UpdateSession(session_id, &response[0], response.size());
192 }
193
194 void BrowserCdmManager::OnReleaseSession(int cdm_id, uint32 session_id) {
195 BrowserCdm* cdm = GetCdm(cdm_id);
196 if (!cdm) {
197 DLOG(WARNING) << "No CDM for ID " << cdm_id << " found";
198 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
199 return;
200 }
201
202 cdm->ReleaseSession(session_id);
203 }
204
205 void BrowserCdmManager::OnDestroyCdm(int cdm_id) {
206 BrowserCdm* cdm = GetCdm(cdm_id);
207 if (!cdm)
208 return;
209
210 CancelAllPendingSessionCreations(cdm_id);
211 RemoveCdm(cdm_id);
212 }
213
214 void BrowserCdmManager::CancelAllPendingSessionCreations(int cdm_id) {
215 BrowserContext* context =
216 web_contents_->GetRenderProcessHost()->GetBrowserContext();
217 std::map<int, GURL>::const_iterator iter =
218 cdm_security_origin_map_.find(cdm_id);
219 if (iter == cdm_security_origin_map_.end())
220 return;
221 context->CancelProtectedMediaIdentifierPermissionRequests(
222 web_contents_->GetRenderProcessHost()->GetID(),
223 web_contents_->GetRenderViewHost()->GetRoutingID(),
224 iter->second);
225 }
226
227 void BrowserCdmManager::AddCdm(int cdm_id,
228 const std::string& key_system,
229 const GURL& security_origin) {
230 DCHECK(!GetCdm(cdm_id));
231 base::WeakPtr<BrowserCdmManager> weak_this = weak_ptr_factory_.GetWeakPtr();
232 scoped_ptr<BrowserCdm> cdm(media::CreateBrowserCdm(
233 key_system,
234 base::Bind(&BrowserCdmManager::OnSessionCreated, weak_this, cdm_id),
235 base::Bind(&BrowserCdmManager::OnSessionMessage, weak_this, cdm_id),
236 base::Bind(&BrowserCdmManager::OnSessionReady, weak_this, cdm_id),
237 base::Bind(&BrowserCdmManager::OnSessionClosed, weak_this, cdm_id),
238 base::Bind(&BrowserCdmManager::OnSessionError, weak_this, cdm_id)));
239
240 if (!cdm) {
241 // This failure will be discovered and reported by OnCreateSession()
242 // as GetCdm() will return null.
243 DVLOG(1) << "failed to create CDM.";
244 return;
245 }
246
247 cdm_map_[cdm_id] = cdm.release();
248 cdm_security_origin_map_[cdm_id] = security_origin;
249 }
250
251 void BrowserCdmManager::RemoveCdm(int cdm_id) {
252 // TODO(xhwang): Detach CDM from the player it's set to. In prefixed
253 // EME implementation the current code is fine because we always destroy the
254 // player before we destroy the DrmBridge. This will not always be the case
255 // in unprefixed EME implementation.
256 CdmMap::iterator iter = cdm_map_.find(cdm_id);
257 if (iter != cdm_map_.end()) {
258 delete iter->second;
259 cdm_map_.erase(iter);
260 }
261 cdm_security_origin_map_.erase(cdm_id);
262 }
263
264 int BrowserCdmManager::RoutingID() {
265 return render_frame_host_->GetRoutingID();
266 }
267
268 bool BrowserCdmManager::Send(IPC::Message* msg) {
269 return render_frame_host_->Send(msg);
270 }
271
272 void BrowserCdmManager::CreateSessionIfPermitted(
273 int cdm_id,
274 uint32 session_id,
275 const std::string& content_type,
276 const std::vector<uint8>& init_data,
277 bool permitted) {
278 if (!permitted) {
279 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
280 return;
281 }
282
283 BrowserCdm* cdm = GetCdm(cdm_id);
284 if (!cdm) {
285 DLOG(WARNING) << "No CDM for ID: " << cdm_id << " found";
286 OnSessionError(cdm_id, session_id, MediaKeys::kUnknownError, 0);
287 return;
288 }
289
290 // This could fail, in which case a SessionError will be fired.
291 cdm->CreateSession(session_id, content_type, &init_data[0], init_data.size());
292 }
293
294 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/media/android/browser_cdm_manager.h ('k') | content/browser/media/android/media_web_contents_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698