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/v8/ArrayValue.h" 36 #include "bindings/v8/Dictionary.h" 37 #include "bindings/v8/ExceptionState.h" 38 #include "core/dom/ExceptionCode.h" 39 #include "wtf/text/StringHash.h" 40 41 namespace WebCore { 42 43 PassRefPtr<MediaConstraintsImpl> MediaConstraintsImpl::create(const Dictionary& constraints, ExceptionState& exceptionState) 44 { 45 RefPtr<MediaConstraintsImpl> object = adoptRef(new MediaConstraintsImpl()); 46 if (!object->initialize(constraints)) { 47 exceptionState.throwUninformativeAndGenericDOMException(TypeMismatchError); 48 return 0; 49 } 50 return object.release(); 51 } 52 53 PassRefPtr<MediaConstraintsImpl> MediaConstraintsImpl::create() 54 { 55 return adoptRef(new MediaConstraintsImpl()); 56 } 57 58 bool MediaConstraintsImpl::initialize(const Dictionary& constraints) 59 { 60 if (constraints.isUndefinedOrNull()) 61 return true; 62 63 Vector<String> names; 64 constraints.getOwnPropertyNames(names); 65 66 String mandatory("mandatory"); 67 String optional("optional"); 68 69 for (Vector<String>::iterator it = names.begin(); it != names.end(); ++it) { 70 if (*it != mandatory && *it != optional) 71 return false; 72 } 73 74 if (names.contains(mandatory)) { 75 Dictionary mandatoryConstraints; 76 bool ok = constraints.get(mandatory, mandatoryConstraints); 77 if (!ok || mandatoryConstraints.isUndefinedOrNull()) 78 return false; 79 80 ok = mandatoryConstraints.getOwnPropertiesAsStringHashMap(m_mandatoryConstraints); 81 if (!ok) 82 return false; 83 } 84 85 if (names.contains(optional)) { 86 ArrayValue optionalConstraints; 87 bool ok = constraints.get(optional, optionalConstraints); 88 if (!ok || optionalConstraints.isUndefinedOrNull()) 89 return false; 90 91 size_t numberOfConstraints; 92 ok = optionalConstraints.length(numberOfConstraints); 93 if (!ok) 94 return false; 95 96 for (size_t i = 0; i < numberOfConstraints; ++i) { 97 Dictionary constraint; 98 ok = optionalConstraints.get(i, constraint); 99 if (!ok || constraint.isUndefinedOrNull()) 100 return false; 101 Vector<String> localNames; 102 constraint.getOwnPropertyNames(localNames); 103 if (localNames.size() != 1) 104 return false; 105 String key = localNames[0]; 106 String value; 107 ok = constraint.get(key, value); 108 if (!ok) 109 return false; 110 m_optionalConstraints.append(MediaConstraint(key, value)); 111 } 112 } 113 114 return true; 115 } 116 117 MediaConstraintsImpl::~MediaConstraintsImpl() 118 { 119 } 120 121 void MediaConstraintsImpl::getMandatoryConstraints(Vector<MediaConstraint>& constraints) const 122 { 123 constraints.clear(); 124 HashMap<String, String>::const_iterator i = m_mandatoryConstraints.begin(); 125 for (; i != m_mandatoryConstraints.end(); ++i) 126 constraints.append(MediaConstraint(i->key, i->value)); 127 } 128 129 void MediaConstraintsImpl::getOptionalConstraints(Vector<MediaConstraint>& constraints) const 130 { 131 constraints.clear(); 132 constraints.append(m_optionalConstraints); 133 } 134 135 bool MediaConstraintsImpl::getMandatoryConstraintValue(const String& name, String& value) const 136 { 137 HashMap<String, String>::const_iterator i = m_mandatoryConstraints.find(name); 138 if (i == m_mandatoryConstraints.end()) 139 return false; 140 141 value = i->value; 142 return true; 143 } 144 145 bool MediaConstraintsImpl::getOptionalConstraintValue(const String& name, String& value) const 146 { 147 Vector<MediaConstraint>::const_iterator i = m_optionalConstraints.begin(); 148 for (; i != m_optionalConstraints.end(); ++i) { 149 if (i->m_name == name) { 150 value = i->m_value; 151 return true; 152 } 153 } 154 155 return false; 156 } 157 158 } // namespace WebCore 159