Bug 868778 - Part c: Move DataChannel to WebIDL; r=mounir+jesup
authorMs2ger <ms2ger@gmail.com>
Mon, 20 May 2013 09:19:45 +0200
changeset 144723 b94e996b05fd657336723355ff4c905220a8c9ce
parent 144722 60c386548d5eb1282d170999a226304bb961ac3a
child 144724 ca7f8131a8d4ee0de01ee7d513a3543815846997
push id368
push userbbajaj@mozilla.com
push dateMon, 09 Sep 2013 22:57:58 +0000
treeherdermozilla-release@5a4f47ae1217 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmounir
bugs868778
milestone24.0a1
first release with
nightly linux32
b94e996b05fd / 24.0a1 / 20130520031230 / files
nightly linux64
b94e996b05fd / 24.0a1 / 20130520031230 / files
nightly mac
b94e996b05fd / 24.0a1 / 20130520031230 / files
nightly win32
b94e996b05fd / 24.0a1 / 20130520031230 / files
nightly win64
b94e996b05fd / 24.0a1 / 20130520031230 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 868778 - Part c: Move DataChannel to WebIDL; r=mounir+jesup
content/base/public/nsIDOMDataChannel.idl
content/base/src/nsDOMDataChannel.cpp
content/base/src/nsDOMDataChannel.h
content/events/src/nsDOMEventTargetHelper.h
dom/base/nsDOMClassInfo.cpp
dom/base/nsDOMClassInfoClasses.h
dom/bindings/Bindings.conf
dom/webidl/DataChannel.webidl
dom/webidl/WebIDL.mk
netwerk/sctp/datachannel/DataChannel.h
--- a/content/base/public/nsIDOMDataChannel.idl
+++ b/content/base/public/nsIDOMDataChannel.idl
@@ -1,22 +1,26 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
 #include "domstubs.idl"
 
 #include "nsIDOMEventTarget.idl"
 
 %{C++
 #ifdef GetBinaryType
 // Windows apparently has a #define for GetBinaryType...
 #undef GetBinaryType
 #endif
 %}
 
 interface nsIVariant;
 
-[scriptable, builtinclass, uuid(1aed816d-1156-414e-8fe2-f01daa6021f0)]
+[scriptable, builtinclass, uuid(4410f28d-c9eb-481d-a47e-e7ef49f382c8)]
 interface nsIDOMDataChannel : nsIDOMEventTarget
 {
   readonly attribute DOMString label;
   readonly attribute DOMString protocol;
   readonly attribute boolean reliable;
   readonly attribute boolean ordered;
 
   readonly attribute DOMString readyState;
@@ -27,19 +31,9 @@ interface nsIDOMDataChannel : nsIDOMEven
   [implicit_jscontext] attribute jsval onopen;
   [implicit_jscontext] attribute jsval onerror;
   [implicit_jscontext] attribute jsval onclose;
   [implicit_jscontext] attribute jsval onmessage;
 
   attribute DOMString binaryType;
 
   void close();
-
-  /**
-   * Transmits data to other end of the connection.
-   * @param data The data to be transmitted.  Arraybuffers and Blobs are sent as
-   * binary data.  Strings are sent as UTF-8 text data.  Other types are
-   * converted to a String and sent as a String.
-   * @return if the connection is still established and the data was queued or
-   *         sent successfully.
-   */
-  void send(in nsIVariant data);
 };
--- a/content/base/src/nsDOMDataChannel.cpp
+++ b/content/base/src/nsDOMDataChannel.cpp
@@ -17,63 +17,62 @@
 extern PRLogModuleInfo* GetDataChannelLog();
 #endif
 #undef LOG
 #define LOG(args) PR_LOG(GetDataChannelLog(), PR_LOG_DEBUG, args)
 
 
 #include "nsDOMDataChannelDeclarations.h"
 #include "nsIDOMFile.h"
-#include "nsIJSNativeInitializer.h"
 #include "nsIDOMDataChannel.h"
 #include "nsIDOMMessageEvent.h"
-#include "nsDOMClassInfo.h"
 #include "nsDOMEventTargetHelper.h"
 
-#include "js/Value.h"
-
 #include "nsError.h"
 #include "nsAutoPtr.h"
 #include "nsContentUtils.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIScriptObjectPrincipal.h"
-#include "nsJSUtils.h"
 #include "nsNetUtil.h"
 #include "nsDOMFile.h"
 
 #include "DataChannel.h"
 
 using namespace mozilla;
-
-DOMCI_DATA(DataChannel, nsDOMDataChannel)
+using namespace mozilla::dom;
 
 nsDOMDataChannel::~nsDOMDataChannel()
 {
   // Don't call us anymore!  Likely isn't an issue (or maybe just less of
   // one) once we block GC until all the (appropriate) onXxxx handlers
   // are dropped. (See WebRTC spec)
   LOG(("Close()ing %p", mDataChannel.get()));
   mDataChannel->SetListener(nullptr, nullptr);
   mDataChannel->Close();
 }
 
+/* virtual */ JSObject*
+nsDOMDataChannel::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
+{
+  return DataChannelBinding::Wrap(aCx, aScope, this);
+}
+
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDataChannel,
                                                   nsDOMEventTargetHelper)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDataChannel,
                                                 nsDOMEventTargetHelper)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ADDREF_INHERITED(nsDOMDataChannel, nsDOMEventTargetHelper)
 NS_IMPL_RELEASE_INHERITED(nsDOMDataChannel, nsDOMEventTargetHelper)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMDataChannel)
   NS_INTERFACE_MAP_ENTRY(nsIDOMDataChannel)
-  NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DataChannel)
 NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
 
 nsresult
 nsDOMDataChannel::Init(nsPIDOMWindow* aDOMWindow)
 {
   nsresult rv;
   nsAutoString urlParam;
 
@@ -121,38 +120,63 @@ nsDOMDataChannel::GetLabel(nsAString& aL
 
 NS_IMETHODIMP
 nsDOMDataChannel::GetProtocol(nsAString& aProtocol)
 {
   mDataChannel->GetProtocol(aProtocol);
   return NS_OK;
 }
 
+uint16_t
+nsDOMDataChannel::Stream() const
+{
+  return mDataChannel->GetStream();
+}
+
 NS_IMETHODIMP
 nsDOMDataChannel::GetStream(uint16_t *aStream)
 {
-  mDataChannel->GetStream(aStream);
+  *aStream = Stream();
   return NS_OK;
 }
 
 // XXX should be GetType()?  Open question for the spec
+bool
+nsDOMDataChannel::Reliable() const
+{
+  return mDataChannel->GetType() == mozilla::DataChannelConnection::RELIABLE;
+}
+
 NS_IMETHODIMP
 nsDOMDataChannel::GetReliable(bool* aReliable)
 {
-  *aReliable = (mDataChannel->GetType() == mozilla::DataChannelConnection::RELIABLE);
+  *aReliable = Reliable();
   return NS_OK;
 }
 
+bool
+nsDOMDataChannel::Ordered() const
+{
+  return mDataChannel->GetOrdered();
+}
+
 NS_IMETHODIMP
 nsDOMDataChannel::GetOrdered(bool* aOrdered)
 {
-  *aOrdered = mDataChannel->GetOrdered();
+  *aOrdered = Ordered();
   return NS_OK;
 }
 
+RTCDataChannelState
+nsDOMDataChannel::ReadyState() const
+{
+  return static_cast<RTCDataChannelState>(mDataChannel->GetReadyState());
+}
+
+
 NS_IMETHODIMP
 nsDOMDataChannel::GetReadyState(nsAString& aReadyState)
 {
   uint16_t readyState = mDataChannel->GetReadyState();
   // From the WebRTC spec
   const char * stateName[] = {
     "connecting",
     "open",
@@ -161,20 +185,26 @@ nsDOMDataChannel::GetReadyState(nsAStrin
   };
   MOZ_ASSERT(/*readyState >= mozilla::DataChannel::CONNECTING && */ // Always true due to datatypes
              readyState <= mozilla::DataChannel::CLOSED);
   aReadyState.AssignASCII(stateName[readyState]);
 
   return NS_OK;
 }
 
+uint32_t
+nsDOMDataChannel::BufferedAmount() const
+{
+  return mDataChannel->GetBufferedAmount();
+}
+
 NS_IMETHODIMP
 nsDOMDataChannel::GetBufferedAmount(uint32_t* aBufferedAmount)
 {
-  *aBufferedAmount = mDataChannel->GetBufferedAmount();
+  *aBufferedAmount = BufferedAmount();
   return NS_OK;
 }
 
 NS_IMETHODIMP nsDOMDataChannel::GetBinaryType(nsAString & aBinaryType)
 {
   switch (mBinaryType) {
   case DC_BINARY_TYPE_ARRAYBUFFER:
     aBinaryType.AssignLiteral("arraybuffer");
@@ -203,130 +233,115 @@ nsDOMDataChannel::SetBinaryType(const ns
 
 NS_IMETHODIMP
 nsDOMDataChannel::Close()
 {
   mDataChannel->Close();
   return NS_OK;
 }
 
-// Almost a clone of nsWebSocketChannel::Send()
-NS_IMETHODIMP
-nsDOMDataChannel::Send(nsIVariant* aData)
+// All of the following is copy/pasted from WebSocket.cpp.
+void
+nsDOMDataChannel::Send(const nsAString& aData, ErrorResult& aRv)
+{
+  NS_ConvertUTF16toUTF8 msgString(aData);
+  Send(nullptr, msgString, msgString.Length(), false, aRv);
+}
+
+void
+nsDOMDataChannel::Send(nsIDOMBlob* aData, ErrorResult& aRv)
+{
+  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
+
+  nsCOMPtr<nsIInputStream> msgStream;
+  nsresult rv = aData->GetInternalStream(getter_AddRefs(msgStream));
+  if (NS_FAILED(rv)) {
+    aRv.Throw(rv);
+    return;
+  }
+
+  uint64_t msgLength;
+  rv = aData->GetSize(&msgLength);
+  if (NS_FAILED(rv)) {
+    aRv.Throw(rv);
+    return;
+  }
+
+  if (msgLength > UINT32_MAX) {
+    aRv.Throw(NS_ERROR_FILE_TOO_BIG);
+    return;
+  }
+
+  Send(msgStream, EmptyCString(), msgLength, true, aRv);
+}
+
+void
+nsDOMDataChannel::Send(ArrayBuffer& aData, ErrorResult& aRv)
+{
+  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
+
+  MOZ_ASSERT(sizeof(*aData.Data()) == 1);
+  uint32_t len = aData.Length();
+  char* data = reinterpret_cast<char*>(aData.Data());
+
+  nsDependentCSubstring msgString(data, len);
+  Send(nullptr, msgString, len, true, aRv);
+}
+
+void
+nsDOMDataChannel::Send(ArrayBufferView& aData, ErrorResult& aRv)
+{
+  NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
+
+  MOZ_ASSERT(sizeof(*aData.Data()) == 1);
+  uint32_t len = aData.Length();
+  char* data = reinterpret_cast<char*>(aData.Data());
+
+  nsDependentCSubstring msgString(data, len);
+  Send(nullptr, msgString, len, true, aRv);
+}
+
+void
+nsDOMDataChannel::Send(nsIInputStream* aMsgStream,
+                       const nsACString& aMsgString,
+                       uint32_t aMsgLength,
+                       bool aIsBinary,
+                       ErrorResult& aRv)
 {
   MOZ_ASSERT(NS_IsMainThread());
   uint16_t state = mDataChannel->GetReadyState();
 
   // In reality, the DataChannel protocol allows this, but we want it to
   // look like WebSockets
   if (state == mozilla::DataChannel::CONNECTING) {
-    return NS_ERROR_DOM_INVALID_STATE_ERR;
+    aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
+    return;
   }
 
-  nsCString msgString;
-  nsCOMPtr<nsIInputStream> msgStream;
-  bool isBinary;
-  uint32_t msgLen;
-  nsresult rv = GetSendParams(aData, msgString, msgStream, isBinary, msgLen);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   if (state == mozilla::DataChannel::CLOSING ||
       state == mozilla::DataChannel::CLOSED) {
-    return NS_OK;
+    return;
   }
 
   MOZ_ASSERT(state == mozilla::DataChannel::OPEN,
-             "Unknown state in nsWebSocket::Send");
+             "Unknown state in nsDOMDataChannel::Send");
 
   int32_t sent;
-  if (msgStream) {
-    sent = mDataChannel->SendBinaryStream(msgStream, msgLen);
+  if (aMsgStream) {
+    sent = mDataChannel->SendBinaryStream(aMsgStream, aMsgLength);
   } else {
-    if (isBinary) {
-      sent = mDataChannel->SendBinaryMsg(msgString);
+    if (aIsBinary) {
+      sent = mDataChannel->SendBinaryMsg(aMsgString);
     } else {
-      sent = mDataChannel->SendMsg(msgString);
+      sent = mDataChannel->SendMsg(aMsgString);
     }
   }
-  return sent >= 0 ? NS_OK : NS_ERROR_FAILURE;
-}
-
-// XXX Exact clone of nsWebSocketChannel::GetSendParams() - find a way to share!
-nsresult
-nsDOMDataChannel::GetSendParams(nsIVariant* aData, nsCString& aStringOut,
-                                nsCOMPtr<nsIInputStream>& aStreamOut,
-                                bool& aIsBinary, uint32_t& aOutgoingLength)
-{
-  // Get type of data (arraybuffer, blob, or string)
-  uint16_t dataType;
-  nsresult rv = aData->GetDataType(&dataType);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (dataType == nsIDataType::VTYPE_INTERFACE ||
-      dataType == nsIDataType::VTYPE_INTERFACE_IS) {
-    nsCOMPtr<nsISupports> supports;
-    nsID* iid;
-    rv = aData->GetAsInterface(&iid, getter_AddRefs(supports));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    nsMemory::Free(iid);
-
-    AutoSafeJSContext cx;
-    // ArrayBuffer?
-    JS::Rooted<JS::Value> realVal(cx);
-    JS::Rooted<JSObject*> obj(cx);
-    nsresult rv = aData->GetAsJSVal(realVal.address());
-    if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) &&
-        (obj = JSVAL_TO_OBJECT(realVal)) &&
-        (JS_IsArrayBufferObject(obj))) {
-      int32_t len = JS_GetArrayBufferByteLength(obj);
-      char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj));
-
-      aStringOut.Assign(data, len);
-      aIsBinary = true;
-      aOutgoingLength = len;
-      return NS_OK;
-    }
-
-    // Blob?
-    nsCOMPtr<nsIDOMBlob> blob = do_QueryInterface(supports);
-    if (blob) {
-      rv = blob->GetInternalStream(getter_AddRefs(aStreamOut));
-      NS_ENSURE_SUCCESS(rv, rv);
-
-      // GetSize() should not perform blocking I/O (unlike Available())
-      uint64_t blobLen;
-      rv = blob->GetSize(&blobLen);
-      NS_ENSURE_SUCCESS(rv, rv);
-      if (blobLen > UINT32_MAX) {
-        return NS_ERROR_FILE_TOO_BIG;
-      }
-      aOutgoingLength = static_cast<uint32_t>(blobLen);
-
-      aIsBinary = true;
-      return NS_OK;
-    }
+  if (sent < 0) {
+    aRv.Throw(NS_ERROR_FAILURE);
   }
-
-  // Text message: if not already a string, turn it into one.
-  // TODO: bug 704444: Correctly coerce any JS type to string
-  //
-  PRUnichar* data = nullptr;
-  uint32_t len = 0;
-  rv = aData->GetAsWStringWithSize(&len, &data);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsString text;
-  text.Adopt(data, len);
-
-  CopyUTF16toUTF8(text, aStringOut);
-
-  aIsBinary = false;
-  aOutgoingLength = aStringOut.Length();
-  return NS_OK;
 }
 
 nsresult
 nsDOMDataChannel::DoOnMessageAvailable(const nsACString& aData,
                                        bool aBinary)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
--- a/content/base/src/nsDOMDataChannel.h
+++ b/content/base/src/nsDOMDataChannel.h
@@ -2,16 +2,18 @@
 /* vim: set sw=2 ts=8 et tw=80 : */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsDOMDataChannel_h
 #define nsDOMDataChannel_h
 
+#include "mozilla/dom/DataChannelBinding.h"
+#include "mozilla/dom/TypedArray.h"
 #include "mozilla/net/DataChannel.h"
 #include "nsDOMEventTargetHelper.h"
 #include "nsIDOMDataChannel.h"
 
 class nsDOMDataChannel : public nsDOMEventTargetHelper,
                          public nsIDOMDataChannel,
                          public mozilla::DataChannelListener
 {
@@ -28,16 +30,52 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIDOMDATACHANNEL
 
   NS_REALLY_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper)
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMDataChannel,
                                            nsDOMEventTargetHelper)
 
+  virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
+    MOZ_OVERRIDE;
+  nsPIDOMWindow* GetParentObject() const
+  {
+    return GetOwner();
+  }
+
+  // WebIDL
+  // Uses XPIDL GetLabel.
+  bool Reliable() const;
+  mozilla::dom::RTCDataChannelState ReadyState() const;
+  uint32_t BufferedAmount() const;
+  IMPL_EVENT_HANDLER(open)
+  IMPL_EVENT_HANDLER(error)
+  IMPL_EVENT_HANDLER(close)
+  // Uses XPIDL Close.
+  IMPL_EVENT_HANDLER(message)
+  mozilla::dom::RTCDataChannelType BinaryType() const
+  {
+    return static_cast<mozilla::dom::RTCDataChannelType>(
+      static_cast<int>(mBinaryType));
+  }
+  void SetBinaryType(mozilla::dom::RTCDataChannelType aType)
+  {
+    mBinaryType = static_cast<DataChannelBinaryType>(
+      static_cast<int>(aType));
+  }
+  void Send(const nsAString& aData, mozilla::ErrorResult& aRv);
+  void Send(nsIDOMBlob* aData, mozilla::ErrorResult& aRv);
+  void Send(mozilla::dom::ArrayBuffer& aData, mozilla::ErrorResult& aRv);
+  void Send(mozilla::dom::ArrayBufferView& aData, mozilla::ErrorResult& aRv);
+
+  // Uses XPIDL GetProtocol.
+  bool Ordered() const;
+  uint16_t Stream() const;
+
   nsresult
   DoOnMessageAvailable(const nsACString& aMessage, bool aBinary);
 
   virtual nsresult
   OnMessageAvailable(nsISupports* aContext, const nsACString& aMessage);
 
   virtual nsresult
   OnBinaryMessageAvailable(nsISupports* aContext, const nsACString& aMessage);
@@ -49,24 +87,22 @@ public:
 
   virtual nsresult
   OnChannelClosed(nsISupports* aContext);
 
   virtual void
   AppReady();
 
 private:
-  // Get msg info out of JS variable being sent (string, arraybuffer, blob)
-  nsresult GetSendParams(nsIVariant *aData, nsCString &aStringOut,
-                         nsCOMPtr<nsIInputStream> &aStreamOut,
-                         bool &aIsBinary, uint32_t &aOutgoingLength);
+  void Send(nsIInputStream* aMsgStream, const nsACString& aMsgString,
+            uint32_t aMsgLength, bool aIsBinary, mozilla::ErrorResult& aRv);
 
   // Owning reference
   nsRefPtr<mozilla::DataChannel> mDataChannel;
   nsString  mOrigin;
-  enum
-  {
+  enum DataChannelBinaryType {
     DC_BINARY_TYPE_ARRAYBUFFER,
     DC_BINARY_TYPE_BLOB,
-  } mBinaryType;
+  };
+  DataChannelBinaryType mBinaryType;
 };
 
 #endif // nsDOMDataChannel_h
--- a/content/events/src/nsDOMEventTargetHelper.h
+++ b/content/events/src/nsDOMEventTargetHelper.h
@@ -160,17 +160,17 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsDOMEvent
 
 // WebIDL event handlers
 #define IMPL_EVENT_HANDLER(_event)                                        \
   inline mozilla::dom::EventHandlerNonNull* GetOn##_event()               \
   {                                                                       \
     return GetEventHandler(nsGkAtoms::on##_event);                        \
   }                                                                       \
   inline void SetOn##_event(mozilla::dom::EventHandlerNonNull* aCallback, \
-                            ErrorResult& aRv)                             \
+                            mozilla::ErrorResult& aRv)                    \
   {                                                                       \
     SetEventHandler(nsGkAtoms::on##_event, aCallback, aRv);               \
   }
 
 /* Use this macro to declare functions that forward the behavior of this
  * interface to another object.
  * This macro doesn't forward PreHandleEvent because sometimes subclasses
  * want to override it.
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -328,20 +328,16 @@ using mozilla::dom::workers::ResolveWork
 
 #include "mozilla/dom/BindingUtils.h"
 #include "mozilla/Likely.h"
 
 #ifdef MOZ_TIME_MANAGER
 #include "TimeManager.h"
 #endif
 
-#ifdef MOZ_WEBRTC
-#include "nsIDOMDataChannel.h"
-#endif
-
 using namespace mozilla;
 using namespace mozilla::dom;
 
 static NS_DEFINE_CID(kDOMSOF_CID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 
 static const char kDOMStringBundleURL[] =
   "chrome://global/locale/dom/dom.properties";
 
@@ -897,21 +893,16 @@ static nsDOMClassInfoData sClassInfoData
 
   NS_DEFINE_CLASSINFO_DATA(LockedFile, nsEventTargetSH,
                            EVENTTARGET_SCRIPTABLE_FLAGS)
 
 #ifdef MOZ_TIME_MANAGER
   NS_DEFINE_CLASSINFO_DATA(MozTimeManager, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
 #endif
-
-#ifdef MOZ_WEBRTC
-  NS_DEFINE_CLASSINFO_DATA(DataChannel, nsEventTargetSH,
-                           EVENTTARGET_SCRIPTABLE_FLAGS)
-#endif
 };
 
 #define NS_DEFINE_CONTRACT_CTOR(_class, _contract_id)                           \
   static nsresult                                                               \
   _class##Ctor(nsISupports** aInstancePtrResult)                                \
   {                                                                             \
     nsresult rv = NS_OK;                                                        \
     nsCOMPtr<nsISupports> native = do_CreateInstance(_contract_id, &rv);        \
@@ -2267,23 +2258,16 @@ nsDOMClassInfo::Init()
   DOM_CLASSINFO_MAP_END
 
 #ifdef MOZ_TIME_MANAGER
   DOM_CLASSINFO_MAP_BEGIN(MozTimeManager, nsIDOMMozTimeManager)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozTimeManager)
   DOM_CLASSINFO_MAP_END
 #endif
 
-#ifdef MOZ_WEBRTC
-  DOM_CLASSINFO_MAP_BEGIN(DataChannel, nsIDOMDataChannel)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMDataChannel)
-    DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
-  DOM_CLASSINFO_MAP_END
-#endif
-
   MOZ_STATIC_ASSERT(MOZ_ARRAY_LENGTH(sClassInfoData) == eDOMClassInfoIDCount,
                     "The number of items in sClassInfoData doesn't match the "
                     "number of nsIDOMClassInfo ID's, this is bad! Fix it!");
 
 #ifdef DEBUG
   for (size_t i = 0; i < eDOMClassInfoIDCount; i++) {
     if (!sClassInfoData[i].u.mConstructorFptr ||
         sClassInfoData[i].mDebugID != i) {
--- a/dom/base/nsDOMClassInfoClasses.h
+++ b/dom/base/nsDOMClassInfoClasses.h
@@ -232,10 +232,9 @@ DOMCI_CLASS(AsyncScrollEventDetail)
 
 DOMCI_CLASS(LockedFile)
 
 #ifdef MOZ_TIME_MANAGER
 DOMCI_CLASS(MozTimeManager)
 #endif
 
 #ifdef MOZ_WEBRTC
-DOMCI_CLASS(DataChannel)
 #endif
--- a/dom/bindings/Bindings.conf
+++ b/dom/bindings/Bindings.conf
@@ -226,16 +226,20 @@ DOMInterfaces = {
 'CSSValue': {
   'concrete': False
 },
 
 'CSSValueList': {
   'nativeType': 'nsDOMCSSValueList'
 },
 
+'DataChannel': {
+    'nativeType': 'nsDOMDataChannel',
+},
+
 'DataContainerEvent': {
     'nativeType': 'nsDOMDataContainerEvent',
 },
 
 'DelayNode': [
 {
     'resultNotAddRefed': [ 'delayTime' ],
 }],
copy from content/base/public/nsIDOMDataChannel.idl
copy to dom/webidl/DataChannel.webidl
--- a/content/base/public/nsIDOMDataChannel.idl
+++ b/dom/webidl/DataChannel.webidl
@@ -1,45 +1,50 @@
-#include "domstubs.idl"
-
-#include "nsIDOMEventTarget.idl"
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-%{C++
-#ifdef GetBinaryType
-// Windows apparently has a #define for GetBinaryType...
-#undef GetBinaryType
-#endif
-%}
+enum RTCDataChannelState {
+  "connecting",
+  "open",
+  "closing",
+  "closed"
+};
 
-interface nsIVariant;
+enum RTCDataChannelType {
+  "arraybuffer",
+  "blob"
+};
 
-[scriptable, builtinclass, uuid(1aed816d-1156-414e-8fe2-f01daa6021f0)]
-interface nsIDOMDataChannel : nsIDOMEventTarget
+// XXX This interface is called RTCDataChannel in the spec.
+interface DataChannel : EventTarget
 {
   readonly attribute DOMString label;
-  readonly attribute DOMString protocol;
   readonly attribute boolean reliable;
-  readonly attribute boolean ordered;
-
-  readonly attribute DOMString readyState;
+  readonly attribute RTCDataChannelState readyState;
   readonly attribute unsigned long bufferedAmount;
-
-  readonly attribute unsigned short stream;
-
-  [implicit_jscontext] attribute jsval onopen;
-  [implicit_jscontext] attribute jsval onerror;
-  [implicit_jscontext] attribute jsval onclose;
-  [implicit_jscontext] attribute jsval onmessage;
+  [SetterThrows]
+  attribute EventHandler onopen;
+  [SetterThrows]
+  attribute EventHandler onerror;
+  [SetterThrows]
+  attribute EventHandler onclose;
+  void close();
+  [SetterThrows]
+  attribute EventHandler onmessage;
+  attribute RTCDataChannelType binaryType;
+  [Throws]
+  void send(DOMString data);
+  [Throws]
+  void send(Blob data);
+  [Throws]
+  void send(ArrayBuffer data);
+  [Throws]
+  void send(ArrayBufferView data);
+};
 
-  attribute DOMString binaryType;
-
-  void close();
-
-  /**
-   * Transmits data to other end of the connection.
-   * @param data The data to be transmitted.  Arraybuffers and Blobs are sent as
-   * binary data.  Strings are sent as UTF-8 text data.  Other types are
-   * converted to a String and sent as a String.
-   * @return if the connection is still established and the data was queued or
-   *         sent successfully.
-   */
-  void send(in nsIVariant data);
+// Mozilla extensions.
+partial interface DataChannel
+{
+  readonly attribute DOMString protocol;
+  readonly attribute boolean ordered;
+  readonly attribute unsigned short stream;
 };
--- a/dom/webidl/WebIDL.mk
+++ b/dom/webidl/WebIDL.mk
@@ -354,16 +354,17 @@ endif
 ifdef MOZ_WEBGL
 webidl_files += \
   WebGLRenderingContext.webidl \
   $(NULL)
 endif
 
 ifdef MOZ_WEBRTC
 webidl_files += \
+  DataChannel.webidl \
   MediaStreamList.webidl \
   $(NULL)
 endif
 
 ifdef MOZ_WEBSPEECH
 webidl_files += \
   SpeechGrammar.webidl \
   SpeechGrammarList.webidl \
--- a/netwerk/sctp/datachannel/DataChannel.h
+++ b/netwerk/sctp/datachannel/DataChannel.h
@@ -405,17 +405,17 @@ public:
         return CONNECTING;
       return mState;
     }
 
   void SetReadyState(uint16_t aState) { mState = aState; }
 
   void GetLabel(nsAString& aLabel) { CopyUTF8toUTF16(mLabel, aLabel); }
   void GetProtocol(nsAString& aProtocol) { CopyUTF8toUTF16(mProtocol, aProtocol); }
-  void GetStream(uint16_t *aStream) { *aStream = mStream; }
+  uint16_t GetStream() { return mStream; }
 
   void AppReady();
 
   void SendOrQueue(DataChannelOnMessageAvailable *aMessage);
 
 protected:
   Mutex mListenerLock; // protects mListener and mContext
   DataChannelListener *mListener;