OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 16 matching lines...) Expand all Loading... |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "modules/mediastream/MediaConstraintsImpl.h" | 31 #include "modules/mediastream/MediaConstraintsImpl.h" |
32 | 32 |
33 #include "bindings/core/v8/ArrayValue.h" | 33 #include "bindings/core/v8/ArrayValue.h" |
34 #include "bindings/core/v8/Dictionary.h" | 34 #include "bindings/core/v8/Dictionary.h" |
35 #include "bindings/core/v8/ExceptionState.h" | 35 #include "bindings/core/v8/ExceptionState.h" |
36 #include "core/dom/ExceptionCode.h" | 36 #include "core/dom/ExceptionCode.h" |
| 37 #include "core/dom/ExecutionContext.h" |
37 #include "core/frame/UseCounter.h" | 38 #include "core/frame/UseCounter.h" |
| 39 #include "core/inspector/ConsoleMessage.h" |
38 #include "modules/mediastream/MediaTrackConstraintSet.h" | 40 #include "modules/mediastream/MediaTrackConstraintSet.h" |
39 #include "platform/Logging.h" | 41 #include "platform/Logging.h" |
40 #include "platform/RuntimeEnabledFeatures.h" | 42 #include "platform/RuntimeEnabledFeatures.h" |
41 #include "wtf/HashMap.h" | 43 #include "wtf/HashMap.h" |
42 #include "wtf/Vector.h" | 44 #include "wtf/Vector.h" |
43 #include "wtf/text/StringHash.h" | 45 #include "wtf/text/StringHash.h" |
44 | 46 |
45 namespace blink { | 47 namespace blink { |
46 | 48 |
47 namespace MediaConstraintsImpl { | 49 namespace MediaConstraintsImpl { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 const char kScreencastMinBitrate[] = "googScreencastMinBitrate"; | 118 const char kScreencastMinBitrate[] = "googScreencastMinBitrate"; |
117 const char kCpuOveruseDetection[] = "googCpuOveruseDetection"; | 119 const char kCpuOveruseDetection[] = "googCpuOveruseDetection"; |
118 const char kCpuUnderuseThreshold[] = "googCpuUnderuseThreshold"; | 120 const char kCpuUnderuseThreshold[] = "googCpuUnderuseThreshold"; |
119 const char kCpuOveruseThreshold[] = "googCpuOveruseThreshold"; | 121 const char kCpuOveruseThreshold[] = "googCpuOveruseThreshold"; |
120 const char kCpuUnderuseEncodeRsdThreshold[] = "googCpuUnderuseEncodeRsdThreshold
"; | 122 const char kCpuUnderuseEncodeRsdThreshold[] = "googCpuUnderuseEncodeRsdThreshold
"; |
121 const char kCpuOveruseEncodeRsdThreshold[] = "googCpuOveruseEncodeRsdThreshold"; | 123 const char kCpuOveruseEncodeRsdThreshold[] = "googCpuOveruseEncodeRsdThreshold"; |
122 const char kCpuOveruseEncodeUsage[] = "googCpuOveruseEncodeUsage"; | 124 const char kCpuOveruseEncodeUsage[] = "googCpuOveruseEncodeUsage"; |
123 const char kHighStartBitrate[] = "googHighStartBitrate"; | 125 const char kHighStartBitrate[] = "googHighStartBitrate"; |
124 const char kPayloadPadding[] = "googPayloadPadding"; | 126 const char kPayloadPadding[] = "googPayloadPadding"; |
125 // End of names from libjingle | 127 // End of names from libjingle |
| 128 // Names that have been used in the past, but should now be ignored. |
| 129 // Kept around for backwards compatibility. |
| 130 // https://crbug.com/579729 |
| 131 const char kGoogLeakyBucket[] = "googLeakyBucket"; |
126 | 132 |
127 // Names used for testing. | 133 // Names used for testing. |
128 const char kTestConstraint1[] = "valid_and_supported_1"; | 134 const char kTestConstraint1[] = "valid_and_supported_1"; |
129 const char kTestConstraint2[] = "valid_and_supported_2"; | 135 const char kTestConstraint2[] = "valid_and_supported_2"; |
130 | 136 |
131 static bool parseMandatoryConstraintsDictionary(const Dictionary& mandatoryConst
raintsDictionary, WebVector<WebMediaConstraint>& mandatory) | 137 static bool parseMandatoryConstraintsDictionary(const Dictionary& mandatoryConst
raintsDictionary, WebVector<WebMediaConstraint>& mandatory) |
132 { | 138 { |
133 Vector<WebMediaConstraint> mandatoryConstraintsVector; | 139 Vector<WebMediaConstraint> mandatoryConstraintsVector; |
134 HashMap<String, String> mandatoryConstraintsHashMap; | 140 HashMap<String, String> mandatoryConstraintsHashMap; |
135 bool ok = mandatoryConstraintsDictionary.getOwnPropertiesAsStringHashMap(man
datoryConstraintsHashMap); | 141 bool ok = mandatoryConstraintsDictionary.getOwnPropertiesAsStringHashMap(man
datoryConstraintsHashMap); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 return true; | 246 return true; |
241 } | 247 } |
242 | 248 |
243 static bool toBoolean(const WebString& asWebString) | 249 static bool toBoolean(const WebString& asWebString) |
244 { | 250 { |
245 return asWebString.equals("true"); | 251 return asWebString.equals("true"); |
246 // TODO(hta): Check against "false" and return error if it's neither. | 252 // TODO(hta): Check against "false" and return error if it's neither. |
247 // https://crbug.com/576582 | 253 // https://crbug.com/576582 |
248 } | 254 } |
249 | 255 |
250 static void parseOldStyleNames(const WebVector<WebMediaConstraint>& oldNames, We
bMediaTrackConstraintSet& result, MediaErrorState& errorState) | 256 static void parseOldStyleNames(ExecutionContext* context, const WebVector<WebMed
iaConstraint>& oldNames, bool reportUnknownNames, WebMediaTrackConstraintSet& re
sult, MediaErrorState& errorState) |
251 { | 257 { |
252 for (const WebMediaConstraint& constraint : oldNames) { | 258 for (const WebMediaConstraint& constraint : oldNames) { |
253 if (constraint.m_name.equals(kMinAspectRatio)) { | 259 if (constraint.m_name.equals(kMinAspectRatio)) { |
254 result.aspectRatio.setMin(atof(constraint.m_value.utf8().c_str())); | 260 result.aspectRatio.setMin(atof(constraint.m_value.utf8().c_str())); |
255 } else if (constraint.m_name.equals(kMaxAspectRatio)) { | 261 } else if (constraint.m_name.equals(kMaxAspectRatio)) { |
256 result.aspectRatio.setMax(atof(constraint.m_value.utf8().c_str())); | 262 result.aspectRatio.setMax(atof(constraint.m_value.utf8().c_str())); |
257 } else if (constraint.m_name.equals(kMaxWidth)) { | 263 } else if (constraint.m_name.equals(kMaxWidth)) { |
258 result.width.setMax(atoi(constraint.m_value.utf8().c_str())); | 264 result.width.setMax(atoi(constraint.m_value.utf8().c_str())); |
259 } else if (constraint.m_name.equals(kMinWidth)) { | 265 } else if (constraint.m_name.equals(kMinWidth)) { |
260 result.width.setMin(atoi(constraint.m_value.utf8().c_str())); | 266 result.width.setMin(atoi(constraint.m_value.utf8().c_str())); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
346 } else if (constraint.m_name.equals(kCpuUnderuseEncodeRsdThreshold)) { | 352 } else if (constraint.m_name.equals(kCpuUnderuseEncodeRsdThreshold)) { |
347 result.googCpuUnderuseEncodeRsdThreshold.setExact(atoi(constraint.m_
value.utf8().c_str())); | 353 result.googCpuUnderuseEncodeRsdThreshold.setExact(atoi(constraint.m_
value.utf8().c_str())); |
348 } else if (constraint.m_name.equals(kCpuOveruseEncodeRsdThreshold)) { | 354 } else if (constraint.m_name.equals(kCpuOveruseEncodeRsdThreshold)) { |
349 result.googCpuOveruseEncodeRsdThreshold.setExact(atoi(constraint.m_v
alue.utf8().c_str())); | 355 result.googCpuOveruseEncodeRsdThreshold.setExact(atoi(constraint.m_v
alue.utf8().c_str())); |
350 } else if (constraint.m_name.equals(kCpuOveruseEncodeUsage)) { | 356 } else if (constraint.m_name.equals(kCpuOveruseEncodeUsage)) { |
351 result.googCpuOveruseEncodeUsage.setExact(toBoolean(constraint.m_val
ue)); | 357 result.googCpuOveruseEncodeUsage.setExact(toBoolean(constraint.m_val
ue)); |
352 } else if (constraint.m_name.equals(kHighStartBitrate)) { | 358 } else if (constraint.m_name.equals(kHighStartBitrate)) { |
353 result.googHighStartBitrate.setExact(atoi(constraint.m_value.utf8().
c_str())); | 359 result.googHighStartBitrate.setExact(atoi(constraint.m_value.utf8().
c_str())); |
354 } else if (constraint.m_name.equals(kPayloadPadding)) { | 360 } else if (constraint.m_name.equals(kPayloadPadding)) { |
355 result.googPayloadPadding.setExact(toBoolean(constraint.m_value)); | 361 result.googPayloadPadding.setExact(toBoolean(constraint.m_value)); |
| 362 } else if (constraint.m_name.equals(kGoogLeakyBucket)) { |
| 363 context->addConsoleMessage(ConsoleMessage::create(DeprecationMessage
Source, WarningMessageLevel, |
| 364 "Obsolete constraint named " + String(constraint.m_name) |
| 365 + " is ignored. Please stop using it.")); |
356 } else if (constraint.m_name.equals(kTestConstraint1) | 366 } else if (constraint.m_name.equals(kTestConstraint1) |
357 || constraint.m_name.equals(kTestConstraint2)) { | 367 || constraint.m_name.equals(kTestConstraint2)) { |
358 // These constraints are only for testing parsing. | 368 // These constraints are only for testing parsing. |
359 // Values 0 and 1 are legal, all others are a ConstraintError. | 369 // Values 0 and 1 are legal, all others are a ConstraintError. |
360 if (!constraint.m_value.equals("0") && !constraint.m_value.equals("1
")) | 370 if (!constraint.m_value.equals("0") && !constraint.m_value.equals("1
")) { |
361 errorState.throwConstraintError("Illegal value for constraint",
constraint.m_name); | 371 errorState.throwConstraintError("Illegal value for constraint",
constraint.m_name); |
| 372 } |
362 } else { | 373 } else { |
363 // TODO(hta): UMA stats for unknown constraints passed. | 374 if (reportUnknownNames) { |
364 // https://crbug.com/576613 | 375 // TODO(hta): UMA stats for unknown constraints passed. |
365 WTF_LOG(Media, "Unknown constraint name detected"); | 376 // https://crbug.com/576613 |
366 errorState.throwConstraintError("Unknown name of constraint detected
", constraint.m_name); | 377 context->addConsoleMessage( |
| 378 ConsoleMessage::create( |
| 379 DeprecationMessageSource, |
| 380 WarningMessageLevel, |
| 381 "Unknown constraint named " |
| 382 + String(constraint.m_name) + " rejected")); |
| 383 errorState.throwConstraintError("Unknown name of constraint dete
cted", constraint.m_name); |
| 384 } |
367 } | 385 } |
368 } | 386 } |
369 } | 387 } |
370 | 388 |
371 static WebMediaConstraints createFromNamedConstraints(WebVector<WebMediaConstrai
nt>& mandatory, const WebVector<WebMediaConstraint>& optional, MediaErrorState&
errorState) | 389 static WebMediaConstraints createFromNamedConstraints(ExecutionContext* context,
WebVector<WebMediaConstraint>& mandatory, const WebVector<WebMediaConstraint>&
optional, MediaErrorState& errorState) |
372 { | 390 { |
373 WebMediaTrackConstraintSet basic; | 391 WebMediaTrackConstraintSet basic; |
374 WebMediaTrackConstraintSet advanced; | 392 WebMediaTrackConstraintSet advanced; |
375 WebMediaConstraints constraints; | 393 WebMediaConstraints constraints; |
376 parseOldStyleNames(mandatory, basic, errorState); | 394 parseOldStyleNames(context, mandatory, true, basic, errorState); |
377 if (errorState.hadException()) | 395 if (errorState.hadException()) |
378 return constraints; | 396 return constraints; |
379 // We ignore errors in optional constraints. | 397 // We ignore unknow names and syntax errors in optional constraints. |
380 MediaErrorState ignoredErrorState; | 398 MediaErrorState ignoredErrorState; |
381 parseOldStyleNames(optional, advanced, ignoredErrorState); | 399 parseOldStyleNames(context, optional, false, advanced, ignoredErrorState); |
382 WebVector<WebMediaTrackConstraintSet> advancedVector(&advanced, 1); | 400 WebVector<WebMediaTrackConstraintSet> advancedVector(&advanced, 1); |
383 // Use the 4-argument initializer until Chrome has been converted. | 401 // Use the 4-argument initializer until Chrome has been converted. |
384 constraints.initialize(optional, mandatory, basic, advancedVector); | 402 constraints.initialize(optional, mandatory, basic, advancedVector); |
385 return constraints; | 403 return constraints; |
386 } | 404 } |
387 | 405 |
388 // Deprecated. | 406 // Deprecated. |
389 WebMediaConstraints create(const ExecutionContext* context, const Dictionary& co
nstraintsDictionary, MediaErrorState& errorState) | 407 WebMediaConstraints create(ExecutionContext* context, const Dictionary& constrai
ntsDictionary, MediaErrorState& errorState) |
390 { | 408 { |
391 WebVector<WebMediaConstraint> optional; | 409 WebVector<WebMediaConstraint> optional; |
392 WebVector<WebMediaConstraint> mandatory; | 410 WebVector<WebMediaConstraint> mandatory; |
393 if (!parse(constraintsDictionary, optional, mandatory)) { | 411 if (!parse(constraintsDictionary, optional, mandatory)) { |
394 errorState.throwTypeError("Malformed constraints object."); | 412 errorState.throwTypeError("Malformed constraints object."); |
395 return WebMediaConstraints(); | 413 return WebMediaConstraints(); |
396 } | 414 } |
397 UseCounter::count(context, UseCounter::MediaStreamConstraintsFromDictionary)
; | 415 UseCounter::count(context, UseCounter::MediaStreamConstraintsFromDictionary)
; |
398 return createFromNamedConstraints(mandatory, optional, errorState); | 416 return createFromNamedConstraints(context, mandatory, optional, errorState); |
399 } | 417 } |
400 | 418 |
401 void copyLongConstraint(const ConstrainLongRange& blinkForm, LongConstraint& web
Form) | 419 void copyLongConstraint(const ConstrainLongRange& blinkForm, LongConstraint& web
Form) |
402 { | 420 { |
403 if (blinkForm.hasMin()) { | 421 if (blinkForm.hasMin()) { |
404 webForm.setMin(blinkForm.min()); | 422 webForm.setMin(blinkForm.min()); |
405 } | 423 } |
406 if (blinkForm.hasMax()) { | 424 if (blinkForm.hasMax()) { |
407 webForm.setMax(blinkForm.max()); | 425 webForm.setMax(blinkForm.max()); |
408 } | 426 } |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
486 copyLongConstraint(constraintsIn.channelCount(), constraintBuffer.channe
lCount); | 504 copyLongConstraint(constraintsIn.channelCount(), constraintBuffer.channe
lCount); |
487 } | 505 } |
488 if (constraintsIn.hasDeviceId()) { | 506 if (constraintsIn.hasDeviceId()) { |
489 copyStringConstraint(constraintsIn.deviceId(), constraintBuffer.deviceId
); | 507 copyStringConstraint(constraintsIn.deviceId(), constraintBuffer.deviceId
); |
490 } | 508 } |
491 if (constraintsIn.hasGroupId()) { | 509 if (constraintsIn.hasGroupId()) { |
492 copyStringConstraint(constraintsIn.groupId(), constraintBuffer.groupId); | 510 copyStringConstraint(constraintsIn.groupId(), constraintBuffer.groupId); |
493 } | 511 } |
494 } | 512 } |
495 | 513 |
496 WebMediaConstraints create(const ExecutionContext* context, const MediaTrackCons
traintSet& constraintsIn, MediaErrorState& errorState) | 514 WebMediaConstraints create(ExecutionContext* context, const MediaTrackConstraint
Set& constraintsIn, MediaErrorState& errorState) |
497 { | 515 { |
498 WebMediaConstraints constraints; | 516 WebMediaConstraints constraints; |
499 WebMediaTrackConstraintSet constraintBuffer; | 517 WebMediaTrackConstraintSet constraintBuffer; |
500 WebVector<WebMediaTrackConstraintSet> advancedBuffer; | 518 WebVector<WebMediaTrackConstraintSet> advancedBuffer; |
501 copyConstraints(constraintsIn, constraintBuffer); | 519 copyConstraints(constraintsIn, constraintBuffer); |
502 // TODO(hta): Add initialization of advanced constraints once present. | 520 // TODO(hta): Add initialization of advanced constraints once present. |
503 // https://crbug.com/253412 | 521 // https://crbug.com/253412 |
504 if (constraintsIn.hasOptional() || constraintsIn.hasMandatory()) { | 522 if (constraintsIn.hasOptional() || constraintsIn.hasMandatory()) { |
505 if (!constraintBuffer.isEmpty()) { | 523 if (!constraintBuffer.isEmpty()) { |
506 errorState.throwTypeError("Malformed constraint: Cannot use both opt
ional/mandatory and specific constraints."); | 524 errorState.throwTypeError("Malformed constraint: Cannot use both opt
ional/mandatory and specific constraints."); |
507 return WebMediaConstraints(); | 525 return WebMediaConstraints(); |
508 } | 526 } |
509 WebVector<WebMediaConstraint> optional; | 527 WebVector<WebMediaConstraint> optional; |
510 WebVector<WebMediaConstraint> mandatory; | 528 WebVector<WebMediaConstraint> mandatory; |
511 if (!parse(constraintsIn, optional, mandatory)) { | 529 if (!parse(constraintsIn, optional, mandatory)) { |
512 errorState.throwTypeError("Malformed constraints object."); | 530 errorState.throwTypeError("Malformed constraints object."); |
513 return WebMediaConstraints(); | 531 return WebMediaConstraints(); |
514 } | 532 } |
515 UseCounter::count(context, UseCounter::MediaStreamConstraintsNameValue); | 533 UseCounter::count(context, UseCounter::MediaStreamConstraintsNameValue); |
516 return createFromNamedConstraints(mandatory, optional, errorState); | 534 return createFromNamedConstraints(context, mandatory, optional, errorSta
te); |
517 } | 535 } |
518 UseCounter::count(context, UseCounter::MediaStreamConstraintsConformant); | 536 UseCounter::count(context, UseCounter::MediaStreamConstraintsConformant); |
519 constraints.initialize(constraintBuffer, advancedBuffer); | 537 constraints.initialize(constraintBuffer, advancedBuffer); |
520 return constraints; | 538 return constraints; |
521 } | 539 } |
522 | 540 |
523 WebMediaConstraints create() | 541 WebMediaConstraints create() |
524 { | 542 { |
525 WebMediaConstraints constraints; | 543 WebMediaConstraints constraints; |
526 constraints.initialize(); | 544 constraints.initialize(); |
527 return constraints; | 545 return constraints; |
528 } | 546 } |
529 | 547 |
530 } // namespace MediaConstraintsImpl | 548 } // namespace MediaConstraintsImpl |
531 } // namespace blink | 549 } // namespace blink |
OLD | NEW |