1/* 2 * Copyright (C) 2012 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * 3. Neither the name of Google Inc. nor the names of its contributors 15 * may be used to endorse or promote products derived from this 16 * software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 29 */ 30 31#include "config.h" 32 33#include "modules/mediastream/MediaConstraintsImpl.h" 34 35#include "bindings/core/v8/ArrayValue.h" 36#include "bindings/core/v8/Dictionary.h" 37#include "bindings/core/v8/ExceptionState.h" 38#include "core/dom/ExceptionCode.h" 39#include "wtf/HashMap.h" 40#include "wtf/Vector.h" 41#include "wtf/text/StringHash.h" 42 43namespace blink { 44 45namespace MediaConstraintsImpl { 46 47static bool parse(const Dictionary& constraintsDictionary, WebVector<WebMediaConstraint>& optional, WebVector<WebMediaConstraint>& mandatory) 48{ 49 if (constraintsDictionary.isUndefinedOrNull()) 50 return true; 51 52 Vector<String> names; 53 constraintsDictionary.getOwnPropertyNames(names); 54 55 String mandatoryName("mandatory"); 56 String optionalName("optional"); 57 58 for (Vector<String>::iterator it = names.begin(); it != names.end(); ++it) { 59 if (*it != mandatoryName && *it != optionalName) 60 return false; 61 } 62 63 Vector<WebMediaConstraint> mandatoryConstraintsVector; 64 if (names.contains(mandatoryName)) { 65 Dictionary mandatoryConstraintsDictionary; 66 bool ok = constraintsDictionary.get(mandatoryName, mandatoryConstraintsDictionary); 67 if (!ok || mandatoryConstraintsDictionary.isUndefinedOrNull()) 68 return false; 69 70 HashMap<String, String> mandatoryConstraintsHashMap; 71 ok = mandatoryConstraintsDictionary.getOwnPropertiesAsStringHashMap(mandatoryConstraintsHashMap); 72 if (!ok) 73 return false; 74 75 HashMap<String, String>::const_iterator iter = mandatoryConstraintsHashMap.begin(); 76 for (; iter != mandatoryConstraintsHashMap.end(); ++iter) 77 mandatoryConstraintsVector.append(WebMediaConstraint(iter->key, iter->value)); 78 } 79 80 Vector<WebMediaConstraint> optionalConstraintsVector; 81 if (names.contains(optionalName)) { 82 ArrayValue optionalConstraints; 83 bool ok = DictionaryHelper::get(constraintsDictionary, optionalName, optionalConstraints); 84 if (!ok || optionalConstraints.isUndefinedOrNull()) 85 return false; 86 87 size_t numberOfConstraints; 88 ok = optionalConstraints.length(numberOfConstraints); 89 if (!ok) 90 return false; 91 92 for (size_t i = 0; i < numberOfConstraints; ++i) { 93 Dictionary constraint; 94 ok = optionalConstraints.get(i, constraint); 95 if (!ok || constraint.isUndefinedOrNull()) 96 return false; 97 Vector<String> localNames; 98 constraint.getOwnPropertyNames(localNames); 99 if (localNames.size() != 1) 100 return false; 101 String key = localNames[0]; 102 String value; 103 ok = DictionaryHelper::get(constraint, key, value); 104 if (!ok) 105 return false; 106 optionalConstraintsVector.append(WebMediaConstraint(key, value)); 107 } 108 } 109 110 optional.assign(optionalConstraintsVector); 111 mandatory.assign(mandatoryConstraintsVector); 112 return true; 113} 114 115 116WebMediaConstraints create(const Dictionary& constraintsDictionary, ExceptionState& exceptionState) 117{ 118 WebVector<WebMediaConstraint> optional; 119 WebVector<WebMediaConstraint> mandatory; 120 if (!parse(constraintsDictionary, optional, mandatory)) { 121 exceptionState.throwTypeError("Malformed constraints object."); 122 return WebMediaConstraints(); 123 } 124 125 WebMediaConstraints constraints; 126 constraints.initialize(optional, mandatory); 127 return constraints; 128} 129 130WebMediaConstraints create() 131{ 132 WebMediaConstraints constraints; 133 constraints.initialize(); 134 return constraints; 135} 136 137} // namespace MediaConstraintsImpl 138} // namespace blink 139