Source/WebCore/ChangeLog

 12012-07-27 Tommy Widenflycht <tommyw@google.com>
 2
 3 Introduce a minimal RTCPeerConnection together with Dictionary changes
 4 https://bugs.webkit.org/show_bug.cgi?id=92380
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 This patch introduces a shell RTCPeerConnection together with neccecary changes to
 9 Dictionary.
 10
 11 The W3C specification can be found here:
 12 http://dev.w3.org/2011/webrtc/editor/webrtc.html#rtcpeerconnection
 13
 14 Since Dictionaries can't be fully copied around adding
 15 get(const String& name, Vector<Dictionary>& result)
 16 isn't reasible so I have added two new methods: getArrayLength and getArrayItem.
 17
 18 Test: fast/mediastream/RTCPeerConnection.html
 19
 20 * Modules/mediastream/DOMWindowMediaStream.idl:
 21 * Modules/mediastream/RTCPeerConnection.cpp: Added.
 22 (WebCore):
 23 (RTCIceServer):
 24 (WebCore::RTCIceServer::create):
 25 (WebCore::RTCIceServer::~RTCIceServer):
 26 (WebCore::RTCIceServer::uri):
 27 (WebCore::RTCIceServer::password):
 28 (WebCore::RTCIceServer::RTCIceServer):
 29 (RTCConfiguration):
 30 (WebCore::RTCConfiguration::create):
 31 (WebCore::RTCConfiguration::~RTCConfiguration):
 32 (WebCore::RTCConfiguration::appendServer):
 33 (WebCore::RTCConfiguration::numberOfServers):
 34 (WebCore::RTCConfiguration::server):
 35 (WebCore::RTCConfiguration::RTCConfiguration):
 36 (WebCore::RTCPeerConnection::parseConfiguration):
 37 (WebCore::RTCPeerConnection::create):
 38 (WebCore::RTCPeerConnection::RTCPeerConnection):
 39 (WebCore::RTCPeerConnection::~RTCPeerConnection):
 40 (WebCore::RTCPeerConnection::interfaceName):
 41 (WebCore::RTCPeerConnection::scriptExecutionContext):
 42 (WebCore::RTCPeerConnection::stop):
 43 (WebCore::RTCPeerConnection::eventTargetData):
 44 (WebCore::RTCPeerConnection::ensureEventTargetData):
 45 * Modules/mediastream/RTCPeerConnection.h: Added.
 46 (WebCore):
 47 (RTCPeerConnection):
 48 (WebCore::RTCPeerConnection::refEventTarget):
 49 (WebCore::RTCPeerConnection::derefEventTarget):
 50 * Modules/mediastream/RTCPeerConnection.idl: Added.
 51 * WebCore.gypi:
 52 * bindings/generic/RuntimeEnabledFeatures.h:
 53 (WebCore::RuntimeEnabledFeatures::webkitRTCPeerConnectionEnabled):
 54 * bindings/v8/Dictionary.cpp:
 55 (WebCore::Dictionary::getArrayLength):
 56 (WebCore):
 57 (WebCore::Dictionary::getArrayItem):
 58 * bindings/v8/Dictionary.h:
 59 (Dictionary):
 60 * dom/EventTargetFactory.in:
 61
1622012-07-26 Eric Seidel <eric@webkit.org>
263
364 2% of all samples running grid demo show up in StyleResolver::canShareStyleWithElement, 20% of those due to getAttribute instead of fastGetAttribute

Source/WebCore/Modules/mediastream/DOMWindowMediaStream.idl

@@module window {
3232 ] DOMWindowMediaStream {
3333 attribute [V8EnabledAtRuntime] MediaStreamConstructor webkitMediaStream;
3434 attribute [V8EnabledAtRuntime] PeerConnection00Constructor webkitPeerConnection00;
 35 attribute [V8EnabledAtRuntime] RTCPeerConnectionConstructor webkitRTCPeerConnection;
3536 attribute SessionDescriptionConstructor SessionDescription;
3637 attribute IceCandidateConstructor IceCandidate;
3738 attribute MediaStreamEventConstructor MediaStreamEvent;

Source/WebCore/Modules/mediastream/RTCPeerConnection.cpp

 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#if ENABLE(MEDIA_STREAM)
 34
 35#include "RTCPeerConnection.h"
 36
 37#include "ExceptionCode.h"
 38#include "ScriptExecutionContext.h"
 39
 40namespace WebCore {
 41
 42// FYI: RTCIceServer and RTCConfigration are placed here temporarily.
 43// Their final place is in Source/WebCore/platform/mediastream.
 44class RTCIceServer : public RefCounted<RTCIceServer> {
 45public:
 46 static PassRefPtr<RTCIceServer> create(const String& uri, const String& password) { return adoptRef(new RTCIceServer(uri, password)); }
 47 virtual ~RTCIceServer() { }
 48
 49 const String& uri() { return m_uri; }
 50 const String& password() { return m_password; }
 51
 52private:
 53 RTCIceServer(const String& uri, const String& password) : m_uri(uri), m_password(password) { }
 54
 55 String m_uri;
 56 String m_password;
 57};
 58
 59class RTCConfiguration : public RefCounted<RTCConfiguration> {
 60public:
 61 static PassRefPtr<RTCConfiguration> create() { return adoptRef(new RTCConfiguration()); }
 62 virtual ~RTCConfiguration() { }
 63
 64 void appendServer(PassRefPtr<RTCIceServer> server) { m_servers.append(server); }
 65 size_t numberOfServers() { return m_servers.size(); }
 66 RTCIceServer* server(size_t index) { return m_servers[index].get(); }
 67
 68private:
 69 RTCConfiguration() { }
 70
 71 Vector<RefPtr<RTCIceServer> > m_servers;
 72};
 73
 74PassRefPtr<RTCConfiguration> RTCPeerConnection::parseConfiguration(const Dictionary& configuration, ExceptionCode& ec)
 75{
 76 if (configuration.isUndefinedOrNull())
 77 return 0;
 78
 79 size_t numberOfServers;
 80 bool ok = configuration.getArrayLength("iceServers", numberOfServers);
 81 if (!ok) {
 82 ec = TYPE_MISMATCH_ERR;
 83 return 0;
 84 }
 85
 86 RefPtr<RTCConfiguration> rtcConfiguration = RTCConfiguration::create();
 87
 88 for (size_t i = 0; i < numberOfServers; ++i) {
 89 Dictionary serverConfiguration;
 90 ok = configuration.getArrayItem("iceServers", i, serverConfiguration);
 91 if (!ok) {
 92 ec = TYPE_MISMATCH_ERR;
 93 return 0;
 94 }
 95
 96 String uri, password;
 97 ok = serverConfiguration.get("uri", uri);
 98 if (!ok) {
 99 ec = TYPE_MISMATCH_ERR;
 100 return 0;
 101 }
 102 serverConfiguration.get("credential", password);
 103
 104 rtcConfiguration->appendServer(RTCIceServer::create(uri, password));
 105 }
 106
 107 return rtcConfiguration.release();
 108}
 109
 110PassRefPtr<RTCPeerConnection> RTCPeerConnection::create(ScriptExecutionContext* context, const Dictionary& rtcConfiguration, const Dictionary&, ExceptionCode& ec)
 111{
 112 RefPtr<RTCConfiguration> configuration = parseConfiguration(rtcConfiguration, ec);
 113 if (ec)
 114 return 0;
 115
 116 RefPtr<RTCPeerConnection> peerConnection = adoptRef(new RTCPeerConnection(context, configuration.release(), ec));
 117 if (ec)
 118 return 0;
 119
 120 peerConnection->suspendIfNeeded();
 121 return peerConnection.release();
 122}
 123
 124RTCPeerConnection::RTCPeerConnection(ScriptExecutionContext* context, PassRefPtr<RTCConfiguration>, ExceptionCode& ec)
 125 : ActiveDOMObject(context, this)
 126{
 127}
 128
 129RTCPeerConnection::~RTCPeerConnection()
 130{
 131}
 132
 133const AtomicString& RTCPeerConnection::interfaceName() const
 134{
 135 return eventNames().interfaceForRTCPeerConnection;
 136}
 137
 138ScriptExecutionContext* RTCPeerConnection::scriptExecutionContext() const
 139{
 140 return ActiveDOMObject::scriptExecutionContext();
 141}
 142
 143void RTCPeerConnection::stop()
 144{
 145}
 146
 147EventTargetData* RTCPeerConnection::eventTargetData()
 148{
 149 return &m_eventTargetData;
 150}
 151
 152EventTargetData* RTCPeerConnection::ensureEventTargetData()
 153{
 154 return &m_eventTargetData;
 155}
 156
 157} // namespace WebCore
 158
 159#endif // ENABLE(MEDIA_STREAM)

Source/WebCore/Modules/mediastream/RTCPeerConnection.h

 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#ifndef RTCPeerConnection_h
 32#define RTCPeerConnection_h
 33
 34#if ENABLE(MEDIA_STREAM)
 35
 36#include "ActiveDOMObject.h"
 37#include "Dictionary.h"
 38#include "EventTarget.h"
 39#include "ExceptionBase.h"
 40#include <wtf/RefCounted.h>
 41
 42namespace WebCore {
 43class RTCConfiguration;
 44
 45class RTCPeerConnection : public RefCounted<RTCPeerConnection>, public EventTarget, public ActiveDOMObject {
 46public:
 47 static PassRefPtr<RTCPeerConnection> create(ScriptExecutionContext*, const Dictionary& rtcConfiguration, const Dictionary& mediaConstraints, ExceptionCode&);
 48 ~RTCPeerConnection();
 49
 50 // EventTarget
 51 virtual const AtomicString& interfaceName() const OVERRIDE;
 52 virtual ScriptExecutionContext* scriptExecutionContext() const OVERRIDE;
 53
 54 // ActiveDOMObject
 55 virtual void stop() OVERRIDE;
 56
 57 using RefCounted<RTCPeerConnection>::ref;
 58 using RefCounted<RTCPeerConnection>::deref;
 59
 60private:
 61 RTCPeerConnection(ScriptExecutionContext*, PassRefPtr<RTCConfiguration>, ExceptionCode&);
 62
 63 static PassRefPtr<RTCConfiguration> parseConfiguration(const Dictionary& configuration, ExceptionCode&);
 64
 65 // EventTarget implementation.
 66 virtual EventTargetData* eventTargetData();
 67 virtual EventTargetData* ensureEventTargetData();
 68 virtual void refEventTarget() { ref(); }
 69 virtual void derefEventTarget() { deref(); }
 70 EventTargetData m_eventTargetData;
 71};
 72
 73} // namespace WebCore
 74
 75#endif // ENABLE(MEDIA_STREAM)
 76
 77#endif // RTCPeerConnection_h

Source/WebCore/Modules/mediastream/RTCPeerConnection.idl

 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
 31module mediastream {
 32
 33 // FIXME: The second argument to the constructor should be optional but the idl code generator doesn't support that yet.
 34 interface [
 35 Conditional=MEDIA_STREAM,
 36 ActiveDOMObject,
 37 Constructor(in Dictionary rtcICEServers, in Dictionary mediaConstraints),
 38 ConstructorRaisesException,
 39 CallWith=ScriptExecutionContext,
 40 EventTarget
 41 ] RTCPeerConnection {
 42 // EventTarget interface
 43 void addEventListener(in DOMString type,
 44 in EventListener listener,
 45 in [Optional] boolean useCapture);
 46 void removeEventListener(in DOMString type,
 47 in EventListener listener,
 48 in [Optional] boolean useCapture);
 49 boolean dispatchEvent(in Event event)
 50 raises(EventException);
 51 };
 52
 53}

Source/WebCore/WebCore.gypi

840840 'Modules/mediastream/NavigatorUserMediaErrorCallback.idl',
841841 'Modules/mediastream/NavigatorUserMediaSuccessCallback.idl',
842842 'Modules/mediastream/PeerConnection00.idl',
 843 'Modules/mediastream/RTCPeerConnection.idl',
843844 'Modules/mediastream/SessionDescription.idl',
844845 'Modules/notifications/DOMWindowNotifications.idl',
845846 'Modules/notifications/Notification.idl',

15661567 'Modules/mediastream/NavigatorUserMediaSuccessCallback.h',
15671568 'Modules/mediastream/PeerConnection00.cpp',
15681569 'Modules/mediastream/PeerConnection00.h',
 1570 'Modules/mediastream/RTCPeerConnection.cpp',
 1571 'Modules/mediastream/RTCPeerConnection.h',
15691572 'Modules/mediastream/SessionDescription.cpp',
15701573 'Modules/mediastream/SessionDescription.h',
15711574 'Modules/mediastream/UserMediaClient.h',

Source/WebCore/bindings/generic/RuntimeEnabledFeatures.h

@@public:
188188 static bool peerConnectionEnabled() { return isMediaStreamEnabled && isPeerConnectionEnabled; }
189189 static void setPeerConnectionEnabled(bool isEnabled) { isPeerConnectionEnabled = isEnabled; }
190190 static bool webkitPeerConnection00Enabled() { return peerConnectionEnabled(); }
 191 static bool webkitRTCPeerConnectionEnabled() { return peerConnectionEnabled(); }
191192#endif
192193
193194#if ENABLE(GAMEPAD)

Source/WebCore/bindings/v8/Dictionary.cpp

@@bool Dictionary::get(const String& key, Dictionary& value) const
424424 return true;
425425}
426426
 427bool Dictionary::getArrayLength(const String& key, size_t& length) const
 428{
 429 v8::Local<v8::Value> v8Value;
 430 if (!getKey(key, v8Value))
 431 return false;
 432
 433 if (!v8Value->IsArray())
 434 return false;
 435
 436 v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
 437 length = v8Array->Length();
 438 return true;
 439}
 440
 441bool Dictionary::getArrayItem(const String& key, size_t index, Dictionary& value) const
 442{
 443 v8::Local<v8::Value> v8Value;
 444 if (!getKey(key, v8Value))
 445 return false;
 446
 447 if (!v8Value->IsArray())
 448 return false;
 449
 450 v8::Local<v8::Array> v8Array = v8::Local<v8::Array>::Cast(v8Value);
 451 if (index >= v8Array->Length())
 452 return false;
 453
 454 v8::Local<v8::Value> indexedValue = v8Array->Get(v8::Uint32::New(index));
 455 if (!indexedValue->IsObject())
 456 return false;
 457
 458 value = Dictionary(indexedValue);
 459 return true;
 460}
 461
427462bool Dictionary::get(const String& key, Vector<String>& value) const
428463{
429464 v8::Local<v8::Value> v8Value;

Source/WebCore/bindings/v8/Dictionary.h

@@public:
8686 bool get(const String&, HashSet<AtomicString>&) const;
8787 bool get(const String&, Dictionary&) const;
8888 bool get(const String&, Vector<String>&) const;
 89
 90 bool getArrayLength(const String& key, size_t& length) const;
 91 bool getArrayItem(const String& key, size_t index, Dictionary& value) const;
 92
8993 bool getOwnPropertiesAsStringHashMap(WTF::HashMap<String, String>&) const;
9094
9195 bool getWithUndefinedOrNullCheck(const String&, String&) const;

Source/WebCore/dom/EventTargetFactory.in

@@Node
2424Notification conditional=NOTIFICATIONS|LEGACY_NOTIFICATIONS
2525PeerConnection00 conditional=MEDIA_STREAM
2626Performance conditional=WEB_TIMING
 27RTCPeerConnection conditional=MEDIA_STREAM
2728SharedWorker conditional=SHARED_WORKERS
2829SharedWorkerContext conditional=SHARED_WORKERS
2930SourceBufferList conditional=MEDIA_SOURCE

LayoutTests/ChangeLog

 12012-07-27 Tommy Widenflycht <tommyw@google.com>
 2
 3 Introduce a minimal RTCPeerConnection together with Dictionary changes
 4 https://bugs.webkit.org/show_bug.cgi?id=92380
 5
 6 Reviewed by NOBODY (OOPS!).
 7
 8 * fast/mediastream/RTCPeerConnection.html: Added.
 9
1102012-07-26 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
211
312 [EFL] Gardening after r123634

LayoutTests/fast/mediastream/RTCPeerConnection-expected.txt

 1Tests the RTCPeerConnection constructor.
 2
 3On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 4
 5
 6PASS new webkitRTCPeerConnection(null, null); did not throw exception.
 7PASS new webkitRTCPeerConnection({iceServers:[]}, null); did not throw exception.
 8PASS new webkitRTCPeerConnection({iceServers:[{uri:'foo'}]}, null); did not throw exception.
 9PASS new webkitRTCPeerConnection({iceServers:[{uri:'foo', credential:'x'}]}, null); did not throw exception.
 10PASS new webkitRTCPeerConnection({iceServers:[{uri:'foo', credential:'x'},{uri:'bar'}]}, null); did not throw exception.
 11PASS new webkitRTCPeerConnection({fooServers:[]}, null); threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
 12PASS new webkitRTCPeerConnection({iceServers:true}, null); threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
 13PASS new webkitRTCPeerConnection({iceServers:[1, 2, 3]}, null); threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
 14PASS new webkitRTCPeerConnection({iceServers:[{}]}, null); threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
 15PASS new webkitRTCPeerConnection({iceServers:[{url:'foo'}]}, null); threw exception Error: TYPE_MISMATCH_ERR: DOM Exception 17.
 16PASS successfullyParsed is true
 17
 18TEST COMPLETE
 19

LayoutTests/fast/mediastream/RTCPeerConnection.html

 1<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
 2<html>
 3<head>
 4<link rel="stylesheet" href="../js/resources/js-test-style.css">
 5<script src="../js/resources/js-test-pre.js"></script>
 6</head>
 7<body>
 8<p id="description"></p>
 9<div id="console"></div>
 10<script>
 11description("Tests the RTCPeerConnection constructor.");
 12
 13shouldNotThrow("new webkitRTCPeerConnection(null, null);");
 14shouldNotThrow("new webkitRTCPeerConnection({iceServers:[]}, null);");
 15shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{uri:'foo'}]}, null);");
 16shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{uri:'foo', credential:'x'}]}, null);");
 17shouldNotThrow("new webkitRTCPeerConnection({iceServers:[{uri:'foo', credential:'x'},{uri:'bar'}]}, null);");
 18
 19shouldThrow("new webkitRTCPeerConnection({fooServers:[]}, null);");
 20shouldThrow("new webkitRTCPeerConnection({iceServers:true}, null);");
 21shouldThrow("new webkitRTCPeerConnection({iceServers:[1, 2, 3]}, null);");
 22shouldThrow("new webkitRTCPeerConnection({iceServers:[{}]}, null);");
 23shouldThrow("new webkitRTCPeerConnection({iceServers:[{url:'foo'}]}, null);");
 24
 25window.jsTestIsAsync = false;
 26</script>
 27<script src="../js/resources/js-test-post.js"></script>
 28</body>
 29</html>