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

Side by Side Diff: third_party/WebKit/Source/modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.cpp

Issue 2349813002: EME: Update MediaKeySystemConfiguration defaults; require non-empty capabilities (Closed)
Patch Set: fix Android compile Created 4 years, 2 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
OLDNEW
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 "modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.h" 5 #include "modules/encryptedmedia/NavigatorRequestMediaKeySystemAccess.h"
6 6
7 #include "bindings/core/v8/ScriptPromiseResolver.h" 7 #include "bindings/core/v8/ScriptPromiseResolver.h"
8 #include "bindings/core/v8/ScriptState.h" 8 #include "bindings/core/v8/ScriptState.h"
9 #include "core/dom/DOMException.h" 9 #include "core/dom/DOMException.h"
10 #include "core/dom/Document.h" 10 #include "core/dom/Document.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 // TODO(xhwang): Remove after we handle empty robustness correctly. 122 // TODO(xhwang): Remove after we handle empty robustness correctly.
123 // See http://crbug.com/482277 123 // See http://crbug.com/482277
124 void checkVideoCapabilityRobustness() const; 124 void checkVideoCapabilityRobustness() const;
125 125
126 // Generate deprecation warning and log UseCounter if configuration 126 // Generate deprecation warning and log UseCounter if configuration
127 // contains only container-only contentType strings. 127 // contains only container-only contentType strings.
128 // TODO(jrummell): Remove once this is no longer allowed. 128 // TODO(jrummell): Remove once this is no longer allowed.
129 // See http://crbug.com/605661. 129 // See http://crbug.com/605661.
130 void checkEmptyCodecs(const WebMediaKeySystemConfiguration&); 130 void checkEmptyCodecs(const WebMediaKeySystemConfiguration&);
131 131
132 // Log UseCounter if configuration does not have at least one of
133 // 'audioCapabilities' and 'videoCapabilities' non-empty.
134 // TODO(jrummell): Switch to deprecation message once we have data.
135 // See http://crbug.com/616233.
136 void checkCapabilitiesProvided(const WebMediaKeySystemConfiguration&);
137
132 Member<ScriptPromiseResolver> m_resolver; 138 Member<ScriptPromiseResolver> m_resolver;
133 const String m_keySystem; 139 const String m_keySystem;
134 WebVector<WebMediaKeySystemConfiguration> m_supportedConfigurations; 140 WebVector<WebMediaKeySystemConfiguration> m_supportedConfigurations;
135 }; 141 };
136 142
137 MediaKeySystemAccessInitializer::MediaKeySystemAccessInitializer( 143 MediaKeySystemAccessInitializer::MediaKeySystemAccessInitializer(
138 ScriptState* scriptState, 144 ScriptState* scriptState,
139 const String& keySystem, 145 const String& keySystem,
140 const HeapVector<MediaKeySystemConfiguration>& supportedConfigurations) 146 const HeapVector<MediaKeySystemConfiguration>& supportedConfigurations)
141 : m_resolver(ScriptPromiseResolver::create(scriptState)), 147 : m_resolver(ScriptPromiseResolver::create(scriptState)),
142 m_keySystem(keySystem), 148 m_keySystem(keySystem),
143 m_supportedConfigurations(supportedConfigurations.size()) { 149 m_supportedConfigurations(supportedConfigurations.size()) {
144 for (size_t i = 0; i < supportedConfigurations.size(); ++i) { 150 for (size_t i = 0; i < supportedConfigurations.size(); ++i) {
145 const MediaKeySystemConfiguration& config = supportedConfigurations[i]; 151 const MediaKeySystemConfiguration& config = supportedConfigurations[i];
146 WebMediaKeySystemConfiguration webConfig; 152 WebMediaKeySystemConfiguration webConfig;
147 if (config.hasInitDataTypes()) { 153
148 webConfig.hasInitDataTypes = true; 154 DCHECK(config.hasInitDataTypes());
149 webConfig.initDataTypes = convertInitDataTypes(config.initDataTypes()); 155 webConfig.initDataTypes = convertInitDataTypes(config.initDataTypes());
150 } 156
151 if (config.hasAudioCapabilities()) { 157 DCHECK(config.hasAudioCapabilities());
152 webConfig.hasAudioCapabilities = true; 158 webConfig.audioCapabilities =
153 webConfig.audioCapabilities = 159 convertCapabilities(config.audioCapabilities());
154 convertCapabilities(config.audioCapabilities()); 160
155 } 161 DCHECK(config.hasVideoCapabilities());
156 if (config.hasVideoCapabilities()) { 162 webConfig.videoCapabilities =
157 webConfig.hasVideoCapabilities = true; 163 convertCapabilities(config.videoCapabilities());
158 webConfig.videoCapabilities = 164
159 convertCapabilities(config.videoCapabilities()); 165 checkCapabilitiesProvided(webConfig);
160 } 166
161 DCHECK(config.hasDistinctiveIdentifier()); 167 DCHECK(config.hasDistinctiveIdentifier());
162 webConfig.distinctiveIdentifier = 168 webConfig.distinctiveIdentifier =
163 convertMediaKeysRequirement(config.distinctiveIdentifier()); 169 convertMediaKeysRequirement(config.distinctiveIdentifier());
170
164 DCHECK(config.hasPersistentState()); 171 DCHECK(config.hasPersistentState());
165 webConfig.persistentState = 172 webConfig.persistentState =
166 convertMediaKeysRequirement(config.persistentState()); 173 convertMediaKeysRequirement(config.persistentState());
174
167 if (config.hasSessionTypes()) { 175 if (config.hasSessionTypes()) {
168 webConfig.hasSessionTypes = true;
169 webConfig.sessionTypes = convertSessionTypes(config.sessionTypes()); 176 webConfig.sessionTypes = convertSessionTypes(config.sessionTypes());
177 } else {
178 // From the spec (http://w3c.github.io/encrypted-media/#idl-def-mediakeysy stemconfiguration):
179 // If this member is not present when the dictionary is passed to
180 // requestMediaKeySystemAccess(), the dictionary will be treated
181 // as if this member is set to [ "temporary" ].
182 WebVector<WebEncryptedMediaSessionType> sessionTypes(
183 static_cast<size_t>(1));
184 sessionTypes[0] = WebEncryptedMediaSessionType::Temporary;
185 webConfig.sessionTypes = sessionTypes;
170 } 186 }
187
171 // If |label| is not present, it will be a null string. 188 // If |label| is not present, it will be a null string.
172 webConfig.label = config.label(); 189 webConfig.label = config.label();
173 m_supportedConfigurations[i] = webConfig; 190 m_supportedConfigurations[i] = webConfig;
174 } 191 }
175 192
176 checkVideoCapabilityRobustness(); 193 checkVideoCapabilityRobustness();
177 } 194 }
178 195
179 void MediaKeySystemAccessInitializer::requestSucceeded( 196 void MediaKeySystemAccessInitializer::requestSucceeded(
180 WebContentDecryptionModuleAccess* access) { 197 WebContentDecryptionModuleAccess* access) {
(...skipping 12 matching lines...) Expand all
193 210
194 void MediaKeySystemAccessInitializer::checkVideoCapabilityRobustness() const { 211 void MediaKeySystemAccessInitializer::checkVideoCapabilityRobustness() const {
195 // Only check for widevine key system. 212 // Only check for widevine key system.
196 if (keySystem() != "com.widevine.alpha") 213 if (keySystem() != "com.widevine.alpha")
197 return; 214 return;
198 215
199 bool hasVideoCapabilities = false; 216 bool hasVideoCapabilities = false;
200 bool hasEmptyRobustness = false; 217 bool hasEmptyRobustness = false;
201 218
202 for (const auto& config : m_supportedConfigurations) { 219 for (const auto& config : m_supportedConfigurations) {
203 if (!config.hasVideoCapabilities)
204 continue;
205
206 hasVideoCapabilities = true;
207
208 for (const auto& capability : config.videoCapabilities) { 220 for (const auto& capability : config.videoCapabilities) {
221 hasVideoCapabilities = true;
209 if (capability.robustness.isEmpty()) { 222 if (capability.robustness.isEmpty()) {
210 hasEmptyRobustness = true; 223 hasEmptyRobustness = true;
211 break; 224 break;
212 } 225 }
213 } 226 }
214 227
215 if (hasEmptyRobustness) 228 if (hasEmptyRobustness)
216 break; 229 break;
217 } 230 }
218 231
(...skipping 17 matching lines...) Expand all
236 249
237 void MediaKeySystemAccessInitializer::checkEmptyCodecs( 250 void MediaKeySystemAccessInitializer::checkEmptyCodecs(
238 const WebMediaKeySystemConfiguration& config) { 251 const WebMediaKeySystemConfiguration& config) {
239 // This is only checking for empty codecs in the selected configuration, 252 // This is only checking for empty codecs in the selected configuration,
240 // as apps may pass container only contentType strings for compatibility 253 // as apps may pass container only contentType strings for compatibility
241 // with other implementations. 254 // with other implementations.
242 // This will only check that all returned capabilities do not contain 255 // This will only check that all returned capabilities do not contain
243 // codecs. This avoids alerting on configurations that will continue 256 // codecs. This avoids alerting on configurations that will continue
244 // to succeed in the future once strict checking is enforced. 257 // to succeed in the future once strict checking is enforced.
245 bool areAllAudioCodecsEmpty = false; 258 bool areAllAudioCodecsEmpty = false;
246 if (config.hasAudioCapabilities && !config.audioCapabilities.isEmpty()) { 259 if (!config.audioCapabilities.isEmpty()) {
247 areAllAudioCodecsEmpty = 260 areAllAudioCodecsEmpty =
248 std::find_if(config.audioCapabilities.begin(), 261 std::find_if(config.audioCapabilities.begin(),
249 config.audioCapabilities.end(), 262 config.audioCapabilities.end(),
250 AreCodecsSpecified) == config.audioCapabilities.end(); 263 AreCodecsSpecified) == config.audioCapabilities.end();
251 } 264 }
252 265
253 bool areAllVideoCodecsEmpty = false; 266 bool areAllVideoCodecsEmpty = false;
254 if (config.hasVideoCapabilities && !config.videoCapabilities.isEmpty()) { 267 if (!config.videoCapabilities.isEmpty()) {
255 areAllVideoCodecsEmpty = 268 areAllVideoCodecsEmpty =
256 std::find_if(config.videoCapabilities.begin(), 269 std::find_if(config.videoCapabilities.begin(),
257 config.videoCapabilities.end(), 270 config.videoCapabilities.end(),
258 AreCodecsSpecified) == config.videoCapabilities.end(); 271 AreCodecsSpecified) == config.videoCapabilities.end();
259 } 272 }
260 273
261 if (areAllAudioCodecsEmpty || areAllVideoCodecsEmpty) { 274 if (areAllAudioCodecsEmpty || areAllVideoCodecsEmpty) {
262 Deprecation::countDeprecation( 275 Deprecation::countDeprecation(
263 m_resolver->getExecutionContext(), 276 m_resolver->getExecutionContext(),
264 UseCounter::EncryptedMediaAllSelectedContentTypesMissingCodecs); 277 UseCounter::EncryptedMediaAllSelectedContentTypesMissingCodecs);
265 } else { 278 } else {
266 UseCounter::count( 279 UseCounter::count(
267 m_resolver->getExecutionContext(), 280 m_resolver->getExecutionContext(),
268 UseCounter::EncryptedMediaAllSelectedContentTypesHaveCodecs); 281 UseCounter::EncryptedMediaAllSelectedContentTypesHaveCodecs);
269 } 282 }
270 } 283 }
271 284
285 void MediaKeySystemAccessInitializer::checkCapabilitiesProvided(
286 const WebMediaKeySystemConfiguration& config) {
287 bool atLeastOneAudioCapability = config.audioCapabilities.size() > 0;
288 bool atLeastOneVideoCapability = config.videoCapabilities.size() > 0;
289
290 if (atLeastOneAudioCapability || atLeastOneVideoCapability) {
291 UseCounter::count(m_resolver->getExecutionContext(),
292 UseCounter::EncryptedMediaCapabilityProvided);
293 } else {
294 // TODO(jrummell): Switch to deprecation message once we understand
295 // current usage. http://crbug.com/616233.
296 UseCounter::count(m_resolver->getExecutionContext(),
297 UseCounter::EncryptedMediaCapabilityNotProvided);
298 }
299 }
300
272 } // namespace 301 } // namespace
273 302
274 ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess( 303 ScriptPromise NavigatorRequestMediaKeySystemAccess::requestMediaKeySystemAccess(
275 ScriptState* scriptState, 304 ScriptState* scriptState,
276 Navigator& navigator, 305 Navigator& navigator,
277 const String& keySystem, 306 const String& keySystem,
278 const HeapVector<MediaKeySystemConfiguration>& supportedConfigurations) { 307 const HeapVector<MediaKeySystemConfiguration>& supportedConfigurations) {
279 DVLOG(3) << __func__; 308 DVLOG(3) << __func__;
280 309
281 // From https://w3c.github.io/encrypted-media/#requestMediaKeySystemAccess 310 // From https://w3c.github.io/encrypted-media/#requestMediaKeySystemAccess
282 // When this method is invoked, the user agent must run the following steps: 311 // When this method is invoked, the user agent must run the following steps:
283 // 1. If keySystem is an empty string, return a promise rejected with a 312 // 1. If keySystem is an empty string, return a promise rejected with a
284 // new DOMException whose name is InvalidAccessError. 313 // new DOMException whose name is InvalidAccessError.
285 if (keySystem.isEmpty()) { 314 if (keySystem.isEmpty()) {
286 return ScriptPromise::rejectWithDOMException( 315 return ScriptPromise::rejectWithDOMException(
287 scriptState, DOMException::create(InvalidAccessError, 316 scriptState, DOMException::create(InvalidAccessError,
288 "The keySystem parameter is empty.")); 317 "The keySystem parameter is empty."));
289 } 318 }
290 319
291 // 2. If supportedConfigurations was provided and is empty, return a 320 // 2. If supportedConfigurations was provided and is empty, return a
292 // promise rejected with a new DOMException whose name is 321 // promise rejected with a new DOMException whose name is
293 // InvalidAccessError. 322 // InvalidAccessError.
294 if (!supportedConfigurations.size()) { 323 if (!supportedConfigurations.size()) {
295 return ScriptPromise::rejectWithDOMException( 324 return ScriptPromise::rejectWithDOMException(
296 scriptState, DOMException::create( 325 scriptState, DOMException::create(
297 InvalidAccessError, 326 InvalidAccessError,
298 "The supportedConfigurations parameter is empty.")); 327 "The supportedConfigurations parameter is empty."));
299 } 328 }
300 329
301 // 3-4. 'May Document use powerful features?' check. 330 // Note: This method should only be exposed to secure contexts as indicated
331 // by the [SecureContext] IDL attribute. Since that will break some existing
332 // sites, we simply keep track of sites that aren't secure and output a
333 // deprecation message.
302 ExecutionContext* executionContext = scriptState->getExecutionContext(); 334 ExecutionContext* executionContext = scriptState->getExecutionContext();
303 String errorMessage; 335 String errorMessage;
304 if (executionContext->isSecureContext(errorMessage)) { 336 if (executionContext->isSecureContext(errorMessage)) {
305 UseCounter::count(executionContext, UseCounter::EncryptedMediaSecureOrigin); 337 UseCounter::count(executionContext, UseCounter::EncryptedMediaSecureOrigin);
306 } else { 338 } else {
307 Deprecation::countDeprecation(executionContext, 339 Deprecation::countDeprecation(executionContext,
308 UseCounter::EncryptedMediaInsecureOrigin); 340 UseCounter::EncryptedMediaInsecureOrigin);
309 // TODO(ddorwin): Implement the following: 341 // TODO(ddorwin): Implement the following:
310 // Reject promise with a new DOMException whose name is NotSupportedError. 342 // Reject promise with a new DOMException whose name is NotSupportedError.
311 } 343 }
312 344
313 // 5. Let origin be the origin of document. 345 // 3. Let document be the calling context's Document.
314 // (Passed with the execution context in step 7.)
315
316 // 6. Let promise be a new promise.
317 Document* document = toDocument(executionContext); 346 Document* document = toDocument(executionContext);
318 if (!document->page()) { 347 if (!document->page()) {
319 return ScriptPromise::rejectWithDOMException( 348 return ScriptPromise::rejectWithDOMException(
320 scriptState, 349 scriptState,
321 DOMException::create( 350 DOMException::create(
322 InvalidStateError, 351 InvalidStateError,
323 "The context provided is not associated with a page.")); 352 "The context provided is not associated with a page."));
324 } 353 }
325 354
355 // 4. Let origin be the origin of document.
356 // (Passed with the execution context.)
357
358 // 5. Let promise be a new promise.
326 MediaKeySystemAccessInitializer* initializer = 359 MediaKeySystemAccessInitializer* initializer =
327 new MediaKeySystemAccessInitializer(scriptState, keySystem, 360 new MediaKeySystemAccessInitializer(scriptState, keySystem,
328 supportedConfigurations); 361 supportedConfigurations);
329 ScriptPromise promise = initializer->promise(); 362 ScriptPromise promise = initializer->promise();
330 363
331 // 7. Asynchronously determine support, and if allowed, create and 364 // 6. Asynchronously determine support, and if allowed, create and
332 // initialize the MediaKeySystemAccess object. 365 // initialize the MediaKeySystemAccess object.
333 MediaKeysController* controller = MediaKeysController::from(document->page()); 366 MediaKeysController* controller = MediaKeysController::from(document->page());
334 WebEncryptedMediaClient* mediaClient = 367 WebEncryptedMediaClient* mediaClient =
335 controller->encryptedMediaClient(executionContext); 368 controller->encryptedMediaClient(executionContext);
336 mediaClient->requestMediaKeySystemAccess( 369 mediaClient->requestMediaKeySystemAccess(
337 WebEncryptedMediaRequest(initializer)); 370 WebEncryptedMediaRequest(initializer));
338 371
339 // 8. Return promise. 372 // 7. Return promise.
340 return promise; 373 return promise;
341 } 374 }
342 375
343 } // namespace blink 376 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698